Compare commits

...

1219 Commits

Author SHA1 Message Date
akwizgran 085987febd DO NOT MERGE: Add hacky poller method for testing discovery. 2020-03-10 15:29:05 +00:00
akwizgran 65c96514b5 Add workaround for Android UUID endianness bug. 2020-03-10 15:29:05 +00:00
akwizgran 174e678304 Don't try to add extra UUIDs to emptyList(). 2020-03-10 15:29:05 +00:00
akwizgran 14d7abc823 Don't try to discover peers if discovery is already in progress. 2020-03-10 15:29:05 +00:00
akwizgran 52fca33d0b Restart discovery if it finishes too quickly.
Discovery finishes quickly on some devices if called at the wrong time.
2020-03-10 15:29:05 +00:00
akwizgran 472d560dda Wait for discovery to finish before returning discovered devices. 2020-03-10 15:29:05 +00:00
akwizgran 2522034397 Implement peer discovery for Android Bluetooth plugin. 2020-03-10 15:29:05 +00:00
akwizgran 3e6b65b1a0 Return devices from discoverDevices() method. 2020-03-10 15:29:05 +00:00
akwizgran 155746b24e Add discovery methods to plugin API. 2020-03-10 15:29:04 +00:00
akwizgran 91caff183f Remove unnecessary plugin lookup. 2020-03-05 14:45:35 +00:00
akwizgran 249dcda34e Use tinted icon for plugin settings dialog. 2020-03-05 14:45:35 +00:00
akwizgran c0a82f96a3 Show dialog from controller. 2020-03-05 14:45:35 +00:00
akwizgran 79f5229230 Add icon, title to Change Settings dialog. 2020-03-05 14:45:35 +00:00
akwizgran 02b4925609 Change Tor settings after asking for confirmation. 2020-03-05 14:45:35 +00:00
akwizgran 0664720680 Transition from one constraint set to another. 2020-03-05 14:45:35 +00:00
akwizgran f04d32f7f2 Make entire collapsed view clickable. 2020-03-05 14:45:35 +00:00
akwizgran dfa05fc473 Put the transport toggles in an expandable view (no animations). 2020-03-05 14:45:35 +00:00
akwizgran cb936d95c5 Add STARTING_STOPPING state, use flags for reasons disabled. 2020-03-05 14:45:35 +00:00
akwizgran 1b402ba0c2 Close small gap between setStarted() and setDisabledBySettings(). 2020-03-05 14:45:34 +00:00
akwizgran 2c6f81a120 Don't show Tor in the enabling state if it's disabled by settings. 2020-03-05 14:45:34 +00:00
akwizgran b69eb8f203 Remove "don't connect" option from Tor network setting.
This has been replaced by the enable/disable setting and no longer
works.
2020-03-05 14:45:34 +00:00
Torsten Grote e956f073ae [android] Scroll down when nav drawer chevron is pressed 2020-03-05 14:45:34 +00:00
Torsten Grote f4b6389163 [android] remove unused strings 2020-03-05 14:45:34 +00:00
Torsten Grote 82bfb4d95e [android] make transport plugin toggles functional 2020-03-05 14:45:34 +00:00
Torsten Grote 93ec646634 [android] Add transport plugin toggles to NavDrawer 2020-03-05 14:45:34 +00:00
Torsten Grote 2420456f25 [bramble] Add method for enabling/disabling plugins to PluginManager 2020-03-05 14:45:32 +00:00
akwizgran b32417e7d3 Remove another redundant call to pluginStateChanged(). 2020-03-05 14:45:17 +00:00
akwizgran 9efa3cc44e Enable LAN plugin before showing QR code. 2020-03-05 14:45:17 +00:00
akwizgran 90c8603d3a Remove redundant call to pluginStateChanged(). 2020-03-05 14:45:17 +00:00
akwizgran 1ae9750c13 Use XML to specify dependencies between settings. 2020-03-05 14:45:17 +00:00
akwizgran b0b87fc0db Clean up logic for enabling/disabling settings. 2020-03-05 14:45:17 +00:00
akwizgran 62cb6095ca Don't remove old settings yet.
This avoids an unlikely race condition at startup, where the user opens
the settings screen before the Tor plugin has migrated the settings.
2020-03-05 14:45:17 +00:00
akwizgran d4a64f4ee3 Enable LAN plugin in unit test. 2020-03-05 14:45:14 +00:00
akwizgran 6886551895 Enable BT plugin before showing QR code. 2020-03-05 14:44:58 +00:00
akwizgran b50b9f8088 Small code cleanups in key agreement UI. 2020-03-05 14:44:58 +00:00
akwizgran c1aade221a Make REASON_USER into a generic reason code. 2020-03-05 14:44:57 +00:00
akwizgran 40f2c1923b Add toggle setting for LAN plugin. 2020-03-05 14:44:57 +00:00
akwizgran cfc640f4ce Update semantics of Bluetooth setting.
The setting now enables/disables the plugin, not just contact
connections. The key agreement UI will need to be updated to change the
setting if the user agrees to use Bluetooth.
2020-03-05 14:44:57 +00:00
akwizgran c865b90c6c Convert Bluetooth setting to a switch. 2020-03-05 14:44:57 +00:00
akwizgran 4db2d0fda2 Add toggle setting for Tor plugin. 2020-03-05 14:44:57 +00:00
akwizgran 719debc36a Remove redundant casts. 2020-03-05 14:44:57 +00:00
akwizgran ce1b5eb0d9 Skip fetching RSS feeds if Tor is not active. 2020-03-05 14:44:57 +00:00
akwizgran 5bd9a29eab Use amber icon when enabling transports. 2020-03-05 14:44:57 +00:00
akwizgran e6d093c52f Only update bridge and padding settings if network is enabled. 2020-03-05 14:44:57 +00:00
akwizgran fe5bbfdd17 Notify callback of state changes while holding lock. 2020-03-05 14:44:57 +00:00
akwizgran e6ac6913a7 Update javadocs for lock-safe methods. 2020-03-05 14:44:57 +00:00
akwizgran 54068a9e24 Remove redundant logging. 2020-03-05 14:44:57 +00:00
akwizgran 4bb14f51d2 Remove debug logging. 2020-03-05 14:44:57 +00:00
akwizgran 37ea59a89e Close server socket when BT is disabled. 2020-03-05 14:44:56 +00:00
akwizgran f19dbf144a Remove unnecessary inner class, state checks. 2020-03-05 14:44:56 +00:00
akwizgran 4b94bd0f1b Reset backoff before notifying of new state.
The new state may cause the poller to poll the
plugin. Let's avoid a race between updating and
querying the polling interval.
2020-03-05 14:44:56 +00:00
akwizgran 0b29e3ce11 Move to enabling state earlier in Tor startup. 2020-03-05 14:44:56 +00:00
akwizgran 6a9dbcf482 Add TransportStateEvent, rename existing events. 2020-03-05 14:44:56 +00:00
akwizgran f5a21d8c07 Ensure server socket is closed. 2020-03-05 14:44:54 +00:00
akwizgran b6a73f2c98 Add method for getting reason why plugin is disabled. 2020-03-05 14:44:28 +00:00
akwizgran d084f6dd8d Fix test expectations. 2020-03-05 14:44:28 +00:00
akwizgran 0259c23cb4 Rename available/unavailable states. 2020-03-05 14:44:26 +00:00
akwizgran 341382cfa8 Update tests. 2020-03-05 14:44:08 +00:00
akwizgran 49baf1020b If adapter is disabled, forget that we enabled it. 2020-03-05 14:44:08 +00:00
akwizgran 6b33c5b913 Check that server sockets are closed as expected. 2020-03-05 14:44:08 +00:00
akwizgran 53889436fc Provide more information about plugin states. 2020-03-05 14:44:05 +00:00
akwizgran e35d1763bc Avoid NPE if there's no TelephonyManager. 2020-03-05 14:42:43 +00:00
akwizgran 4a68e5347d Merge branch '1582-fix-climbing-snackbar' into 'master'
Fix climbing snackbar

Closes #1582

See merge request briar/briar!1223
2020-03-03 14:42:20 +00:00
Torsten Grote 27dd383496 Merge branch '1371-protect-code-cache-directory' into 'master'
Protect cache and code_cache directories when deleting account

Closes #1545 and #1371

See merge request briar/briar!1231
2020-02-26 14:03:39 +00:00
akwizgran 4bdf966e67 Test that code_cache directory isn't deleted. 2020-02-25 11:23:07 +00:00
akwizgran e1e67f3b2e Clear the cache directory but don't delete it. 2020-02-25 11:18:50 +00:00
akwizgran 1d63b16ff1 Don't delete the code_cache directory when deleting account.
This seems to avoid the disappearing account bug when installing a new
version.
2020-02-25 10:14:31 +00:00
Torsten Grote 421f0ebfa5 Merge branch 'network-prefix-length' into 'master'
Use network prefix length to determine which addresses are connectable

Closes #1178

See merge request briar/briar!1230
2020-02-19 13:11:24 +00:00
akwizgran 61db5d1b04 Make bit-twiddling code more readable. 2020-02-19 09:52:13 +00:00
akwizgran b3d4012527 Use network prefix length to determine which addresses are connectable. 2020-02-18 11:22:29 +00:00
Torsten Grote 60172331ee Merge branch 'ipv4-link-local' into 'master'
Add support for IPv4 link-local addresses

See merge request briar/briar!1229
2020-02-17 12:42:01 +00:00
akwizgran 076debdc4b Merge branch '1328-reuse-port' into 'master'
Choose port in advance when providing wifi access point

Closes #1328

See merge request briar/briar!1228
2020-02-17 12:37:29 +00:00
akwizgran ed13cbca6a Add support for IPv4 link-local addresses. 2020-02-17 11:42:13 +00:00
akwizgran 49cb1d0612 Choose port in advance when providing wifi access point. 2020-02-14 16:56:00 +00:00
akwizgran eb562f8f6b Bump version numbers for 1.2.7 release. 2020-02-14 09:51:14 +00:00
Torsten Grote d9b3ee7f77 Merge branch '1707-fragment-listeners' into 'master'
Don't overwrite listener references with null during fragment changes

Closes #1707, #1706, #1704, and #1697

See merge request briar/briar!1227
2020-02-13 17:47:09 +00:00
akwizgran c206b46e28 Don't overwrite listener references with null during fragment changes. 2020-02-13 15:58:26 +00:00
akwizgran 62ef64db11 Bump version numbers for 1.2.6 release. 2020-02-13 11:33:18 +00:00
akwizgran c2e83dd21d Update translations. 2020-02-13 11:32:19 +00:00
akwizgran 48048dd2fd Merge branch '1483-crash-logging' into 'master'
Log the role we find when failing to parse creator session

See merge request briar/briar!1225
2020-02-12 17:26:32 +00:00
akwizgran 17335811ec Merge branch '1699-no-browser' into 'master'
Check if browser intent resolves before starting

Closes #1699

See merge request briar/briar!1226
2020-02-12 14:48:58 +00:00
Torsten Grote 9946fe806a [android] check if browser intent resolves before starting
This prevents a crash on systems without a browser
2020-02-12 10:43:59 -03:00
Torsten Grote 748d249771 [core] log the role when failing to parse creator session 2020-02-12 09:31:16 -03:00
akwizgran 68d6b4b2ac Merge branch '1665-recyclerview-selection' into 'master'
Upgrade recyclerview and selection library to fix crashes

Closes #1665

See merge request briar/briar!1224
2020-02-12 11:24:22 +00:00
Torsten Grote cf48efae34 [android] upgrade recyclerview and selection library 2020-02-12 08:02:25 -03:00
akwizgran 287be6aa3f Merge branch '1695-show-no-internet-snackbar-when-tor-disabled' into 'master'
Show "No Internet" snackbar when Tor plugin is not active

Closes #1695

See merge request briar/briar!1222
2020-02-11 17:28:05 +00:00
Torsten Grote 1e4ad67ffc [android] Fix climbing snackbar
Use a fresh snackbar for pending contacts each time it needs to be
shown. Don't re-use the old instance and clear it in onStop().
2020-02-11 13:25:15 -03:00
Torsten Grote c976dd02ae [android] Show "No Internet" snackbar when Tor plugin is not active 2020-02-11 12:59:28 -03:00
Torsten Grote c4761c3bb2 Merge branch 'ignore-ble-for-bt-discovery' into 'master'
Ignore BLE-only devices during BT discovery

See merge request briar/briar!1221
2020-02-07 13:18:53 +00:00
Torsten Grote 0ff182b5af Merge branch 'message-tree-thread-safety' into 'master'
Ensure MessageTreeImpl#contains() is thread-safe

See merge request briar/briar!1213
2020-01-23 11:02:55 +00:00
akwizgran b904b6ea51 Ensure MessageTreeImpl#contains() is thread-safe. 2020-01-23 10:14:35 +00:00
akwizgran aad92e3f32 Bump version numbers for 1.2.5 release. 2020-01-20 17:28:04 +00:00
akwizgran f816132ac2 Update translations. 2020-01-20 17:27:11 +00:00
akwizgran 0dcfa5826f Merge branch 'nav-drawer-banner' into 'master'
Hide banner of navigation drawer when not enough screen heigth available

See merge request briar/briar!1208
2020-01-15 13:35:59 +00:00
Torsten Grote 792892d933 Hide banner of navigation drawer when not enough screen heigth available 2020-01-15 09:22:50 -03:00
Torsten Grote ab9ade9a0b Merge branch '1182-hardware-backed-key' into 'master'
Encrypt DB key with hardware-backed key when available

Closes #1182

See merge request briar/briar!1207
2020-01-15 11:32:33 +00:00
akwizgran c61c9bbc02 Refactor Android-specific code out of bramble-core. 2020-01-10 17:41:10 +00:00
akwizgran f650b2236e Catch any Exception when generating stored key. 2020-01-10 16:15:56 +00:00
akwizgran 72a391b506 Break out of loop after generating key. 2020-01-10 12:22:47 +00:00
akwizgran f76d08c19a Use StrongBox on API 28+ if available. 2020-01-09 15:18:58 +00:00
akwizgran fc6b596241 Remove unnecessary key purpose. 2020-01-09 15:03:46 +00:00
akwizgran c11d09a885 Re-encrypt the DB key with the stored key. 2020-01-09 14:45:32 +00:00
akwizgran d7b05dcba0 Add javadocs. 2020-01-09 14:45:32 +00:00
akwizgran 4d3c1b4fd2 Use Android keystore for encrypting DB key.
Only for new accounts on API 23+.
2020-01-09 14:45:32 +00:00
akwizgran 8a6e886d09 Remove DB key migration code. 2020-01-09 11:22:39 +00:00
Torsten Grote 69093d6786 Merge branch '1636-compression-failure' into 'master'
Fix PNG compression on some phones

Closes #1636

See merge request briar/briar!1183
2020-01-08 16:06:39 +00:00
akwizgran 120fcf550d Merge branch 'undefined' into 'master'
Android TV leanback banner

See merge request briar/briar!1199
2020-01-08 16:00:30 +00:00
akwizgran 5af7bbb24d Merge branch 'master' into '1636-compression-failure'
# Conflicts:
#   bramble-android/src/main/java/org/briarproject/bramble/util/AndroidUtils.java
2020-01-08 15:27:01 +00:00
Torsten Grote dd3c909b31 Merge branch 'bt-address-reflection' into 'master'
Use reflection to get local Bluetooth address

See merge request briar/briar!1202
2020-01-08 14:05:01 +00:00
Torsten Grote 4f1e9067e3 Merge branch '68-enable-private-message-deletion-in-release-builds' into 'master'
Enable private message deletion in release builds

See merge request briar/briar!1206
2020-01-08 14:00:03 +00:00
akwizgran 9305532079 Enable private message deletion in release builds. 2020-01-07 12:43:10 +00:00
akwizgran bbcdd9418c Revert breaking change to Korean translation. 2020-01-07 12:35:25 +00:00
akwizgran 373ca0e0ea Update translations. 2020-01-07 11:30:21 +00:00
akwizgran e4af161db5 Merge branch 'fix-test-sensitivity-to-arrival-order' into 'master'
Fix sensitivity of integration tests to message arrival order

See merge request briar/briar!1205
2019-12-20 12:12:36 +00:00
akwizgran 9b37cb19f4 Reset counters before each test. 2019-12-19 17:55:56 +00:00
akwizgran 016178045f Make integration tests less sensitive to sync order. 2019-12-19 17:45:32 +00:00
akwizgran dae08b2af4 Merge branch '1677-note-alias-key' into 'master'
Add warning about alias key to headless contacts response documentation

See merge request briar/briar!1204
2019-12-17 12:26:16 +00:00
Nico Alt 3bc349e426 Add warning about alias key to headless contacts response documentation
Quick fix for https://code.briarproject.org/briar/briar/issues/1677.
2019-12-16 15:30:02 +01:00
akwizgran bd478c5074 Ignore BLE-only devices during BT discovery. 2019-12-12 17:24:09 +00:00
akwizgran 26144c18d8 Download test assets, fix expectations. 2019-12-12 14:25:40 +00:00
akwizgran ace1d38966 Disable PngSuite test by default.
Results are device-dependent and outside our
control.
2019-12-12 14:25:40 +00:00
akwizgran 24a63b08c0 Add transparent PNG. 2019-12-12 14:25:40 +00:00
akwizgran 44411ab224 Simplify code. 2019-12-12 14:25:40 +00:00
akwizgran 6d742c554f Test that PngSuite corrupt test images fail. 2019-12-12 14:25:40 +00:00
akwizgran 1e2ccd96a7 Remove support for GIF attachments on API < 24. 2019-12-12 14:25:40 +00:00
Torsten Grote 1000512c5b [android] Add PngSuite images to compression test 2019-12-12 14:25:37 +00:00
Torsten Grote c7a0f794c8 [android] Fix PNG compression with different BitmapConfig
Source: https://stackoverflow.com/a/6140360
2019-12-12 10:04:49 +00:00
Torsten Grote 62970cce30 [android] add instrumentation test for image compression 2019-12-12 10:04:44 +00:00
Torsten Grote 6a31274b76 Merge branch 'remove-default-methods' into 'master'
Replace default methods with helper classes

See merge request briar/briar!1203
2019-12-11 16:44:59 +00:00
akwizgran 5962d3c763 Replace default methods with helper classes.
This is a workaround for AbstractMethodErrors
thrown by on-device tests.
2019-12-11 16:28:19 +00:00
Torsten Grote 6f38e70ad2 Merge branch 'tor-0.3.5.9' into 'master'
Upgrade Tor to 0.3.5.9

See merge request briar/briar!1201
2019-12-11 13:10:43 +00:00
akwizgran 61324b1cb0 Catch SecurityException.
This isn't currently thrown, but future versions
of Android might throw it.
2019-12-11 12:03:37 +00:00
akwizgran d1e21877b3 Use reflection to get local Bluetooth address.
This is expected to work on Android 8 but not 8.1+.
2019-12-11 11:48:53 +00:00
akwizgran 61293c0747 Upgrade Tor to 0.3.5.9. 2019-12-11 09:43:24 +00:00
Torsten Grote 5ba64577bd Merge branch '68-tweak-deletion-error-messages' into 'master'
Tweak the error dialog when message deletion fails

See merge request briar/briar!1200
2019-12-10 16:56:48 +00:00
akwizgran 3486cc8fcc Tweak the error dialog when message deletion fails. 2019-12-10 16:05:03 +00:00
akwizgran a1357c22b2 Fix checksum for jackson-annotations.
See https://issues.sonatype.org/browse/OSSRH-51881
2019-12-10 13:44:30 +00:00
akwizgran 86693abd66 Merge branch '1656-explain-deletion-failures' into 'master'
Better explain why messages could not be deleted

Closes #1656

See merge request briar/briar!1197
2019-12-10 12:38:07 +00:00
Torsten Grote 0edb2b7b6e [core] Add JavaDoc for MessageRetreiver of IntroductionManager
for message deletion
2019-12-10 09:02:43 -03:00
akwizgran ffc2c5d900 Merge branch 'javalin-3.5' into 'master'
Upgrade headless to Javalin 3.5

See merge request briar/briar!1162
2019-12-10 10:11:55 +00:00
Hugh Isaacs II 6380133fcd Update briar-android/src/main/AndroidManifest.xml, briar-android/src/main/res/mipmap-xhdpi/tv_banner.png files 2019-12-02 16:29:25 +00:00
Hugh Isaacs II 1ae4062f01 Android TV leanback banner 2019-12-02 16:13:15 +00:00
Torsten Grote 9ebe49b85d [headless] Let websocket upgrade requests pass in AccessManager
This is because JavaScript in browsers apparently can not add Authentication
headers to websocket requests, so we use a dedicated authentication message there.

In Javalin 3, the AccessManager also handles websocket requests.
We need to let those pass to support JavaScript.
2019-11-14 14:13:54 -03:00
Torsten Grote 6f153f14c7 [headless] upgrade to Javalin 3.5 2019-11-14 14:13:54 -03:00
Torsten Grote 5aeee9af8b [core] address review comments for message deletion explanation 2019-11-14 14:05:28 -03:00
akwizgran 52feabecbe Merge branch 'disable-google-tracking' into 'master'
Disable instrumentation test analytics

See merge request briar/briar!1198
2019-11-14 14:07:50 +00:00
Torsten Grote 53fb3f78c1 [android] disable instrumentation test analytics 2019-11-13 14:12:07 -03:00
Torsten Grote ae0fa351b6 Better explain why messages could not be deleted
This also fixes a bug in the IntroductionManager that would allow to
delete only part of a session's visible messages.
2019-11-11 13:09:51 -03:00
akwizgran 11c43dc7f4 Merge branch '1628-multi-select' into 'master'
Multi-select conversion messages (to delete)

Closes #1628

See merge request briar/briar!1179
2019-11-08 13:05:09 +00:00
Torsten Grote 497ab38be1 [android] highlight selected messages with accent color 2019-11-08 09:54:04 -03:00
Torsten Grote ddcb412fcd [core] remove notice about removing support for old message type 2019-11-07 15:31:24 -03:00
Torsten Grote 71243ce561 [android] prevent empty state message from showing up briefly when clearing list 2019-11-07 15:30:25 -03:00
Torsten Grote 5c900c443d [core] also support private messages in legacy format for selective deletion 2019-11-07 14:39:50 -03:00
Torsten Grote 97dd9b901d [android] hook up UI to ConversationManager to actually delete messages 2019-11-07 14:39:50 -03:00
Torsten Grote 9ce327a40c [android] highlight selected conversation messages in UI 2019-11-07 14:39:50 -03:00
Torsten Grote a9b9a8c5f8 [android] allow to select multiple conversation messages 2019-11-07 14:39:49 -03:00
akwizgran ed66a470cc Merge branch '1643-controller-leaks' into 'master'
Fix controller memory leaks

Closes #1643

See merge request briar/briar!1184
2019-11-07 16:33:18 +00:00
akwizgran 405c243313 Merge branch '1243-attachment-close-button-color' into 'master'
Change image preview close button color to accent color

See merge request briar/briar!1182
2019-11-07 16:23:24 +00:00
Torsten Grote 034e76dd5c [android] Fix controller memory leaks 2019-11-07 12:57:41 -03:00
Torsten Grote 73417a42d6 [android] change image preview close button color to accent color
This was suggested in #1243.
2019-11-07 12:56:52 -03:00
akwizgran 9d72fca2a7 Merge branch 'AndroidX' into 'master'
AndroidX Migration

See merge request briar/briar!1176
2019-11-07 15:40:19 +00:00
akwizgran b4e0d3b982 Merge branch '1653-npe-settings-fragment' into 'master'
Don't try to display settings before they are fully loaded

Closes #1653

See merge request briar/briar!1194
2019-11-07 15:29:55 +00:00
Torsten Grote 088ca01eb3 [android] re-include BrambleCoreModule since issue caused by it also exists on master 2019-11-07 12:20:03 -03:00
Torsten Grote 83ed6f90d7 [core] downgrade okhttp to 3.12.x series to support our minSdk level 2019-11-07 11:49:45 -03:00
Torsten Grote ab7b287082 [android] downgrade zxing to 3.3.3 because newer versions need minSdk 24 2019-11-07 10:44:08 -03:00
Torsten Grote 4fe41bfde7 Merge branch 'remove-beta-build-flag' into 'master'
Remove beta build flag

Closes #1527

See merge request briar/briar!1196
2019-11-06 17:53:02 +00:00
Torsten Grote 2e65122e9d Merge branch 'client-versioning-events' into 'master'
Update image attachment UI when new client version is received from contact

Closes #1638

See merge request briar/briar!1195
2019-11-06 17:52:43 +00:00
akwizgran ee180defce Remove expiry update code, fix references to Briar 1.0. 2019-11-06 14:21:52 +00:00
akwizgran 7ee0febf0c Use TimeUnit to make durations more readable. 2019-11-06 14:21:52 +00:00
akwizgran 216f0598f9 Remove ancient flag for beta builds. 2019-11-06 14:20:11 +00:00
akwizgran 27cba75a50 Fix test expectations. 2019-11-06 14:17:16 +00:00
akwizgran b3bc5e69b5 Use client versioning event to update UI. 2019-11-06 13:58:11 +00:00
akwizgran ee1fd2ad8a Broadcast events for client versioning updates. 2019-11-06 13:58:11 +00:00
akwizgran a844526dae Refactor ClientVersion to bramble-api. 2019-11-06 13:58:06 +00:00
Torsten Grote cb5a9bdff8 [android] don't try to display settings before they are fully loaded 2019-11-06 09:21:28 -03:00
akwizgran 75dfa80541 Bump version numbers for 1.2.4 release. 2019-11-06 09:58:00 +00:00
akwizgran 41b59fbcfe Merge branch '1610-pending-contacts-offline-snackbar' into 'master'
Don't show offline snackbar when there's no pending contacts

Closes #1610

See merge request briar/briar!1193
2019-11-06 09:50:39 +00:00
akwizgran 98a4f5def1 Merge branch '1654-notification-channel-unavailable' into 'master'
Fail gracefully when ACTION_CHANNEL_NOTIFICATION_SETTINGS is not available

Closes #1654

See merge request briar/briar!1192
2019-11-06 09:49:21 +00:00
akwizgran aeefa35f38 Merge branch '1454-theme-system-crash' into 'master'
Prevent crash when user has set theme to system default on unsupported API level

Closes #1454

See merge request briar/briar!1191
2019-11-06 09:46:48 +00:00
akwizgran 4e7f33edfd Merge branch '1483-group-invite-not-allowed' into 'master'
Make sure group actions can only be made by the correct role

See merge request briar/briar!1190
2019-11-06 09:45:28 +00:00
akwizgran f1e957ffed Merge branch '1655-no-bluetooth-activity' into 'master'
Check if REQUEST_BLUETOOTH_DISCOVERABLE is available before launching

Closes #1655

See merge request briar/briar!1189
2019-11-06 09:42:00 +00:00
akwizgran 9e3fed6bc0 Merge branch '1651-no-ringtone-picker' into 'master'
Check if ringtone picker is available before launching it

Closes #1485 and #1651

See merge request briar/briar!1188
2019-11-06 09:40:30 +00:00
Torsten Grote bf9a39cc6c [android] don't show offline snackbar when there's no pending contacts
If the pending contact list is opened concurrently
with the last pending contact being removed (unlikely but possible)
then the "no internet connection" snackbar would be shown
even though the app is connected to Tor.
2019-11-05 15:35:10 -03:00
Torsten Grote 72aa5397f8 [android] fail gracefully when ACTION_CHANNEL_NOTIFICATION_SETTINGS is not available 2019-11-05 15:17:10 -03:00
Torsten Grote 21eaab3259 [android] prevent crash when user has set theme to system default
on an API level that does not support it.
2019-11-05 14:57:25 -03:00
Torsten Grote 92d595da35 [android] make sure group actions can only be made by the correct role 2019-11-05 14:46:10 -03:00
Torsten Grote 5e85566fc3 [android] check if REQUEST_BLUETOOTH_DISCOVERABLE is available before launching 2019-11-05 12:54:02 -03:00
Torsten Grote 1574bf35fc [android] do not use file:// Uris for notification sounds
This causes a FileUriExposedException otherwise.

Closes #1485
2019-11-05 12:31:25 -03:00
Torsten Grote 533e01e881 [android] check if ringtone picker is available before launching
Also refuse file:// Uri as they cause a FileUriExposedException as in #1485
2019-11-05 12:03:00 -03:00
Torsten Grote 0103835601 [android] upgrade design library to fix memory leak 2019-11-01 14:12:24 -03:00
Torsten Grote dc1183b4cc [android] Apply updated Android XML layout formatting 2019-11-01 11:47:35 -03:00
Torsten Grote 044e1ebe73 [android] Fix theme of DevReportActivity after AndroidX migration 2019-11-01 11:47:34 -03:00
Torsten Grote 494e51ef07 Optimize imports after AndroidX migration 2019-11-01 11:47:33 -03:00
Torsten Grote 1be078d181 Change CI config so that it finds more breakages
Previously we did not run lint and did not try to compile the
AndroidTest instrumentation tests.
2019-11-01 11:44:37 -03:00
Torsten Grote 98eb78c7bc [android] fix instrumentation tests after AndroidX migration 2019-11-01 11:44:36 -03:00
Torsten Grote 9d31a0a536 [android] Fix robolectric test after AndroidX migration 2019-11-01 11:44:36 -03:00
Torsten Grote a592c05146 AndroidX migration and library updates 2019-11-01 11:44:36 -03:00
akwizgran 383367f0c8 Merge branch 'remove-remove-contacts-feature-flag' into 'master'
Remove contacts feature flag

See merge request briar/briar!1185
2019-11-01 14:29:37 +00:00
Torsten Grote ca052ea7dd update translations 2019-11-01 11:12:26 -03:00
Torsten Grote 5147f6b7e6 Remove RemoteContacts feature flag in preparation of 1.2 release 2019-11-01 11:09:43 -03:00
akwizgran 84a8ff1dd8 Merge branch '1629-delete-message-subset' into 'master'
Support for deleting a subset of all conversation messages

Closes #1629

See merge request briar/briar!1180
2019-10-28 16:52:41 +00:00
Torsten Grote 6c489fbea3 [core] also delete attachments when deleting select messages 2019-10-28 10:22:04 -03:00
Torsten Grote c7200910c9 [core] address feedback for selective conversation message deletion 2019-10-28 09:45:41 -03:00
akwizgran 663e5c4b46 Merge branch '1405-emoji-keyboard' into 'master'
Always show keyboard when clicking text input field

Closes #1405

See merge request briar/briar!1181
2019-10-28 12:16:15 +00:00
Torsten Grote 529eaceec7 [android] show keyboard when clicking text input field 2019-10-22 12:43:35 -03:00
Torsten Grote f516dbe34f [core] add method to ConversationManager for deleting a set of messages 2019-10-22 11:18:10 -03:00
Torsten Grote 5b515d7e18 [core] implement subset conversation message deletion for IntroductionManager 2019-10-22 11:18:10 -03:00
Torsten Grote ef04a26cfc [core] implement subset conversation message deletion for GroupInvitationManager 2019-10-22 11:18:09 -03:00
Torsten Grote 2e6fe42074 [core] implement subset conversation message deletion for SharingManager 2019-10-22 11:18:09 -03:00
Torsten Grote 124e2f99b0 [core] Add method to ConversationClient for deleting a set of messages
This also implements the method for MessagingManager
(including integration tests) and adds no-op implementations for other
clients.
2019-10-22 11:18:09 -03:00
Torsten Grote 190a6bff96 [core] Add method to ConversationClient that returns a set of MessageIds it is responsible for 2019-10-22 11:18:08 -03:00
Torsten Grote 01df141c08 Merge branch '843-landscape-keyboard' into 'master'
Raise target API version to 28 and fix soft keyboard issues

Closes #1505

See merge request briar/briar!1043
2019-10-21 12:38:38 +00:00
Torsten Grote d7c9bf80de Merge branch 'xml-formatting-settings' into 'master'
Update XML code style settings

See merge request briar/briar!1178
2019-10-18 16:51:30 +00:00
akwizgran 3a5e51e248 Update XML code style settings. 2019-10-18 17:38:41 +01:00
akwizgran a76e3dcec1 Fix bug with enter key when rotating screen. 2019-10-18 14:03:01 +01:00
akwizgran 0fdc7199ed Hide keyboard when contact alias dialog is closed. 2019-10-18 14:03:01 +01:00
akwizgran 248f482fee Use requestFocus tag for RSS import. 2019-10-18 14:03:00 +01:00
akwizgran 4196d046a3 Use stateAlwaysVisible for consistent behaviour. 2019-10-18 14:03:00 +01:00
akwizgran 722ebb22f6 Use requestFocus tag to request initial focus. 2019-10-18 13:45:48 +01:00
akwizgran a4f561ca1a Request focus when showing soft keyboard. 2019-10-18 13:45:48 +01:00
akwizgran c7db0bf6fa Remove unused listener implementation. 2019-10-18 13:45:47 +01:00
akwizgran ca6f458551 Always hide keyboard when importing RSS feed. 2019-10-18 13:45:47 +01:00
akwizgran c85990408a Remove redundant requestFocus() call. 2019-10-18 13:45:47 +01:00
akwizgran 3ed0204170 Clean up soft input modes. 2019-10-18 13:45:46 +01:00
akwizgran e2b3340734 Remove redundant methods for showing/hiding keyboard. 2019-10-18 13:45:45 +01:00
akwizgran 78aac8de52 Replace EditText with TextInputEditText. 2019-10-18 13:45:45 +01:00
akwizgran 971ae3a20e Raise target API level to 28. 2019-10-18 13:45:44 +01:00
Torsten Grote 622e7a775a [android] Soft keyboard fixes
1. Manually request focus for input fields and show keyboard

This is needed when targetting API 28 which doesn't give focus anymore
automatically like it used to be.

Closes #1505

2. Remember keyboard states across screen rotations

This also upgrades the emoji library and gets rid of the
KeyboardAwareLinearLayout that is still a relict from the time when we
were using Signal's emoji implementation.

3. Move soft keyboard showing/hiding into UiUtils
2019-10-18 13:44:44 +01:00
akwizgran 103e8482b0 Merge branch 'codeStylesAS3.5' into 'master'
Android Studio 3.5 changed our codeStyles

See merge request briar/briar!1177
2019-10-17 16:56:13 +00:00
Torsten Grote ddcfc11012 Android Studio 3.5 changed our codeStyles 2019-10-17 13:33:51 -03:00
akwizgran ab2e40abde Merge branch '1565-duplicate-remote-contacts' into 'master'
UX for handling duplicate handshake links

Closes #1565

See merge request briar/briar!1173
2019-10-16 16:16:08 +00:00
Torsten Grote 1ddceaadd6 Always replace pending contacts no matter their state when link is re-entered 2019-10-16 13:06:21 -03:00
akwizgran 7a644f7d8b Merge branch '1210-fix-list-duplicates' into 'master'
[android] Fix duplicate items in lists

Closes #1210

See merge request briar/briar!1174
2019-10-16 14:32:49 +00:00
Torsten Grote 397afbfec0 Address review comments for detecting duplicate (pending) contacts 2019-10-16 11:15:14 -03:00
Torsten Grote 0d4cb05ac0 [android] fix possible duplicates in list
When doing reloads of list items such as when adding test contacts,
we loaded different versions of those items and added them to the list.
According to the documentation
https://developer.android.com/reference/android/support/v7/util/SortedList.html#add
> If the sorting criteria of the item is changed,
> SortedList won't be able to find its duplicate in the list
> which will result in having a duplicate of the Item in the list.

For the contact list at least, new contacts caused reloads of the entire list
and new messages caused the contacts to be sorted differently.
Thus we ended up with duplicate contacts in the list.

This commit fixes this by replacing the contacts in the list instead of adding them.
It applies the same fix to forums and private groups
which use the same logic and are thus also affected.

Fixes #1210
2019-10-15 16:25:10 -03:00
Torsten Grote aa0937e6aa [android] Show dialog when (pending) contact already exists
If two different people sent the same link, show warning dialog to the
user to prevent a social attack trying to discover contact
relationships.
2019-10-15 14:47:42 -03:00
Torsten Grote 4bf8d4c0e7 [bramble] add method for getting pending contact state 2019-10-15 14:46:37 -03:00
Torsten Grote 75fcd28071 [bramble] throw exceptions when adding pending contact which exists 2019-10-15 10:32:52 -03:00
Torsten Grote 5f29ab3b40 [bramble-core] Add DB method for getting contact by handshake key 2019-10-15 10:12:59 -03:00
Torsten Grote f45d00e23c Update translations, add Bosnian and Swahili 2019-10-14 15:11:44 -03:00
akwizgran 2b589c2da6 Merge branch 'tor64' into 'master'
Add support for 64-bit Tor binaries

Closes #1506

See merge request briar/briar!1161
2019-10-14 16:33:53 +00:00
akwizgran 67d15ec82e Merge branch '1633-min-api-16' into 'master'
[android] Raise minimum API level to 16

Closes #1633

See merge request briar/briar!1171
2019-10-14 15:37:43 +00:00
akwizgran 2d44d749ba Merge branch '1627-test-fix' into 'master'
Fix group sharing message deletion test

See merge request briar/briar!1168
2019-10-14 15:36:12 +00:00
Torsten Grote 6ef86c5638 Merge branch 'remove-tor-settings-migration' into 'master'
Remove old migration code for Tor settings

See merge request briar/briar!1172
2019-10-14 15:28:24 +00:00
akwizgran 131f9b9696 Remove old migration code for Tor settings. 2019-10-14 16:00:43 +01:00
akwizgran a876d4cfb7 Remove a couple of redundant comments. 2019-10-14 15:59:14 +01:00
akwizgran fafcacf808 Remove a couple more API version checks. 2019-10-14 15:56:44 +01:00
akwizgran 7a0d990f0b Don't include non-PIE binaries in APK.
This shouldn't be merged before raising the minimum
API version to 16.
2019-10-14 15:49:37 +01:00
Torsten Grote 234bdf686e [android] Raise minimum API level to 16 2019-10-14 11:49:06 -03:00
akwizgran edb9da107f Merge branch '1632-allow-resharing-shareable' into 'master'
Allow sharer to re-share a shareable again after leaving

Closes #1632

See merge request briar/briar!1169
2019-10-14 14:29:38 +00:00
Torsten Grote d1d4914c6a Merge branch '1582-restore-recycler-view-behaviour' into 'master'
Restore custom layout behaviour for handling snackbar

Closes #1582

See merge request briar/briar!1170
2019-10-14 14:26:01 +00:00
Torsten Grote 9261d23bba [core] allow sharer to re-share a shareable again after leaving 2019-10-14 11:13:01 -03:00
akwizgran f4febe90c9 Restore custom layout behaviour for handling snackbar. 2019-10-14 14:45:23 +01:00
Torsten Grote ecd766b204 [core] Fix group sharing message deletion test 2019-10-14 09:40:52 -03:00
akwizgran ca4fc2dc26 Merge branch '1627-delete-completed-privategroup-sessions' into 'master'
Delete conversation messages belonging to completed private group sessions

Closes #1627

See merge request briar/briar!1167
2019-10-14 11:57:27 +00:00
akwizgran c3ddcdffe0 Merge branch '1627-delete-completed-sharing-sessions' into 'master'
Delete conversation messages belonging to completed sharing sessions

See merge request briar/briar!1164
2019-10-14 11:45:30 +00:00
Torsten Grote 2e37619357 [android] use new obfs4 release with only pie builds and fixed arm64 2019-10-10 10:01:15 -03:00
Torsten Grote c247d745df [bramble-android] add support for 64-bit Tor binaries 2019-10-10 09:29:24 -03:00
akwizgran 3a4de3d2cb Merge branch '68-fix-message-tracker' into 'master'
Fix MessageTracker group counts after deleting messages

See merge request briar/briar!1166
2019-10-10 08:54:45 +00:00
Torsten Grote 04f1036dbf [android] Change non-deletion message to refer to ongoing sessions 2019-10-09 17:21:41 -03:00
Torsten Grote 9736f9d31f [core] allow messages from private group sessions with responses get deleted 2019-10-09 17:21:41 -03:00
Torsten Grote 440d5239b1 [core] track GroupCount properly when deleting messages from SharingManager 2019-10-09 13:32:41 -03:00
Torsten Grote e4a8b10b94 [core] allow messages from shareable sessions with responses get deleted 2019-10-09 13:22:37 -03:00
Torsten Grote 41676065c5 [core] Fix MessageTracker group counts after deleting messages 2019-10-09 13:19:43 -03:00
Torsten Grote 1fcc83a0d0 Merge branch 'feature-flag-message-deletion' into 'master'
Add feature flag for private message deletion

See merge request briar/briar!1165
2019-10-09 15:56:17 +00:00
akwizgran 249b85cd26 Add feature flag for private message deletion. 2019-10-09 16:22:04 +01:00
akwizgran a23e0699d8 Merge branch '1627-delete-completed-introduction-sessions' into 'master'
Delete conversation messages belonging to completed introduction sessions

See merge request briar/briar!1163
2019-10-09 12:39:05 +00:00
Torsten Grote e3e47dae48 [core] throw AssertionError if SessionId is missing
Also remove stale comment
2019-10-09 08:27:33 -03:00
Torsten Grote 9660ff2fff [core] delete conversation messages belonging to completed introduction sessions
A session is completed if it returned to the START state
and if all sent messages have been ACKed by the receiver.

The session's metadata is kept in case the user restarts the session
by doing another introduction.
2019-10-09 08:24:16 -03:00
akwizgran ea810c817b Merge branch '1626-delete-all-messages-ui' into 'master'
Add conversation menu action to delete all messages

Closes #1626

See merge request briar/briar!1159
2019-10-07 16:56:44 +00:00
Torsten Grote 876d50975e [android] fix typo s/can not/cannot/ 2019-10-07 12:08:18 -03:00
akwizgran bf5bdc52b4 Merge branch '1577-headless-readme-improvements' into 'master'
Clarify minor things in headless readme

Closes #1577

See merge request briar/briar!1157
2019-10-07 14:55:17 +00:00
akwizgran 29320c410e Merge branch '1625-conversation-client-message-deletion' into 'master'
Add ConversationManager method for deleting all messages

Closes #1625

See merge request briar/briar!1158
2019-10-07 14:44:41 +00:00
Nico Alt d41472a18c Clarify minor things in headless readme
Based on answers received in #1577, I tried to clarify outstanding
questions I had about the Briar Headless API.

Fixes #1577.
2019-10-07 16:35:21 +02:00
akwizgran c411065255 Merge branch '1582-pending-contacts-snackbar-fab' into 'master'
Use snackbar-aware behaviour for FAB.

Closes #1582

See merge request briar/briar!1156
2019-10-07 13:48:01 +00:00
Torsten Grote 3ac5646355 [briar-android] Add conversation menu action to delete all messages 2019-10-03 15:24:36 -03:00
Torsten Grote c46fdce277 Add ConversationManager method for deleting all messages
Note that this does not yet delete special conversation messages
such as invitations or introductions and their responses.
2019-10-03 14:47:12 -03:00
akwizgran 643ef593e1 Use dodgeInsetEdges to make room for the snackbar. 2019-10-02 12:16:24 +01:00
akwizgran eda17449be Merge branch '1582-pending-contacts-snackbar' into 'master'
Prevent pending contacts snackbar from covering contact list

See merge request briar/briar!1152
2019-10-01 12:18:11 +00:00
Torsten Grote 28f82a1507 Use snackbar-aware behaviour for FAB. 2019-10-01 13:01:44 +01:00
Torsten Grote 8734825346 [android] prevent pending contacts snackbar from covering contact list 2019-10-01 08:53:14 -03:00
akwizgran 640f3d63b0 Merge branch '1583-remote-contacts-small-screens' into 'master'
Make Remote Contact layouts work on small screens

Closes #1583

See merge request briar/briar!1155
2019-09-27 14:58:43 +00:00
akwizgran b1dfd867f0 Bump version numbers for 1.1.9 release. 2019-07-03 12:16:52 +01:00
Torsten Grote ff76900d74 Merge branch '1609-trimmed-text-length' into 'master'
Use trimmed length when deciding whether text is empty

Closes #1609

See merge request briar/briar!1153
2019-07-01 16:25:15 +00:00
Torsten Grote 945fdb8ee4 [android] Make Remote Contact layouts work on small screens 2019-07-01 17:56:28 +02:00
Torsten Grote 53fe3e1592 Merge branch '1428-android-debug-logging' into 'master'
Enable debug logging for debug and beta builds

Closes #1428

See merge request briar/briar!1154
2019-07-01 14:34:06 +00:00
akwizgran be76c5b7db Add safety annotations. 2019-07-01 14:38:28 +01:00
akwizgran 909e946e58 Enable debug logging for debug and beta builds. 2019-07-01 14:34:51 +01:00
akwizgran 408d9ddee4 Rename directory for traditional Chinese translation. 2019-07-01 10:14:08 +01:00
akwizgran 0e5027e725 Update list of translations. 2019-07-01 01:35:52 +01:00
akwizgran 2d4c97a69e Update translations, add new translations. 2019-07-01 01:26:27 +01:00
akwizgran 7d62ae5fa8 Use trimmed length when deciding whether text is empty. 2019-07-01 01:13:24 +01:00
Torsten Grote bd616853cf Merge branch '1607-upgrade-rome' into 'master'
Upgrade Rome to fix memory allocation bug

Closes #1607

See merge request briar/briar!1151
2019-06-28 14:17:46 +00:00
akwizgran 32e1d6c748 Upgrade Rome to fix memory allocation bug. 2019-06-28 15:09:09 +01:00
akwizgran 6b022afa67 Bump version numbers for 1.1.8 release. 2019-06-28 14:48:00 +01:00
akwizgran e8b454b25b Update translations. 2019-06-28 14:47:03 +01:00
Torsten Grote 54c05b5ffe Merge branch '1606-bump-client-minor-version' into 'master'
Bump client minor version to avoid triggering crash

Closes #1606

See merge request briar/briar!1150
2019-06-28 13:28:37 +00:00
akwizgran d145a082f5 Bump client minor version to avoid triggering crash. 2019-06-28 14:07:28 +01:00
akwizgran 4fd012c31a Merge branch 'compress-images' into 'master'
Compress images

See merge request briar/briar!1147
2019-06-26 14:21:24 +00:00
akwizgran 95d06770bf Rename 'scale' to 'inSampleSize' for clarity. 2019-06-26 14:36:40 +01:00
akwizgran 428247b7b2 Initialise result LiveData before starting task. 2019-06-26 14:31:40 +01:00
akwizgran a921361a56 Inject ImageSizeCalculator. 2019-06-26 12:40:28 +01:00
akwizgran fe7dfa721e Compress image attachments. 2019-06-25 16:55:09 +01:00
akwizgran 92eb06a9e9 Refactor attachment creation to use injection. 2019-06-25 16:29:54 +01:00
Torsten Grote 5beed1a748 Merge branch '1594-preview-fails-to-load' into 'master'
Use a fresh LiveData for each attachment creation task

Closes #1594

See merge request briar/briar!1144
2019-06-20 14:05:43 +00:00
Torsten Grote 774047d856 Merge branch '1585-check-attachment-content-type' into 'master'
Improve handling of missing attachments in UI

See merge request briar/briar!1142
2019-06-20 14:04:02 +00:00
Torsten Grote fc28e7aa88 Merge branch 'nickname-nitpicks' into 'master'
Nickname nitpicks

See merge request briar/briar!1143
2019-06-20 13:41:25 +00:00
Torsten Grote 78459499b2 Merge branch '1593-qr-code-assertion-error' into 'master'
Keep enum methods used by ZXing

Closes #1593

See merge request briar/briar!1146
2019-06-19 23:45:49 +00:00
akwizgran c2973608d7 Keep enum methods used by ZXing. 2019-06-19 16:36:39 +01:00
akwizgran be1c33cb42 Use a fresh LiveData for each attachment creation task. 2019-06-19 13:43:04 +01:00
akwizgran c955466bda Load missing attachments when they arrive. 2019-06-19 12:47:18 +01:00
akwizgran 593a0c4632 Improve handling of missing and invalid attachments. 2019-06-19 11:23:57 +01:00
akwizgran ed20b2d8d6 Use attachment header to retrieve attachment. 2019-06-19 10:57:13 +01:00
akwizgran 34583e6d2d Merge branch '1054-crash-scroll' into 'master'
Improve crash screen and reporter

Closes #1426, #1061, #1390, #1012, and #1054

See merge request briar/briar!1049
2019-06-18 16:47:02 +00:00
Torsten Grote ea5a862242 [android] Fix send button in ReportForm's action bar 2019-06-18 13:28:28 -03:00
akwizgran 9ab9e02f8a Trim whitespace from nicknames (useful for auto-complete). 2019-06-18 17:24:08 +01:00
akwizgran 3f70ae3c8c Use same input type for nicknames everywhere. 2019-06-18 17:19:39 +01:00
Torsten Grote 3f60098099 [android] don't cancel crash reports after sending them 2019-06-18 12:21:04 -03:00
Torsten Grote e965021e3d [android] don't clear task when submitting feedback, only after crash 2019-06-18 12:21:04 -03:00
Torsten Grote 7d9380d3d6 [android] go to homescreen after pressing back in crash reporter
Fixes #1390
2019-06-18 12:21:04 -03:00
Torsten Grote 3c8c0e579e [android] point ACRA to correct BuildConfig class
Fixes #1061
2019-06-18 12:21:03 -03:00
Torsten Grote bd2bbe9268 [android] don't show JSON in feedback/crash report
use key-value pairs instead

Closes #1426
2019-06-18 12:21:03 -03:00
Torsten Grote 89d24b1753 [android] Make entire report form scrollable, not only the hidden data 2019-06-18 12:21:03 -03:00
Torsten Grote 861dbe20b1 [android] Fix crash screen buttons to the bottom of the screen
and resize crash icon to the available screen space
2019-06-18 12:21:02 -03:00
Torsten Grote 197800de8b [android] split crash report screen into two fragments 2019-06-18 12:21:02 -03:00
Torsten Grote 07e824ad68 [android] Make crash screen scrollable and add icon 2019-06-18 12:21:01 -03:00
Torsten Grote d210215bd1 Merge branch '1585-new-messaging-client' into 'master'
Add support for image attachments to messaging client

Closes #1585

See merge request briar/briar!1133
2019-06-18 14:55:40 +00:00
akwizgran 00705447ec Use feature flag to decide which version to advertise. 2019-06-18 13:39:01 +01:00
akwizgran 9095ccef85 Filter attachment URIs in controller. 2019-06-18 13:10:52 +01:00
akwizgran 3196204094 Send legacy private messages from headless app. 2019-06-18 13:03:50 +01:00
akwizgran 2bae639105 Upgrade messaging client to support attachments. 2019-06-18 13:03:49 +01:00
akwizgran f73d298752 Merge branch 'inject-feature-flags' into 'master'
Use injection to provide feature flags

See merge request briar/briar!1140
2019-06-18 11:51:09 +00:00
Torsten Grote bc3a443276 Merge branch '1590-create-private-messages-on-ui-thread' into 'master'
Move private message creation off the crypto executor

Closes #1590

See merge request briar/briar!1141
2019-06-18 11:22:45 +00:00
akwizgran 2a29d33303 Move private message creation off the crypto executor. 2019-06-18 12:14:10 +01:00
akwizgran 30e0be9f43 Merge branch '1580-show-snackbar' into 'master'
Show snackbar when there is no internet connection

Closes #1580

See merge request briar/briar!1139
2019-06-18 09:54:34 +00:00
akwizgran 3828d16971 Use injection to provide feature flags. 2019-06-18 10:52:21 +01:00
akwizgran a54eb64eb5 Merge branch '1468-reject-unsupported-images' into 'master'
Reject unsupported images

Closes #1468

See merge request briar/briar!1038
2019-06-17 16:39:26 +00:00
Torsten Grote ad2d3e70d6 [android] address thread-safety issues of attachment creation 2019-06-17 13:22:38 -03:00
Torsten Grote 1f91842c52 [android] re-use the same LiveData for AttachmentResults 2019-06-17 13:11:16 -03:00
Torsten Grote c07a0a2fd7 [android] address review comments for rejecting unsupported images 2019-06-17 13:11:16 -03:00
Torsten Grote 4ee4905e06 [android] migrate added conversation header to new LiveEvent 2019-06-17 13:11:16 -03:00
Torsten Grote 67b7517f2b [android] refactor AttachmentCreator to return a single LiveData 2019-06-17 13:11:16 -03:00
Torsten Grote cd3174a643 [android] Fix view recycling issue of image previews 2019-06-17 13:11:15 -03:00
Torsten Grote 9d9bc4ca84 [android] Let AttachmentCreator return same LiveData after configuration changes 2019-06-17 13:11:15 -03:00
Torsten Grote 7358091699 [android] Address first round of review comments for attachments 2019-06-17 13:11:15 -03:00
Torsten Grote 11eefaedcf Refactor attachment creation 2019-06-17 13:11:14 -03:00
Torsten Grote bb5a6c0241 [android] Add assertions to TextAttachmentController 2019-06-17 13:11:14 -03:00
Torsten Grote 70d29af2ba [android] Allow sending message with attachments before previews are loaded 2019-06-17 13:11:14 -03:00
Torsten Grote baedb14e2b [android] allow attaching only of images with supported mime type 2019-06-17 13:11:13 -03:00
Torsten Grote 2796926709 [android] Load image preview from database instead of content Uri 2019-06-17 13:11:13 -03:00
Torsten Grote fc6275b037 [android] reject invalid mime types for image attachments 2019-06-17 13:11:13 -03:00
Torsten Grote f76f9be4ed Reject attachments that exceed the allowed size
Closes #1468
2019-06-17 13:11:13 -03:00
Torsten Grote 6167ba5c46 [android] move unsent attachment cache logic into AttachmentController 2019-06-17 13:11:12 -03:00
Torsten Grote 55f4600a69 [android] Create attachments before showing previews 2019-06-17 13:11:12 -03:00
Torsten Grote c73801c7e8 [android] Show snackbar when there is no internet connection 2019-06-17 10:11:02 -03:00
Torsten Grote 249e1e28fe Merge branch '1580-offline-state' into 'master'
Add offline state for pending contacts

Closes #1580

See merge request briar/briar!1138
2019-06-17 13:10:41 +00:00
akwizgran f0cea28aeb Don't show a message for the offline state. 2019-06-17 13:45:22 +01:00
Torsten Grote 32e8ea9888 Merge branch '1565-strings-duplicate-handshake-links' into 'master'
Add strings for duplicate pending contacts

See merge request briar/briar!1137
2019-06-17 12:29:22 +00:00
akwizgran 5a1caed89f Rename endpoints field. 2019-06-17 13:22:36 +01:00
akwizgran 22f5c42fc1 Resolve merge conflicts.
# Conflicts:
#   briar-android/src/main/res/values/strings.xml
2019-06-17 12:13:19 +00:00
akwizgran aab46040a5 Add comments for translators. 2019-06-17 13:12:11 +01:00
akwizgran 18fd238aa1 Merge branch '1580-strings-offline-state' into 'master'
Add string for pending contact offline state

See merge request briar/briar!1136
2019-06-17 11:12:50 +00:00
akwizgran 3a837b3c5a Resolve merge conflicts.
# Conflicts:
#   briar-android/src/main/res/values/strings.xml
2019-06-17 11:04:11 +00:00
akwizgran ac2597865c Merge branch '1587-version-negotiation' into 'master'
Add version negotiation to sync protocol

Closes #1587

See merge request briar/briar!1134
2019-06-17 10:54:39 +00:00
akwizgran 4a67cf3ce7 Don't cache default state when adding pending contact.
This can overwrite the initial state broadcast by the
rendezvous poller.
2019-06-17 10:22:08 +01:00
Torsten Grote a5041e651e Merge branch '1230-strings-adding-contact-slow' into 'master'
Add strings for warning when adding a contact is slow

See merge request briar/briar!1135
2019-06-15 13:37:13 +00:00
akwizgran b0e97d787f Add offline state for pending contacts. 2019-06-15 12:27:24 +01:00
akwizgran 0d8af780a3 Add strings for duplicate pending contacts. 2019-06-15 11:31:18 +01:00
akwizgran 9c20e6b333 Add string for pending contact offline state. 2019-06-15 11:04:22 +01:00
akwizgran ab14976c96 Add strings for warning when adding a contact is slow. 2019-06-15 11:01:09 +01:00
akwizgran ec3f821ba6 Update test expectations. 2019-06-13 17:17:50 +01:00
akwizgran 1d546da781 Store sync versions received from contacts. 2019-06-13 17:07:12 +01:00
akwizgran f2c951b70b Add DB methods for getting and setting sync versions. 2019-06-13 17:06:57 +01:00
akwizgran 1e259c100d Add sync versions column to contacts table. 2019-06-13 16:35:48 +01:00
akwizgran 3636aeba9a Use HyperSQL-compatible syntax in migration. 2019-06-13 16:34:20 +01:00
akwizgran 132e20a6ce Send versions record at start of each session. 2019-06-13 16:16:02 +01:00
akwizgran c228e5c219 Add versions record to sync protocol. 2019-06-13 16:16:02 +01:00
akwizgran ae1d1fc5a7 Add thread safety and null safety annotations. 2019-06-13 16:16:01 +01:00
Torsten Grote 37f02a40e9 Merge branch '1585-temporary-messages' into 'master'
Add support for temporary messages

See merge request briar/briar!1132
2019-06-12 15:39:02 +00:00
akwizgran 3c8b8c39e1 Turn commonly used variables into fields. 2019-06-12 16:29:24 +01:00
akwizgran 8f839e2c30 Remove temporary messages at startup. 2019-06-12 15:21:48 +01:00
akwizgran da4b63f20f Clean up ValidationManagerImplTest. 2019-06-12 15:17:13 +01:00
akwizgran cd40e771d2 Allow messages to be marked as temporary. 2019-06-12 15:11:10 +01:00
Torsten Grote dd7accfa95 Merge branch '1576-db-before-signing-in' into 'master'
Retry database tasks after signing in

Closes #1576

See merge request briar/briar!1131
2019-06-10 16:33:47 +00:00
akwizgran 1cf993484d Avoid unnecessary reloads. 2019-06-10 17:24:58 +01:00
akwizgran e810785fe2 Retry database tasks after signing in. 2019-06-10 15:51:20 +01:00
akwizgran 7ec826ccb7 Merge branch '1562-intent-router' into 'master'
Receive external intents through NavDrawerActivity

Closes #1562

See merge request briar/briar!1128
2019-06-10 14:20:06 +00:00
Torsten Grote 4a4abd7efa Merge branch '1232-polling-events' into 'master'
Show "connecting" state for pending contacts

See merge request briar/briar!1129
2019-06-10 13:11:06 +00:00
Torsten Grote dc2e42e1f2 [android] don't check getIntent() for null as it should be non-null now 2019-06-10 07:39:49 -03:00
Torsten Grote 1c4d277771 Don't route intents for MANAGE_NETWORK_USAGE settings
This is because we require a special permission to launch this intent
and we prefer requiring this permission to having the NavDrawerActivity
added to the back stack.

This commit also re-adds the deprecated USE_FINGERPRINT permission as
Android Studio would show an error otherwise.
2019-06-10 07:39:48 -03:00
Torsten Grote fb10ba5855 [android] Receive external intents through NavDrawerActivity
This ensures that our main activity is on the task stack below the
activity opened by an external intent. So when the user navigates back,
they always get back to the main activity.
2019-06-10 07:39:48 -03:00
Torsten Grote f31b85acdb Merge branch '1564-tor-rendezvous-crypto' into 'master'
Publish hidden service for connecting to pending contact

Closes #1564

See merge request briar/briar!1125
2019-06-09 14:24:40 +00:00
akwizgran 6519706599 Merge branch '1579-remove-pending-contacts-button' into 'master'
Show less obstrusive remove button for pending contacts

Closes #1579

See merge request briar/briar!1130
2019-06-08 09:44:35 +00:00
Torsten Grote 76741bc2ba [android] show less obstrusive remove button for pending contacts
This uses the same button as the RSS feed items
2019-06-07 11:09:34 -03:00
akwizgran 60eefbf3e0 Use named constants. 2019-06-07 11:54:44 +01:00
akwizgran a4a45efd43 Broadcast event when polling newly added contact. 2019-06-07 11:48:53 +01:00
akwizgran 208ae6a4b6 Show recently polled pending contacts as "connecting". 2019-06-07 11:42:48 +01:00
akwizgran fe1df6dafa Move pending contact events to rendezvous poller. 2019-06-07 11:42:48 +01:00
akwizgran 15d9ff1ebd Rename "connected" state to "connecting". 2019-06-07 11:42:10 +01:00
akwizgran dc741e988c Shorter description for "waiting for connection" state. 2019-06-07 11:42:10 +01:00
Torsten Grote 6665235768 Merge branch '1232-pending-contact-states' into 'master'
Add ContactManager support for pending contact states

See merge request briar/briar!1122
2019-06-06 21:31:43 +00:00
akwizgran ba19716e0f Don't broadcast disabled event whenever we close a socket. 2019-06-06 16:42:26 +01:00
akwizgran 41deff1bf3 Suppress redundant enabled/disabled events. 2019-06-06 16:42:26 +01:00
akwizgran 1ec3fa3ade Implement Tor rendezvous crypto. 2019-06-06 16:42:26 +01:00
akwizgran 64ae99bbce Handle corner cases such as removal during rendezvous. 2019-06-06 16:40:55 +01:00
akwizgran ed1cefa144 Use concurrent map for pending contact states. 2019-06-06 16:40:54 +01:00
akwizgran 23354d6568 Use predicates to match events. 2019-06-06 16:40:54 +01:00
akwizgran 1aa579a44f Add unit tests for pending contact state. 2019-06-06 16:40:54 +01:00
akwizgran 98191fb059 Add ContactManager support for pending contact states. 2019-06-06 16:40:54 +01:00
Torsten Grote b9283ea654 Merge branch '1232-rendezvous-poller-expiry' into 'master'
Use periodic poll task for expiry

See merge request briar/briar!1127
2019-06-06 15:12:08 +00:00
akwizgran 71b1f99b56 Use regular poll task for expiry. 2019-06-06 13:45:00 +01:00
Torsten Grote 2982a874d4 Merge branch '1232-rendezvous-poller-cleanup' into 'master'
Small cleanups for rendezvous poller

See merge request briar/briar!1126
2019-06-06 12:04:08 +00:00
akwizgran ea228164dc Check that poller instance isn't reused. 2019-06-06 12:11:31 +01:00
akwizgran 4b5ad9ace4 Make test expectations modular. 2019-06-06 12:11:31 +01:00
Torsten Grote a94ffd413c Merge branch '1232-transfer-pending-contact-alias' into 'master'
Transfer pending contact alias to contact

See merge request briar/briar!1124
2019-06-05 17:11:48 +00:00
Torsten Grote 1f921753fd Merge branch '1567-rendezvous-poller' into 'master'
Create poller for rendezvous connections

Closes #1567

See merge request briar/briar!1121
2019-06-05 17:08:31 +00:00
Torsten Grote 157b64e643 Merge branch 'pending-contacts-crash' into 'master'
Don't call setValue() on a background thread

See merge request briar/briar!1123
2019-06-05 16:57:04 +00:00
akwizgran 6f285c5b0a Transfer pending contact alias to contact. 2019-06-05 17:48:02 +01:00
akwizgran bf39c30d24 Don't call setValue() on a background thread. 2019-06-05 17:45:12 +01:00
akwizgran 7439e5579f Let plugins know if we're Alice or Bob. 2019-06-05 11:23:56 +01:00
akwizgran 4452dacc94 Make RendezvousCrypto package-private. 2019-06-05 11:01:28 +01:00
akwizgran 0579157010 Include protocol version in rendezvous key derivation. 2019-06-05 10:59:21 +01:00
akwizgran 3dbd0b80aa Make rendezvous constants package-private. 2019-06-05 10:58:12 +01:00
akwizgran 3863df3c1f Poll pending contact immediately when added. 2019-06-05 10:44:08 +01:00
akwizgran 08a5b8393f Add unit test for starting rendezvous poller. 2019-06-05 10:44:07 +01:00
akwizgran 92dea21c67 Run commit actions in unit tests. 2019-06-05 10:44:07 +01:00
akwizgran 82a52638cf Derive rendezvous key from static master key. 2019-06-05 10:44:07 +01:00
akwizgran a38113e862 Add rendezvous poller. 2019-06-05 10:44:07 +01:00
akwizgran 7fd8ad65be Make RendezvousEndpoint closeable. 2019-06-05 10:44:06 +01:00
akwizgran ce9c7cb32a Add requireNull() utility method. 2019-06-05 10:44:06 +01:00
akwizgran 5d2252ebda Add method for deriving rendezvous key. 2019-06-05 10:44:06 +01:00
akwizgran 3820d7413c Rename rendezvous handler to endpoint. 2019-06-05 10:44:06 +01:00
akwizgran ab90e1de04 Pass incoming connection handler to plugins. 2019-06-05 10:44:05 +01:00
Torsten Grote a650d812fa Merge branch '1571-connection-manager-pending-contacts' into 'master'
Add rendezvous connection support to connection manager

Closes #1571

See merge request briar/briar!1120
2019-06-04 14:08:05 +00:00
akwizgran c536782e01 Remove redundant use of IO executor. 2019-06-04 14:23:47 +01:00
akwizgran 9ffd1ec2c2 Unregister connection if sending stream header fails. 2019-06-04 14:20:57 +01:00
Torsten Grote 1c56068bf1 Merge branch '1232-handshake-manager' into 'master'
Implement handshake protocol

See merge request briar/briar!1118
2019-06-04 11:49:11 +00:00
Torsten Grote d2290e2037 Merge branch '1560-forum-sharing-integration-test' into 'master'
Fix race conditions in ForumSharingIntegrationTest

Closes #1560

See merge request briar/briar!1119
2019-06-04 11:47:49 +00:00
akwizgran 0951508af7 Define PROOF_BYTES as MAC_BYTES. 2019-06-04 12:38:21 +01:00
akwizgran 34a5b69100 Reuse TransportCrypto#isAlice(). 2019-06-04 12:21:17 +01:00
akwizgran d939fe80bd Explicitly check length of proof of ownership. 2019-06-04 12:17:10 +01:00
akwizgran 4ea8a4732c Fix race conditions in ForumSharingIntegrationTest. 2019-06-04 11:57:39 +01:00
Torsten Grote da67cae4ce Merge branch 'test-sync-at-higher-level' into 'master'
Test sync at a higher level

See merge request briar/briar!1116
2019-06-04 10:37:31 +00:00
akwizgran d3c7ecdef4 Use static comparison method. 2019-06-03 18:02:19 +01:00
akwizgran 4d8e0baeb4 Rewrap a line. 2019-06-03 17:58:31 +01:00
akwizgran 0b764a01dd Use larger buffer in test connections to prevent deadlock. 2019-06-03 17:55:35 +01:00
akwizgran f95bb9b28e Add integration test for new connection manager methods. 2019-06-03 17:55:35 +01:00
akwizgran 8f21e07840 Add rendezvous connection support to connection manager. 2019-06-03 17:52:43 +01:00
akwizgran eed8d25120 Decouple HandshakeManager from ContactExchangeManager. 2019-06-03 17:44:38 +01:00
Torsten Grote 265a43f5ff Merge branch 'use-real-executors-in-integration-tests' into 'master'
Use BrambleCoreModule in integration tests

See merge request briar/briar!1115
2019-06-03 14:48:53 +00:00
akwizgran 89cbdc824c Add integration test for handshaking with pending contact. 2019-06-03 15:36:28 +01:00
akwizgran 4640651714 Add integration test for converting pending contacts. 2019-06-03 15:36:27 +01:00
akwizgran af8b7f1130 Implement getHandshakeLink(). 2019-06-03 15:36:27 +01:00
akwizgran 643270e247 Add integration test for ContactExchangeManager. 2019-06-03 15:36:24 +01:00
akwizgran 24f1b7eeca Implement handshake manager. 2019-06-03 15:35:53 +01:00
akwizgran 60155f146a Add contact exchange method for pending contacts. 2019-06-03 15:35:53 +01:00
akwizgran 7c3f2c0bed Add test implementation of DuplexTransportConnection. 2019-06-03 15:35:00 +01:00
akwizgran 85a1fd2caa Convert BriarIntegrationTest to use test reader and writer. 2019-06-03 15:34:59 +01:00
akwizgran f8d240a320 Test stream reading and writing at a higher level. 2019-06-03 15:34:59 +01:00
akwizgran 5860c723de Remove unused test module. 2019-06-03 15:34:59 +01:00
akwizgran 33d35148d8 Run briar-headless tests when running all tests. 2019-06-03 15:34:17 +01:00
akwizgran 0e55b06c0a Provide SOCKS module for headless app, remove reporting. 2019-06-03 15:34:17 +01:00
akwizgran d964f06de1 Use default methods for easier maintenance. 2019-06-03 15:34:16 +01:00
akwizgran 100e17b242 Use BrambleCoreModule in integration tests. 2019-06-03 15:34:16 +01:00
akwizgran 7bf86d9c53 Use real executors in integration tests. 2019-06-03 15:34:16 +01:00
Torsten Grote 8fc5c21354 Merge branch '1570-derive-handshake-root-key' into 'master'
Add contact manager and key manager methods for converting a pending contact

Closes #1570

See merge request briar/briar!1114
2019-06-03 14:33:21 +00:00
akwizgran fe83a59d2a Add comment about tag reuse. 2019-06-03 12:48:14 +01:00
akwizgran 1b8692a216 Add longer explanation of 'verified' flag. 2019-06-03 12:40:49 +01:00
akwizgran 57a70f411b Update ContactManager javadocs. 2019-05-31 11:59:00 +01:00
akwizgran b2d2b1765a Fix pending contact flag. Hooray for unit tests. 2019-05-30 17:37:09 +01:00
akwizgran 430b530ca5 Derive handshake root key when converting pending contact. 2019-05-30 17:27:07 +01:00
akwizgran 4a2936c685 Optionally include handshake public key for new contact. 2019-05-30 16:36:25 +01:00
Torsten Grote d3c7c54797 Merge branch '1561-wait-for-delivery-in-integration-test' into 'master'
Wait for message delivery in integration test

Closes #1561

See merge request briar/briar!1113
2019-05-30 15:25:08 +00:00
akwizgran 83dc52572d Remove keys when pending contacts are removed. 2019-05-30 16:20:57 +01:00
akwizgran 810d45d6b9 Derive handshake root key when adding a pending contact. 2019-05-30 15:48:26 +01:00
akwizgran 9b4f60088f Add methods for deriving static master and root keys. 2019-05-30 14:31:12 +01:00
akwizgran b222107044 Add static method for comparing byte arrays. 2019-05-30 14:30:16 +01:00
akwizgran d0495b7c00 Wait for transport properties as well as client versions. 2019-05-30 13:55:16 +01:00
akwizgran ee874947d0 Wait for message delivery in integration test. 2019-05-30 11:51:16 +01:00
akwizgran d38176faea Merge branch '1571-connection-manager-cleanup' into 'master'
Clean up connection manager, ready for pending contacts

See merge request briar/briar!1109
2019-05-29 15:16:35 +00:00
Torsten Grote 2a00f94e23 Merge branch '1571-connection-registry-pending-contacts' into 'master'
Add support for pending contacts to connection registry

See merge request briar/briar!1111
2019-05-28 14:36:42 +00:00
akwizgran 8bd4278ae5 Add support for pending contacts to connection registry. 2019-05-28 14:33:03 +01:00
akwizgran 829a6df567 Remove redundant assignment. 2019-05-28 14:15:47 +01:00
akwizgran aa0c3118a0 Interrupt outgoing session on read error. 2019-05-28 10:45:55 +01:00
Torsten Grote 015f5005d0 Merge branch '1232-get-pending-contact' into 'master'
Add method to get a pending contact

See merge request briar/briar!1110
2019-05-27 17:51:59 +00:00
Torsten Grote 91c5ec6f18 Merge branch '1232-triple-dh' into 'master'
Implement triple Diffie-Hellman key agreement

See merge request briar/briar!1108
2019-05-27 17:49:05 +00:00
Torsten Grote cd9cc375ff Merge branch '1570-convert-pending-contact' into 'master'
Add database methods for converting a pending contact

Closes #1570

See merge request briar/briar!1107
2019-05-27 17:45:26 +00:00
akwizgran 819deca93c Update javadoc. 2019-05-27 17:54:23 +01:00
akwizgran 79632908d4 Add method to get a pending contact. 2019-05-27 17:44:57 +01:00
akwizgran f979d44c96 Update REST API docs. 2019-05-27 17:43:23 +01:00
akwizgran 44d2526997 Add triple Diffie-Hellman key agreement. 2019-05-27 15:03:58 +01:00
akwizgran 14e604e21e Add 'verified' flag to ContactAddedEvent. 2019-05-27 11:40:28 +01:00
akwizgran 677728b9ae Add database methods for converting a pending contact. 2019-05-27 11:19:21 +01:00
akwizgran 84060a57da Merge branch 'unsupported-handshake-link' into 'master'
Add error message for unsupported handshake link version

See merge request briar/briar!1091
2019-05-26 14:36:24 +00:00
Torsten Grote 4a92625a7b Merge branch 'contact-exchange-refactoring' into 'master'
Contact exchange refactoring

See merge request briar/briar!1106
2019-05-24 17:33:21 +00:00
Torsten Grote bea526d64d [android] tweak wording for unsupported link version 2019-05-24 14:31:04 -03:00
akwizgran 717b2d176e Clean up connection manager, ready for pending contacts. 2019-05-24 18:08:06 +01:00
Torsten Grote cff5e53d09 Merge branch 'record-reader-predicates' into 'master'
Use predicates to specify records to accept or ignore

See merge request briar/briar!1105
2019-05-24 16:16:24 +00:00
akwizgran 221687c9d7 Merge branch 'startup-fix' into 'master'
Show OpenDatabaseFragment right after signing in

See merge request briar/briar!1099
2019-05-24 15:06:41 +00:00
akwizgran 953fccba16 Update PendingContactListener to use PendingContactItem. 2019-05-24 15:57:24 +01:00
akwizgran eca82e2888 Merge branch '1554-remove-pending-contacts' into 'master'
Allow pending contacts to be removed at any time

Closes #1554

See merge request briar/briar!1098
2019-05-24 14:49:48 +00:00
Torsten Grote ad93100e99 Merge branch '35-transaction-manager' into 'master'
Extract TransactionManager from DatabaseComponent

See merge request briar/briar!1104
2019-05-24 13:20:35 +00:00
akwizgran d80c77f466 Try to close connection if contact exchange fails. 2019-05-24 13:14:53 +01:00
akwizgran a6376af7c2 Extract TransactionManager from DatabaseComponent. 2019-05-24 12:44:23 +01:00
akwizgran f1e5c2dd66 Return a contact, encapsulate contact exchange crypto. 2019-05-24 11:42:30 +01:00
akwizgran 5be0e928c4 Replace events with return value and exceptions. 2019-05-24 10:53:43 +01:00
akwizgran bcc899eebf Attach information to ContactExistsException. 2019-05-24 10:53:43 +01:00
akwizgran 9ea91cbb3e Move background work into view model. 2019-05-24 10:51:38 +01:00
akwizgran da54712ae1 Refactor ContactExchangeTask into reusable manager. 2019-05-24 10:51:38 +01:00
akwizgran f459115b19 Run contact exchange task on IO executor. 2019-05-24 10:51:38 +01:00
akwizgran cc49648e37 Use predicates to specify records to accept or ignore. 2019-05-24 10:51:27 +01:00
Torsten Grote 9ce71088e2 Merge branch '1564-rendezvous-plugin-api' into 'master'
Add rendezvous API to transport plugins

See merge request briar/briar!1103
2019-05-22 16:58:31 +00:00
Torsten Grote 0f3e6d9736 Merge branch '1567-remove-pending-contact-state-from-db' into 'master'
Remove pending contact state from DB

See merge request briar/briar!1102
2019-05-22 16:56:59 +00:00
akwizgran de97cce119 Address review comments. 2019-05-22 17:46:17 +01:00
akwizgran a82d20564a Update names in RendezvousModule. 2019-05-22 16:13:49 +01:00
akwizgran 967f068637 Add initial API for rendezvous plugins. 2019-05-22 15:26:28 +01:00
akwizgran 90c33133c3 Code cleanup. 2019-05-22 15:22:35 +01:00
akwizgran 01ef367864 Remove pending contact state from the database. 2019-05-22 11:25:05 +01:00
Torsten Grote da5d442c91 Merge branch '1232-poller-refactoring' into 'master'
Pass a connection handler to plugins when polling

See merge request briar/briar!1101
2019-05-21 13:33:53 +00:00
akwizgran ead7570ec5 Add javadoc. 2019-05-21 14:27:27 +01:00
akwizgran 43b2f9da1c Static import. 2019-05-17 15:46:37 +01:00
akwizgran 668433dd62 Pass a connection handler to plugins when polling. 2019-05-17 14:07:54 +01:00
akwizgran a0772852de Decouple poller from plugin manager. 2019-05-17 13:59:30 +01:00
Torsten Grote f0bd18c4d6 [android] show OpenDatabaseFragment right after signing in 2019-05-16 15:22:56 -03:00
akwizgran 99000d8eab Merge branch 'repro-check-on-success' into 'master'
Only check reproducibility when normal tests pass

See merge request briar/briar!1100
2019-05-16 16:58:33 +00:00
Torsten Grote 0b48afb692 Only check reproducibility when normal tests pass 2019-05-16 13:48:25 -03:00
Torsten Grote 299ad07222 [android] Allow pending contacts to be removed at any time 2019-05-16 12:54:42 -03:00
akwizgran 37d0b61d7b Bump version numbers for 1.1.7 release. 2019-05-16 16:07:15 +01:00
akwizgran 98a1ec89d7 Update translations. 2019-05-16 16:06:29 +01:00
akwizgran a61860af85 Merge branch '1369-thread-layout' into 'master'
Adapt private group join notices to new threaded layout

Closes #1369

See merge request briar/briar!1097
2019-05-16 14:54:46 +00:00
Torsten Grote 90437f4fa4 [android] use same color for thread dividers than indentation dividers 2019-05-16 11:35:20 -03:00
Torsten Grote 06212453b2 [android] Adapt private group join notices to new threaded layout 2019-05-16 11:12:48 -03:00
akwizgran ddc9b5b066 Merge branch '1256-adding-contacts-headless' into 'master'
Add a REST endpoint for adding contacts

Closes #1256

See merge request briar/briar!1094
2019-05-16 14:05:48 +00:00
Torsten Grote 0aa6166afa Merge branch 'account-logging' into 'master'
Log contents of account directory for debugging

See merge request briar/briar!1096
2019-05-16 11:51:46 +00:00
akwizgran 60b91bc317 Log contents of account directory for debugging. 2019-05-16 10:06:16 +01:00
akwizgran 20481a3790 Merge branch '1369-thread-layout' into 'master'
Move AuthorView up in threaded conversation

Closes #1369

See merge request briar/briar!1095
2019-05-16 08:46:39 +00:00
Torsten Grote 576934910e Merge branch '1566-equivalent-public-keys' into 'master'
Add tests for equivalent handshake public keys

See merge request briar/briar!1093
2019-05-15 20:02:52 +00:00
Torsten Grote 4abc26093e Merge branch '1556-key-manager-methods-for-pending-contacts' into 'master'
Add key manager methods for pending contacts

Closes #1556

See merge request briar/briar!1089
2019-05-15 19:57:32 +00:00
Torsten Grote aed63746e7 [android] Move AuthorView up in threaded conversation 2019-05-15 16:33:06 -03:00
Torsten Grote 816598b631 [headless] only include alias in contact's JSON representation if it exists 2019-05-15 16:03:02 -03:00
Torsten Grote c062c16d27 Merge branch 'merge-handshake-and-transport-keys' into 'master'
Add support for handshake keys to KeyManager

See merge request briar/briar!1088
2019-05-15 16:27:33 +00:00
Torsten Grote 435b43488a [headless] address review comments for remote contact adding 2019-05-15 12:36:33 -03:00
Torsten Grote faa6a85148 [headless] Add tests to ensure that remote contact adding needs auth token 2019-05-15 11:28:01 -03:00
Torsten Grote 3770a9f217 [headless] make events related to adding contacts available via websocket 2019-05-15 11:28:01 -03:00
Torsten Grote c6211be488 [bramble-core] Broadcast events when pending contacts are added or removed 2019-05-15 11:27:59 -03:00
Torsten Grote 5a73e50248 [headless] expose ContactManager methods for adding contacts remotely 2019-05-15 11:26:21 -03:00
Torsten Grote dc6971734a [briar-core] Add a getRealHandshakeLink() method to BriarTestUtils
Also allow testOutput from briar-core to be used in briar-headless
2019-05-15 11:26:20 -03:00
Torsten Grote 69e57bee61 [bramble] Let TestUtils return a PendingContact with random state 2019-05-15 11:26:19 -03:00
Torsten Grote af8cabbb28 [headless] update dependencies 2019-05-15 11:25:11 -03:00
akwizgran 6f31a3c2ad Merge branch 'key-pair-refactoring' into 'master'
Key pair refactoring

See merge request briar/briar!1083
2019-05-15 14:19:48 +00:00
akwizgran d3469e3782 Merge branch '1482-startup-activity' into 'master'
Combine Password and OpenDatabase Activity into StartupActivity

Closes #1482

See merge request briar/briar!1087
2019-05-15 09:57:01 +00:00
akwizgran 9d64b186ff Add tests for hashing public keys into shared secret. 2019-05-15 10:18:13 +01:00
akwizgran ca591b5c7b Add test for equivalent public keys. 2019-05-15 10:18:09 +01:00
akwizgran 2c4188caf5 Use lambdas for tasks requiring a manager lookup. 2019-05-14 17:59:35 +01:00
akwizgran 0b30a0786e Rename key manager methods for clarity. 2019-05-14 17:59:35 +01:00
akwizgran f9b928c12a Annotate equals() argument as nullable. 2019-05-14 17:59:35 +01:00
akwizgran afa0b96293 Add utility method for null checks. 2019-05-14 17:59:34 +01:00
akwizgran dd50f4bcd4 Add key manager methods for pending contacts. 2019-05-14 17:59:34 +01:00
akwizgran f42fc5213e Add key manager method for contacts with handshake keys. 2019-05-14 17:59:34 +01:00
akwizgran 84e2402404 Update key management terminology. 2019-05-14 17:57:23 +01:00
akwizgran 5adc9d8dbd Add handshake keys to TransportKeyManagerImpl. 2019-05-14 17:57:22 +01:00
akwizgran 3f51ad6c07 Add handshake mode to MutableTransportKeys. 2019-05-14 17:57:22 +01:00
akwizgran 1fd6d7a6d5 Use @GuardedBy annotation. 2019-05-14 17:57:22 +01:00
akwizgran 7dc4dc566f Merge handshake and transport keys. 2019-05-14 17:57:19 +01:00
akwizgran 658c63d94e Rename an argument for clarity. 2019-05-14 17:56:19 +01:00
akwizgran ee05c32871 Allow pending contact state update not to affect any rows. 2019-05-14 17:55:38 +01:00
akwizgran d2951eb3cd Rename key parser classes. 2019-05-14 17:26:28 +01:00
akwizgran de8a60ea21 Use PublicKey and PrivateKey everywhere. 2019-05-14 17:26:26 +01:00
akwizgran 0e77a47cc1 Refactor key handling to use public classes. 2019-05-14 17:24:19 +01:00
Torsten Grote 421ca309c7 Merge branch '1538-create-handshake-key-pair' into 'master'
Generate and store handshake key pair at startup if necessary

Closes #1538

See merge request briar/briar!1082
2019-05-14 15:39:44 +00:00
akwizgran 43787deafd Address review comments. 2019-05-14 15:55:42 +01:00
Torsten Grote 19ec98b607 [android] use exception instead of string resource in LiveResult 2019-05-13 13:21:58 -03:00
Torsten Grote ec7fdb3f72 [android] Pass the entire link to the backend, so newer version have a chance to arrive 2019-05-13 12:00:18 -03:00
Torsten Grote be8aba347d [android] Add error message for unsupported handshake link version 2019-05-13 12:00:18 -03:00
Torsten Grote 22ebdd8e42 [android] Ensure keyboard is shown for entering password
in new StartupActivity and when creating a new account.
2019-05-13 11:58:07 -03:00
Torsten Grote e37ee7ee04 [android] Use LiveEvent to communicate password validation and account deletion 2019-05-13 08:21:28 -03:00
Torsten Grote 5676e18a22 [android] StartupActivity: Address first round of review comments 2019-05-13 08:21:28 -03:00
Torsten Grote 5ece6505da [android] Combine Password and OpenDatabase Activity into StartupActivity 2019-05-13 08:21:27 -03:00
Torsten Grote 451edba467 Merge branch 'live-event-reduce-visibility' into 'master'
Reduce visibility of LiveEvent inner classes

See merge request briar/briar!1092
2019-05-10 16:52:49 +00:00
Torsten Grote 5880479987 Merge branch '1537-contact-manager-pending-contacts' into 'master'
Implement contact manager methods for pending contacts

Closes #1537

See merge request briar/briar!1081
2019-05-10 15:06:08 +00:00
akwizgran 71d8fb2083 Add unit tests for Base32 encoding and decoding. 2019-05-10 15:33:19 +01:00
akwizgran 0825e77dd7 Static import. 2019-05-10 15:11:44 +01:00
akwizgran 593a709a7f Remove redundant regex. 2019-05-10 15:06:12 +01:00
akwizgran 322fefb2a2 Use matcher to discard prefix if present. 2019-05-10 15:02:47 +01:00
akwizgran 8005cdc659 Reduce visibility of LiveEvent inner classes. 2019-05-10 10:20:49 +01:00
akwizgran 33fdca4aa1 Merge branch 'live-event' into 'master'
Migrate existing uses of event-like LiveData to LiveEvent

See merge request briar/briar!1090
2019-05-10 09:09:33 +00:00
akwizgran e5fc91b620 Rename exceptions and events. 2019-05-10 10:02:49 +01:00
akwizgran 9c08073e49 Rename account to identity. 2019-05-10 10:02:49 +01:00
akwizgran 5553b7d0e4 Remove unused method. 2019-05-10 10:02:48 +01:00
akwizgran 2cce0f5fe2 Remove OpenDatabaseHook priorities. 2019-05-10 10:02:48 +01:00
akwizgran ebae1037be Remove unnecessary null check. 2019-05-10 10:02:48 +01:00
akwizgran 0c99ef0e5b Clean up some duplicated code. 2019-05-10 10:02:48 +01:00
akwizgran faba9a6b70 Generate handshake keys on demand, store when DB is opened. 2019-05-10 10:02:47 +01:00
akwizgran 891c82b2e5 Add javadocs to DB hook interfaces. 2019-05-10 10:02:47 +01:00
akwizgran 56fbc93962 Move handshake keys from LocalAuthor to Account. 2019-05-10 10:02:47 +01:00
akwizgran 251eb9e712 Add javadoc for handshakeKeys flag. 2019-05-10 10:02:47 +01:00
akwizgran 8b2b7599f9 Generate and store handshake keys at startup if needed. 2019-05-10 10:02:46 +01:00
akwizgran 8c315382e2 Add DB method for setting local handshake key pair. 2019-05-10 10:02:46 +01:00
akwizgran 8183a48ebb Add unit test for OpenDatabaseHook priority. 2019-05-10 10:02:45 +01:00
akwizgran f6611daf7b Replace Client interface with OpenDatabaseHook. 2019-05-10 10:02:45 +01:00
akwizgran 00bc8ac768 Include handshake keys when loading all local authors. 2019-05-10 10:02:45 +01:00
akwizgran 75776eb7de Generate handshake keys when creating local author. 2019-05-10 10:02:45 +01:00
akwizgran f0a3130bf3 Test that UnsupportedVersionException is thrown. 2019-05-10 10:01:32 +01:00
akwizgran 64aa121c9c Reuse UnsupportedVersionException for handshake links. 2019-05-10 10:01:22 +01:00
akwizgran cc3486df94 Move UnsupportedVersionException to bramble.api package. 2019-05-10 10:01:06 +01:00
akwizgran cd24be7e42 Add unit tests for pending contact factory. 2019-05-10 10:01:05 +01:00
akwizgran fa562b40bc Implement contact manager methods for pending contacts. 2019-05-10 10:01:03 +01:00
akwizgran fc8ca872a8 Add base32 encoder/decoder. 2019-05-10 09:59:16 +01:00
Torsten Grote 5b63eab314 [android] migrate existing uses of event-like LiveData to LiveEvent 2019-05-09 14:47:16 -03:00
akwizgran 6f0ab8b688 Merge branch '1234-remote-contacts' into 'master'
Implement UX for adding contacts remotely

Closes #1234

See merge request briar/briar!1035
2019-05-09 16:52:24 +00:00
Torsten Grote dfc567cbfd [bramble] Remove PendingContact test code from ContactManagerImpl 2019-05-09 13:36:21 -03:00
Torsten Grote de98a4cb12 [android] Introduce a (Mutable)LiveEvent for single-use LiveData 2019-05-09 13:20:09 -03:00
Torsten Grote fbe375cc4e Use event instead of CommitAction to handle removed PendingContacts 2019-05-09 11:43:22 -03:00
Torsten Grote 19bc73ac61 [android] show Toast when user shares own handshake link
This also limits the AddContactActivity to run within one single task
2019-05-03 11:47:51 -03:00
Torsten Grote d17331b578 [android] Set handshake link when received via sharing intent or link click 2019-05-03 10:18:47 -03:00
Torsten Grote bec1f117ba Remote Contact Adding: Rename methods and add more exception handling 2019-05-03 09:48:20 -03:00
Torsten Grote 2c014b4e46 Only remove PendingContact from UI when removed from DB 2019-05-03 09:48:19 -03:00
Torsten Grote 7a71d2bad4 Remote Contact Adding UI: Address review comments 2019-05-03 09:48:19 -03:00
Torsten Grote 4bf21b2f3b [android] hide feature to add contacts remotely behind feature flag 2019-05-03 09:48:19 -03:00
Torsten Grote 4a57939b80 [android] finalize list of pending contacts and add test code 2019-05-03 09:48:19 -03:00
Torsten Grote 66cdf4f595 Refactored IntroductionSucceededEvent into more generic ContactAddedRemotelyEvent 2019-05-03 09:48:18 -03:00
Torsten Grote 3384477499 [android] Add BriarSnackbarBuilder to standardize snackbar creation 2019-05-03 09:48:18 -03:00
Torsten Grote 58ffc6e761 [android] rough sketch of UI for adding contacts remotely 2019-05-03 09:48:15 -03:00
akwizgran df5ac59fc9 Merge branch 'gradle-android-3.4' into 'master'
Update the Android gradle plugin to version 3.4.0

See merge request briar/briar!1085
2019-05-03 09:36:46 +00:00
akwizgran dc649b195a Merge branch '1552-send-controller-exception' into 'master'
Don't disable TextInputView directly, use controller

Closes #1552

See merge request briar/briar!1086
2019-05-01 09:38:34 +00:00
Torsten Grote 3d9a8f9bf8 [android] Use TextSendController to disable TextInputView
Fixes #1552
2019-04-26 13:45:49 -03:00
Torsten Grote 96975e0d43 Upgrade dagger, mockito and okhttp 2019-04-26 09:07:26 -03:00
Torsten Grote 6691e708e4 Update the Android gradle plugin to version 3.4.0 2019-04-25 20:55:30 -03:00
Torsten Grote 421c9c44d6 Merge branch 'bump-schema-version' into 'master'
Bump schema version to match migrations

See merge request briar/briar!1084
2019-04-23 14:41:18 +00:00
akwizgran 29d3ee2439 Bump schema version to match migrations. 2019-04-23 15:31:30 +01:00
akwizgran 06d4f85768 Merge branch 'add-handshake-key-pairs-to-db' into 'master'
Add handshake key pairs to DB, remove inactive contacts

Closes #1276

See merge request briar/briar!1080
2019-04-23 12:31:59 +00:00
Torsten Grote 9685462242 Merge branch 'static-transport-keys' into 'master'
Add database support for pending contacts and handshake keys

See merge request briar/briar!1078
2019-04-22 14:00:52 +00:00
akwizgran 84f2c29c76 Remove unnecessary call to replaceTypes(). 2019-04-22 14:43:47 +01:00
akwizgran 9c8125d77a Rename 'alice' flags to clarify usage, add comments. 2019-04-19 11:57:55 +01:00
akwizgran 1a1a010ee7 Update key derivation labels for handshake mode. 2019-04-19 11:36:21 +01:00
akwizgran 56fb20f257 Small code cleanups. 2019-04-18 13:47:31 +01:00
akwizgran f82294527f Fix column index in getLocalAuthor(). 2019-04-18 13:35:42 +01:00
akwizgran 456f25b701 Revert unintended change to javadoc. 2019-04-18 13:31:00 +01:00
akwizgran 0587fdc54c Add handshake key pairs to DB, remove inactive contacts. 2019-04-18 13:15:25 +01:00
akwizgran ece083026e Merge branch '1534-rss-notification' into 'master'
Make RSS blog posts not local: re-enables notification

Closes #1534

See merge request briar/briar!1079
2019-04-18 08:01:16 +00:00
Torsten Grote 0e5bb3e9de [core] RSS blog posts are not local: re-enables notification 2019-04-17 20:32:09 -03:00
akwizgran dcebd5a81c Update terminology from static keys to handshake keys. 2019-04-17 17:28:22 +01:00
akwizgran e9a3685bfd Fix spurious line wrapping. 2019-04-17 17:22:49 +01:00
akwizgran 3aadcc17dd Add public key to pending contacts. 2019-04-17 15:30:15 +01:00
akwizgran 296ce080e2 Add unit tests for pending contact exception. 2019-04-17 15:14:53 +01:00
akwizgran 724e6643bd Add DB methods for handshake keys and pending contacts. 2019-04-17 15:07:58 +01:00
akwizgran fafd0c7ff9 Rename static transport keys to handshake keys. 2019-04-17 14:52:52 +01:00
akwizgran e91a7c64d8 Add unit tests for DB pending contact methods. 2019-04-17 13:06:41 +01:00
akwizgran f08e3a58e6 Add database methods for pending contacts. 2019-04-17 12:44:43 +01:00
akwizgran 94de1834b8 Add unit tests for DB static key methods. 2019-04-17 12:06:47 +01:00
akwizgran 6b24eeb84c Add method to set reordering window for static keys. 2019-04-17 09:58:36 +01:00
akwizgran f72ff9f812 Add database methods for static keys. 2019-04-16 17:51:31 +01:00
akwizgran 0f5f440f1c Add key set and key set ID classes for static keys. 2019-04-16 16:59:07 +01:00
akwizgran 7acbe56197 Add abstract superclass for transport keys. 2019-04-16 16:34:27 +01:00
akwizgran fccf735a89 Add unit tests for static key derivation. 2019-04-16 16:34:27 +01:00
akwizgran d5ac2c9ead Fix master secret/master key/root key terminology.
In the key agreement, contact exchange and introduction protocols we
refer to the master key. In the transport protocol we refer to the root
key. When adding a contact in person, the key agreement protocol's
master key is used as the transport root key. When a contact is
introduced, the introduction protocol's master key is used as the
transport root key.
2019-04-16 16:34:26 +01:00
akwizgran d4b929fc6c Add key derivation for static keys. 2019-04-16 16:34:26 +01:00
akwizgran b568405f59 Create DB tables for static keys. 2019-04-16 16:34:19 +01:00
Torsten Grote ff2f710495 Merge branch 'crypto-api-code-cleanup' into 'master'
Minor code cleanups for crypto API

See merge request briar/briar!1076
2019-04-06 14:20:26 +00:00
Torsten Grote d00094edab Merge branch '1504-nokia-wake-lock' into 'master'
Use an appropriate wake lock tag for the device

Closes #1504

See merge request briar/briar!1077
2019-04-06 14:18:17 +00:00
akwizgran 9ca854473f Use an appropriate wake lock tag for the device. 2019-04-06 10:38:27 +01:00
Torsten Grote 8603fd3257 Merge branch 'inject-dialog-fragments-early' into 'master'
Inject remaining fragments in onAttach()

See merge request briar/briar!1075
2019-04-05 16:43:27 +00:00
Torsten Grote 648fc6e65c Merge branch 'async-events-refactoring' into 'master'
Refactor UI event listeners

See merge request briar/briar!1074
2019-04-05 16:41:19 +00:00
akwizgran 0c65e97fcf Inject remaining fragments in onAttach(). 2019-04-05 16:57:11 +01:00
akwizgran 16d2154c73 Add a couple of code cleanups. 2019-04-05 16:49:46 +01:00
akwizgran b8e390db21 Refactor UI event listeners. 2019-04-05 16:36:54 +01:00
Torsten Grote b2702062bc Merge branch 'async-events-commit-actions' into 'master'
Allow actions to be attached to transactions

See merge request briar/briar!1073
2019-04-05 15:12:36 +00:00
akwizgran f11b32f188 Add unit test for commit actions. 2019-04-05 16:02:37 +01:00
akwizgran d603607a90 Allow event executor tasks to be attached to transactions. 2019-04-05 15:57:20 +01:00
Torsten Grote 6c0dffff56 Merge branch 'db-code-cleanup' into 'master'
Clean up some database code

See merge request briar/briar!1071
2019-04-05 14:38:54 +00:00
Torsten Grote 9f3394aa1d Merge branch 'async-events' into 'master'
Broadcast events asynchronously

See merge request briar/briar!1072
2019-04-05 14:29:35 +00:00
akwizgran 74710664e3 Reduce scope of @SuppressWarnings. 2019-04-05 15:21:46 +01:00
akwizgran 0d0197fd2d Construct EventBusImpl by injection. 2019-04-05 15:19:31 +01:00
akwizgran c3b5b04b71 Broadcast events asynchronously. 2019-04-05 15:00:49 +01:00
akwizgran 8b3164e107 Merge branch '1529-request-buttons' into 'master'
Ensure that conversation request buttons always work

Closes #1529

See merge request briar/briar!1070
2019-04-05 12:55:26 +00:00
Torsten Grote 79ff5aa148 [android] ensure that conversation request buttons always work 2019-04-05 09:38:08 -03:00
akwizgran 652ce4a53d Merge branch '1514-introduction-message' into 'master'
Fix Introduction Issues

Closes #1516 and #1514

See merge request briar/briar!1067
2019-04-04 16:47:09 +00:00
akwizgran df0d6594b6 Merge branch '1522-contact-alias-length' into 'master'
Check contact alias for maximum length in UI

Closes #1522

See merge request briar/briar!1069
2019-04-03 10:17:54 +00:00
Torsten Grote f73ecc6066 [android] Check contact alias for maximum length before proceeding 2019-04-02 15:06:32 -03:00
akwizgran 0f614e8460 Merge branch '1492-send-after-previews-loaded' into 'master'
Show progress bar while image previews are loading

Closes #1510, #1509, and #1492

See merge request briar/briar!1033
2019-04-01 10:27:38 +00:00
Torsten Grote f4bdd201a3 [android] fix bug where onboarding is shown again when activity resumes 2019-03-28 08:45:43 -03:00
Torsten Grote 5130c83556 [android] Show progress bar while image previews are loading
This refactors the send buttons out into their own composite view
2019-03-28 08:45:43 -03:00
Torsten Grote 423ecc003b [android] Get notified when all image previews have been loaded
Also fix crash when attaching image fails
2019-03-28 08:45:43 -03:00
Torsten Grote 419f37a4a9 Merge branch '1517-scroll-listener-npe' into 'master'
Don't try to get item at NO_POSITION

Closes #1517

See merge request briar/briar!1068
2019-03-28 11:30:42 +00:00
akwizgran 3d94ffb714 Don't try to get item at NO_POSITION. 2019-03-28 11:06:13 +00:00
Torsten Grote d40cfd30a2 Let IntroductionResponse know if introduction can succeed
and use this information in the android UI for showing that the user
needs to wait or not.
2019-03-26 16:18:25 -03:00
Torsten Grote 3b4a92f66c Fix introduction after one was declined
When we received a remote decline we always went into the REMOTE_DECLINED state
while there's two cases where we need to go into the START state instead.
So when the new request arrived, we weren't in START and thus aborted the protocol.
This commit fixes this.

Fixes #1516
2019-03-26 16:18:25 -03:00
Torsten Grote f9dfbe3fa5 Don't show remote introduction responses after declining locally
Fixes #1514
2019-03-26 16:18:11 -03:00
Torsten Grote bc8bb08853 Merge branch '1488-do-not-witness-aapt' into 'master'
Exclude AAPT dependency from gradle-witness

See merge request briar/briar!1066
2019-03-26 17:19:40 +00:00
akwizgran cc67a8fcdd Exclude AAPT dependency from gradle-witness. 2019-03-26 17:06:46 +00:00
akwizgran f8cf88e6cd Merge branch '1421-contact-list-during-migration' into 'master'
Don't start BriarActivities when lifecycle did not start

Closes #1421

See merge request briar/briar!1058
2019-03-26 14:25:10 +00:00
akwizgran bc58c47a22 Merge branch 're-add-objective-c-code-style' into 'master'
Revert "Remove Objective C from code styles"

See merge request briar/briar!1065
2019-03-26 14:23:50 +00:00
Torsten Grote aa6879c48e Revert "Remove Objective C from code styles"
This reverts commit a20e868970.
2019-03-22 15:18:02 -03:00
akwizgran 4d26628f2a Bump version numbers for 1.1.6 release. 2019-03-22 16:56:56 +00:00
akwizgran abaa70da99 Merge branch '1501-new-contacts-at-top' into 'master'
Display new contacts at the top of the contact list

Closes #1501

See merge request briar/briar!1063
2019-03-22 16:53:52 +00:00
Torsten Grote 6435c3520c [android] Update translations, add Azerbaijani 2019-03-22 13:09:38 -03:00
akwizgran b5c4c7ae61 Merge branch '1077-save-threaded-discussion-position' into 'master'
Save list position in threaded conversations and main blog feed

Closes #1077

See merge request briar/briar!1054
2019-03-22 15:42:53 +00:00
Torsten Grote 5d96da3547 Merge branch '1508-check-android-paths-for-null' into 'master'
Check external storage paths for null

Closes #1508

See merge request briar/briar!1064
2019-03-22 14:53:41 +00:00
akwizgran ed842f781a Don't create extra activity instances from splash screen. 2019-03-22 13:37:58 +00:00
akwizgran 5e30e5e1de Check external storage paths for null. 2019-03-22 11:36:07 +00:00
Torsten Grote ce52a36db1 Display new contacts at the top of the contact list
by initializing their latest message time with the current time
2019-03-21 11:45:27 -03:00
akwizgran f5ef87b34b Merge branch '1289-recycler-view-visible-detection' into 'master'
Prevent RecyclerView's pre-rendering from marking invisible messages as read

Closes #1289

See merge request briar/briar!1061
2019-03-21 13:48:44 +00:00
Torsten Grote 4c6f68c255 [android] optimize method to update unread counts 2019-03-21 09:59:33 -03:00
Torsten Grote ae09b4c607 [android] remove complicated logic for detecting new visible items
notify after every scroll for all visible items instead
2019-03-19 12:35:15 -03:00
Torsten Grote 880d77922e [android] use ScrollListener to mark messages read in private conversation 2019-03-19 11:42:59 -03:00
Torsten Grote 1c227e81e4 [android] update unread counts with a ScrollListener in threaded conversations 2019-03-19 11:42:59 -03:00
akwizgran 541acad29a Merge branch '1357-proper-panic-deletion' into 'master'
Stop lifecycle before deleting app data and exit cleanly

Closes #1380 and #1357

See merge request briar/briar!1060
2019-03-19 14:15:49 +00:00
Torsten Grote 60f71648f3 [android] Don't start NavDrawerActivity directly from foreground notification
It might be that the lifecycle didn't start, so we need to show the
OpenDatabaseActivity first.
2019-03-19 11:14:01 -03:00
Torsten Grote 270b8af39f [android] add review comments for panic induced account deletion 2019-03-19 10:57:28 -03:00
Torsten Grote 31d3324701 [android] stop livecycle before delete app data and exit cleanly
Fixes #1380
2019-03-19 10:50:51 -03:00
akwizgran dbe46d60fd Merge branch '830-text-input-landscape-send' into 'master'
Make Text Input Fields Work In Landscape Mode

Closes #830

See merge request briar/briar!1053
2019-03-19 10:38:17 +00:00
akwizgran d10ab96955 Merge branch '1370-block-block-notification' into 'master'
Block blog notifications when this blog is open

Closes #1370

See merge request briar/briar!1057
2019-03-19 10:35:42 +00:00
akwizgran b2841e245a Merge branch 'gradle-plugin-3.3.2' into 'master'
Upgrade android gradle plugin to 3.3.2

See merge request briar/briar!1062
2019-03-19 10:15:37 +00:00
akwizgran 68c40f0c46 Minor code cleanups for crypto API. 2019-03-15 13:54:04 +00:00
Torsten Grote 9ccd8d1602 Upgrade android gradle plugin to 3.3.2
This also updates some briar-headless dependencies
2019-03-14 14:27:53 -03:00
Torsten Grote ac3942975e [android] add SendAction for RSS feed import 2019-03-12 17:10:52 -03:00
Torsten Grote b6455d40a7 [android] add SendAction to EmojiTextInputView 2019-03-12 16:05:53 -03:00
Torsten Grote 2815ad042d [android] don't show blog post notifications for own blog posts 2019-03-08 16:45:31 -03:00
Torsten Grote 2055961534 [android] remember scroll position in individual blogs
across configuration changes
2019-03-08 16:33:15 -03:00
Torsten Grote 741eae34e9 [android] save list position of main blog feed 2019-03-08 16:08:11 -03:00
Torsten Grote 50bd4cce6b [android] Save list position in threaded conversations 2019-03-08 16:08:11 -03:00
akwizgran 0a5a8310fc Merge branch '1210-contact-list-duplicates' into 'master'
Small improvements for contact list, hunting duplicates

See merge request briar/briar!1056
2019-03-08 14:26:56 +00:00
akwizgran cc43d5982a Merge branch '1196-remove-thread-sent-snackbars' into 'master'
Remove unnecessary snackbars in threaded conversation

Closes #1196

See merge request briar/briar!1055
2019-03-08 14:23:19 +00:00
akwizgran 50675473ce Merge branch '1126-link-warning-buttons' into 'master'
Make link warning dialog scrollable

Closes #1126

See merge request briar/briar!1050
2019-03-08 13:38:06 +00:00
akwizgran de852b2a9f Merge branch '1413-empty-state-fix' into 'master'
Always show empty state messages

Closes #1413

See merge request briar/briar!1059
2019-03-08 10:00:41 +00:00
Torsten Grote b7c712116b [android] Always show empty state messages
This works around an upstream ConstraintLayout Group visiblity bug:
https://issuetracker.google.com/issues/117485026
2019-03-01 15:34:29 -03:00
Torsten Grote 7dd4897c8c [android] small improvements for contact list 2019-02-28 15:16:36 -03:00
Torsten Grote 7469c0f5e3 [android] remove unnecessary snackbars in threaded conversation
that appear after posting a new message there
2019-02-28 14:28:37 -03:00
akwizgran 144ea0c2fc Merge branch '875-sharing-status-screen-updates' into 'master'
Update memberlists while they are open

Closes #875

See merge request briar/briar!1048
2019-02-28 13:27:19 +00:00
Torsten Grote a917ebdc76 [android] Close memberlist or sharing status screen when group was left 2019-02-28 09:25:18 -03:00
Torsten Grote 2a389c74dc [android] when sharing a forum or blog, add peers to list while it is open 2019-02-28 09:25:08 -03:00
Torsten Grote ef16d096f1 [android] add group members to memberlist when they join 2019-02-28 09:25:08 -03:00
akwizgran 679455888b Merge branch '833-ui-reference' into 'master'
Don't pass UI classes to the core, use events instead

See merge request briar/briar!1044
2019-02-28 11:11:14 +00:00
akwizgran d4372ddae7 Merge branch 'headless-document-build' into 'master'
Briar Headless: Document build process

See merge request briar/briar!1042
2019-02-28 11:10:24 +00:00
Nico Alt c3ef990a94 Briar Headless: Document build process 2019-02-27 21:27:04 +01:00
Torsten Grote 8ae9b7f5a2 [android] Ensure that buttons of link warning are always visible 2019-02-27 17:01:50 -03:00
Torsten Grote 106d80ef76 [android] Make link warning dialog scrollable 2019-02-27 14:03:20 -03:00
Torsten Grote 9422ba2718 Don't pass UI classes to the core, use events instead
This removed the ContactExchangeListener in favor of new events
2019-02-27 13:55:33 -03:00
akwizgran 8343f5c2db Merge branch 'objective-c' into 'master'
Remove Objective C from code styles

See merge request briar/briar!1051
2019-02-27 13:42:08 +00:00
akwizgran 371c7efb04 Merge branch '1106-memberlist-button' into 'master'
Move group memberlist button to overflow menu

See merge request briar/briar!1052
2019-02-27 13:40:19 +00:00
Torsten Grote 92d67645ab [android] move group memberlist button to overflow menu 2019-02-27 10:25:41 -03:00
Torsten Grote a20e868970 Remove Objective C from code styles 2019-02-27 10:14:22 -03:00
akwizgran dd853f6718 Merge branch '1475-status-bar-return-transition' into 'master'
Show the status bar when finishing ImageActivity

See merge request briar/briar!1036
2019-02-27 13:11:29 +00:00
akwizgran 16a8ad996a Merge branch '869-remove-group-button' into 'master'
[android] Fix private group status text over remove button

Closes #869

See merge request briar/briar!1047
2019-02-27 11:36:06 +00:00
akwizgran e27885f0c8 Merge branch '850-initial-group-sharing-status' into 'master'
Update group sharing status when creator joins group

Closes #850

See merge request briar/briar!1046
2019-02-27 11:34:55 +00:00
Torsten Grote f6ef48bf90 [android] Fix private group status text over remove button 2019-02-26 11:38:17 -03:00
Torsten Grote e282ca763d [android] Update group sharing status when creator joins group 2019-02-26 11:29:23 -03:00
Torsten Grote 71016382dc Merge branch 'tor-0.3.5.8' into 'master'
Upgrade Tor to 0.3.5.8

See merge request briar/briar!1045
2019-02-26 13:15:22 +00:00
akwizgran d004933fae Upgrade Tor to 0.3.5.8. 2019-02-26 12:39:47 +00:00
akwizgran 37512c50d8 Merge branch '1497-foreground-permission' into 'master'
Add FOREGROUND_SERVICE permission (needed when targeting higher API level)

See merge request briar/briar!1041
2019-02-21 10:30:10 +00:00
Torsten Grote 0b61a5d40a Add FOREGROUND_SERVICE permission (needed when targeting higher API level) 2019-02-20 11:00:15 -03:00
akwizgran 5dd320f282 Merge branch '1498-meek' into 'master'
Use the pluggable transport meek lite where obfs4 is blocked

Closes #1498 and #1418

See merge request briar/briar!1040
2019-02-19 17:37:13 +00:00
akwizgran 2a21db5fb6 Merge branch 'tor-0.3.5.7' into 'master'
Upgrade Tor to 0.3.5.7

See merge request briar/briar!1039
2019-02-19 16:37:30 +00:00
Torsten Grote b023593a2c Use the pluggable transport meek lite where obfs4 is blocked 2019-02-19 12:49:22 -03:00
Torsten Grote 5ccf2cae1f Upgrade Tor to 0.3.5.7 2019-02-19 11:09:45 -03:00
Torsten Grote c2cb89ab73 [android] show the status bar when finishing ImageActivity
to prevent visible jump in exit transition.
2019-02-13 16:54:16 -02:00
Torsten Grote b342759e06 Merge branch '978-tor-only-on-battery' into 'master'
Add a setting to disable Tor when running on battery

Closes #978

See merge request briar/briar!1032
2019-02-06 14:46:33 +00:00
akwizgran 93d99b0111 Tweak wording of Tor battery setting. 2019-02-06 14:23:15 +00:00
akwizgran 61e8d576d2 Update mobile data log message, simplify logic. 2019-02-06 14:20:04 +00:00
Torsten Grote 75c37a258e Add a setting to disable Tor when running on battery 2019-02-05 13:46:26 -02:00
akwizgran e964dae64b Merge branch '1468-image-size-tests' into 'master'
Add tests for parsing image sizes

See merge request briar/briar!1026
2019-01-15 17:26:55 +00:00
akwizgran 986d884b40 Refactor ImageManager to ImageHelper. 2019-01-15 17:14:57 +00:00
akwizgran 9557afabc6 Change MIME types to "image/jpeg", unsuppress warning. 2019-01-15 16:49:18 +00:00
Torsten Grote ebe6b0d4c0 [android] Split up AttachmentController tests into integration and unit 2019-01-15 16:33:03 +00:00
Torsten Grote 6e83fb7aef [android] add tests for getting attachment items from AttachmentController 2019-01-15 16:33:00 +00:00
Torsten Grote 7a5ec2af12 [android] Add test for MarkEnforcingInputStream 2019-01-15 16:32:23 +00:00
akwizgran ce1fde496c Merge branch '1477-check-attachment-support' into 'master'
Find out if contacts support image attachments and enable them

Closes #1477

See merge request briar/briar!1019
2019-01-15 15:35:48 +00:00
akwizgran 4b62c51fbf Revert to using a fixed delay for the onboarding. 2019-01-15 15:23:30 +00:00
akwizgran 226ed3dd73 Wrap long line, remove redundant variable. 2019-01-14 14:31:31 +00:00
akwizgran ab07dfb32c Use expression lambda. 2019-01-14 14:26:09 +00:00
akwizgran 20c51c1aa4 Group together fields with the same access restrictions. 2019-01-14 14:25:32 +00:00
Torsten Grote 232c2129a7 [android] use a LiveData in ConversationActivity to get notified when transition ended 2019-01-14 14:22:31 +00:00
Torsten Grote 3620edbfc9 [android] set a transition animation duration for ConversationActivity
so we know better for how long to delay the onboarding dialogs
2019-01-14 14:21:34 +00:00
Torsten Grote ad71d69149 Create and use method in MessagingManager for checking for image support 2019-01-14 14:21:33 +00:00
Torsten Grote f73f8ca7e7 [android] do not show two private conversation onboardings at the same time
Checking for introduction onboarding is now done in the ViewModel
together with the image onboarding. The latter has preference. If both
could be shown, the introduction onboarding will be delayed to the next
time the user enters the conversation.
2019-01-14 14:21:33 +00:00
Torsten Grote 16c701a71a [android] only enable image feature if contact supports it
Also show an onboarding the first time, the feature gets activiated
2019-01-14 14:21:19 +00:00
akwizgran 8183b7b26a Merge branch '1469-hide-ui-without-flashing' into 'master'
Hide UI without flashing

Closes #1469

See merge request briar/briar!1030
2019-01-11 17:22:04 +00:00
akwizgran bd48c97eab Merge branch 'upgrade-jackson-2.9.8' into 'master'
Upgrade Jackson to 2.9.8

See merge request briar/briar!1031
2019-01-11 17:07:07 +00:00
akwizgran 925dc29a1f Merge branch 'hide-ui-api-15' into 'master'
Improve UI hiding behaviour

See merge request briar/briar!1029
2019-01-11 17:03:24 +00:00
akwizgran 91777fd942 Hide UI without flashing. 2019-01-11 16:59:53 +00:00
akwizgran fbce8f81c7 Merge branch '1475-transition-name' into 'master'
Use a unique transition name for each AttachmentItem

See merge request briar/briar!1028
2019-01-11 16:54:24 +00:00
akwizgran d7c72c4d68 Use a unique transition name for each AttachmentItem. 2019-01-11 16:45:20 +00:00
akwizgran 4faf535801 Reduce visibility. 2019-01-11 16:45:20 +00:00
akwizgran 526ef7c6d8 Add array entries for new translations. 2019-01-11 15:13:06 +00:00
akwizgran 798dff1a03 Update translations, add Macedonian and Ukrainian. 2019-01-11 12:18:15 +00:00
akwizgran a4336776c9 Merge branch '1475-image-transitions' into 'master'
Resolve main issues with image transition animation

See merge request briar/briar!1016
2019-01-09 15:01:29 +00:00
akwizgran 418451cbd9 Use consistent conditions to decide whether to scroll. 2019-01-09 14:30:57 +00:00
akwizgran 045fcfc5fa Remove translucent window effect. 2019-01-09 14:30:57 +00:00
Torsten Grote ef998577db [android] add nullability annotations to ImageActivity 2019-01-09 14:30:57 +00:00
Torsten Grote a53345a3c9 [android] scroll down when new messages arrive while conversation is visible
Also shows new message notification when ConversationActivity is paused
2019-01-09 14:30:56 +00:00
Torsten Grote ed8c09282d [android] enable image shared element transition for API 21+22
There's an Android framework bug (#224270) on these APIs that causes a NPE
when the shared element is not visible anymore when returning.
Since we know restore the list position, the shared element should be
visible and thus not produce NPEs anymore.
2019-01-09 14:30:56 +00:00
Torsten Grote 42197b5b5c [android] Fix enter transition to fullscreen ImageActivity 2019-01-09 14:30:56 +00:00
Torsten Grote 374fc7035b [android] Save and restore list position of conversation across restarts 2019-01-09 14:30:55 +00:00
akwizgran 9b796c7cc3 Merge branch '1438-send-image-attachments-multiple' into 'master'
UX for sending multiple image attachments

See merge request briar/briar!1015
2019-01-04 17:04:43 +00:00
akwizgran 532edff642 Minor code cleanups. 2019-01-04 16:55:29 +00:00
akwizgran 6857252471 Merge branch '1480-window-background' into 'master'
[android] Change light theme background color closer to white

See merge request briar/briar!1020
2018-12-21 16:48:18 +00:00
Torsten Grote c229e19452 [android] remove images from preview that could not be loaded
We will not even attempt to attach them
2018-12-21 11:05:34 -02:00
Torsten Grote 42bca09d16 [android] Add gap between attached image previews 2018-12-21 11:05:34 -02:00
Torsten Grote 9eacbfa659 [android] Remove palette library
we are not extracting photo colors anymore
2018-12-21 11:05:34 -02:00
Torsten Grote f14e546dc6 [android] allow to attach multiple images 2018-12-21 11:05:34 -02:00
akwizgran 684c64a1d9 Merge branch '1310-disable-enter-transition-for-samsung7' into 'master'
[android] Disable Conversation Enter Transition for Samsung 7 devices

Closes #1310

See merge request briar/briar!1023
2018-12-19 11:32:51 +00:00
akwizgran 6fdab959b1 Merge branch '631-inject-fragments-early' into 'master'
Inject fragments earlier in their lifecycle

Closes #631

See merge request briar/briar!1024
2018-12-19 11:24:31 +00:00
Torsten Grote c8487483ff [android] Also consider Android 7.1 (API 25) to be Samsung7
which is used for disabling certain features due to crashes there.
2018-12-18 18:17:27 -02:00
Torsten Grote a159b23dc0 [android] Disable Conversation Enter Transition for Samsung 7 devices 2018-12-18 18:16:32 -02:00
Torsten Grote 5070a27a83 [android] also fix some activity nullability issues 2018-12-18 18:12:05 -02:00
Torsten Grote 9ce73a6840 [android] inject fragments already in onAttach()
This also removes the need to override the inject method even when
there's nothing to inject.

While passing over all fragments, some nullability issues also have been
addressed.
2018-12-18 18:01:04 -02:00
akwizgran 6e9928f20f Merge branch '1484-wait-for-component-to-be-created' into 'master'
[android] AliasFragment: Wait for activity component to be created

Closes #1484

See merge request briar/briar!1022
2018-12-18 17:46:19 +00:00
Torsten Grote b31d61afc5 [android] AliasFragment: Wait for activity component to be created
before injecting the ViewModel
2018-12-18 15:32:26 -02:00
akwizgran 5a99cb93cc Merge branch '1482-check-earlier-for-sign-in' into 'master'
[android] don't crash when re-opening conversation after briar exited

Closes #1482

See merge request briar/briar!1021
2018-12-18 12:58:39 +00:00
Torsten Grote d0bbebd25e [android] don't crash when re-opening conversation after briar exited 2018-12-17 18:42:06 -02:00
Torsten Grote 4307d26606 [android] Change light theme background color closer to white 2018-12-17 17:25:12 -02:00
akwizgran 0089c1ac6d Merge branch '1468-restrict-image-size' into 'master'
Fix first issues related to image size

See merge request briar/briar!1018
2018-12-17 12:48:15 +00:00
akwizgran 2a7aac4930 Upgrade Jackson to 2.9.8. 2018-12-17 12:09:36 +00:00
akwizgran a37b6d81ed Merge branch '1242-save-snackbar-fix' into 'master'
[android] Clarify the meaning of image save state

See merge request briar/briar!1017
2018-12-17 11:17:12 +00:00
Torsten Grote 1d09a6708a [android] don't ever load an entire image into memory
This happens on API 27+28 if loading TIFF or WebP files.
Using an InputStream with a read limit prevents this.
2018-12-14 20:11:43 -02:00
Torsten Grote d3b6f484c8 [android] allow image transformations in full-screen view
to prevent crashes from huge images
2018-12-14 20:11:43 -02:00
Torsten Grote 039c6edb66 [android] increase scale levels of PhotoView 2018-12-14 20:11:43 -02:00
Torsten Grote 8b9f89eab2 [android] Clarify the meaning of image save state 2018-12-14 12:27:47 -02:00
akwizgran 1e2c17b170 Merge branch '1242-display-image-attachments-multiple' into 'master'
Swipe left/right in image screen for images from same message

See merge request briar/briar!1012
2018-12-13 16:33:24 +00:00
Torsten Grote a994966095 [android] address review comments for image fullscreen swiping 2018-12-13 12:00:51 -02:00
Torsten Grote 2bea581654 [android] Swipe left/right in image screen to see other images from the same message 2018-12-13 11:59:41 -02:00
Torsten Grote 87377666aa Merge branch '1473-display-multiple-images' into 'master'
UX for displaying multiple image attachments

Closes #1473

See merge request briar/briar!1010
2018-12-13 13:07:24 +00:00
akwizgran 9d07b2e141 Resolve merge conflicts.
# Conflicts:
#   briar-android/src/main/java/org/briarproject/briar/android/conversation/AttachmentController.java
#   briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java
2018-12-13 11:41:04 +00:00
akwizgran 5c312b49e2 Merge branch '1438-send-image-attachments' into 'master'
Store attachments and actually attach them to sent messages

Closes #1438

See merge request briar/briar!1006
2018-12-13 10:27:09 +00:00
Torsten Grote f56efe45cd Merge branch '1477-get-client-minor-version' into 'master'
Add method for querying client minor version supported by contact

See merge request briar/briar!1014
2018-12-12 19:34:55 +00:00
Torsten Grote 2332a58681 [android] address review comments for displaying multiple images 2018-12-12 17:00:44 -02:00
Torsten Grote 8c6dfaa196 [android] Use @UiThread instead of @MainThread 2018-12-12 16:18:43 -02:00
Torsten Grote 3cfb04b60d Establish some rules for handling InputStreams
* Methods shouldn't place any special requirements on the streams
  passed into them
* This implies that if a stream's going to be marked and reset,
  that should all happen within one method
* This also implies that if a method needs to mark and reset a stream,
  it should wrap the stream in a BufferedInputStream before doing so,
  rather than requiring a markable stream to be passed in
2018-12-12 16:17:50 -02:00
Torsten Grote e85fbfb952 [android] close InputStream with new IoUtils method 2018-12-12 16:17:50 -02:00
Torsten Grote 80ee35d926 [core] Return fake mini PNG as Attachment instead of throwing exception 2018-12-12 16:17:50 -02:00
Torsten Grote 4796902b9c [android] store attachments and actually attach them to sent messages 2018-12-12 16:17:50 -02:00
akwizgran 149e67c0f7 Reduce code duplication in tests. 2018-12-12 11:57:35 +00:00
akwizgran 1d5214117f Add tests for getClientMinorVersion(). 2018-12-11 17:55:39 +00:00
akwizgran b8f248ca9c Add tests for getClientVisibility(). 2018-12-11 17:51:42 +00:00
Torsten Grote dfb71a03a5 [android] Only retrieve image sizes for single images in messages
We need to do this to know the height of messages when binding the view.
The size of single images can be different (e.g. due to orientation).
For multiple images, we use a fixed size, so no retrieval is required.
2018-12-11 15:38:05 -02:00
Torsten Grote 961fdc8e72 [android] Show multiple images in message bubble 2018-12-11 15:28:21 -02:00
Torsten Grote c3d44663cd [android] Use a nested RecyclerView with a single items to show image attachments
This is preparation for showing multiple image attachments in one
message bubble.
2018-12-11 15:28:21 -02:00
akwizgran 0081472489 Add method for querying contact's client minor version. 2018-12-11 17:25:29 +00:00
akwizgran cdf4f3a24b Merge branch '1232-add-contacts-remotely-api' into 'master'
[api] Add interface for adding contacts remotely

See merge request briar/briar!1007
2018-12-10 10:53:37 +00:00
Torsten Grote fb1d8e860f [api] Add interface for adding contacts remotely 2018-12-10 08:30:50 -02:00
akwizgran a3c526ec9a Merge branch '1298-scrub-wifi-address-in-crash-report' into 'master'
Scrub wifi IP address in crash reports.

Closes #1298

See merge request briar/briar!1013
2018-12-10 10:12:42 +00:00
Jordi Salvat dee488d06d Scrub wifi IP address in crash reports. 2018-12-10 01:07:37 +01:00
Torsten Grote b29c7d8022 Merge branch '1385-make-link-cover-entire-word' into 'master'
[android] fix start of link in error message for adding contacts

Closes #1385

See merge request briar/briar!1011
2018-12-07 19:13:54 +00:00
akwizgran 0725d207ec Merge branch '1432-headless-integration-tests' into 'master'
[headless] Add first integration test for ContactController

See merge request briar/briar!1008
2018-12-07 17:37:22 +00:00
akwizgran 5a7599a88d Merge branch '1242-display-image-attachments-save' into 'master'
Allow the user to save image attachment outside of Briar

See merge request briar/briar!1005
2018-12-07 17:31:42 +00:00
Torsten Grote 59cd98db81 [android] Get image extension from MimeTypeMap and store it in AttachmentItem 2018-12-07 15:11:09 -02:00
Torsten Grote 768488eb04 [android] Show (tinted) security icon when warning about saving attachments 2018-12-07 14:39:43 -02:00
Torsten Grote a6b1ad48c3 [android] Add support for saving image attachments on API < 19
This is done by using the WRITE_EXTERNAL_STORAGE permission
to write the file directly without using the system activity.
2018-12-07 13:01:44 -02:00
Torsten Grote 77299a68ed [android] Allow the user to save image attachment outside of Briar 2018-12-07 13:01:42 -02:00
akwizgran 5e5705c73b Merge branch '1438-send-image-attachments-ui' into 'master'
Implement UX for sending image attachments

See merge request briar/briar!1004
2018-12-07 14:58:23 +00:00
Torsten Grote e6229a3a13 [android] Factor out image preview into its own view class 2018-12-06 17:56:02 -02:00
Torsten Grote 5fbacb4ee4 [android] Split out an EmojiTextInputView from TextInputViews
This also removes the TextInputController whose job is now done by the view.
2018-12-06 17:56:02 -02:00
Torsten Grote c7f4e976ed [android] Require users of TextInputView to set its controller 2018-12-06 17:56:02 -02:00
Torsten Grote 419f2d966a [android] Show a toast when an image could not be attached 2018-12-06 17:56:02 -02:00
Torsten Grote d6c18db9e9 [android] set image preview size to 1/4 of screen height 2018-12-06 17:56:02 -02:00
Torsten Grote 8fe49d9961 [android] Re-factor TextInputViews 2018-12-06 17:56:02 -02:00
Torsten Grote f536cfdab8 [android] first round of review comments for attaching images 2018-12-06 17:56:02 -02:00
Torsten Grote 4d594acad5 [android] Save attached (but not sent) image on screen rotation 2018-12-06 17:56:02 -02:00
Torsten Grote 800dfed5c1 [android] support adding image attachments to private messages 2018-12-06 17:55:59 -02:00
Jordi Salvat 54b823e401 [android] fix start of link in error message for adding contacts 2018-12-06 20:44:36 +01:00
Torsten Grote 52ec56d690 Merge branch 'invalid-slide-direction' into 'master'
Revert change to slide direction

Closes #1478

See merge request briar/briar!1009
2018-12-06 15:32:07 +00:00
akwizgran d4f8abfac1 Suppress warning about parameter used by subclasses. 2018-12-06 15:24:09 +00:00
akwizgran d07c144316 Remove unnecessary null check. 2018-12-06 15:24:09 +00:00
akwizgran dcd5189910 Remove unused DB code for managing disk space. 2018-12-06 15:24:08 +00:00
akwizgran 7b3afcca99 Revert change to slide direction. 2018-12-06 15:18:16 +00:00
Torsten Grote a22d03d028 [headless] wait for lifecycle manager to finish starting
before starting web server
2018-12-05 16:08:03 -02:00
Torsten Grote d857338ad0 [headless] Add first integration test for ContactController 2018-12-05 16:04:14 -02:00
akwizgran a5c9e7c74d Merge branch '1242-display-image-attachments-fullscreen' into 'master'
Add ImageActivity to show image attachment in full-screen

See merge request briar/briar!999
2018-11-30 18:04:55 +00:00
Torsten Grote 8a4a343147 [android] Move image to the top if it is overlapping the toolbar 2018-11-30 15:53:38 -02:00
akwizgran dcd5e34c6b Improve UI hiding behaviour. 2018-11-30 12:40:45 +00:00
Torsten Grote 7b22d3b84d [android] Address review issues for image fullscreen view 2018-11-28 17:26:01 -02:00
Torsten Grote c8fa23273f [android] support pull down to dismiss pattern for ImageActivity 2018-11-28 17:26:01 -02:00
Torsten Grote fbe5df8938 [android] Add ImageActivity to show images in full-screen 2018-11-28 17:26:01 -02:00
akwizgran 008cf95741 Merge branch '1467-conversation-scrolling' into 'master'
Only scroll conversation list to bottom, when already at bottom

Closes #1467

See merge request briar/briar!1000
2018-11-27 09:32:05 +00:00
Torsten Grote 3eb066a836 [android] Use new IoUtils to close InputStreams 2018-11-26 16:28:06 -02:00
Torsten Grote 674b29af25 [android] static constant all caps 2018-11-26 16:23:51 -02:00
Torsten Grote b8ca5ab557 [android] Only scroll conversation list to bottom, when already at bottom
Closes #1467
2018-11-26 16:23:17 -02:00
Torsten Grote 6e17709f46 Merge branch 'try-to-close' into 'master'
Move tryToClose() methods into utility classes

See merge request briar/briar!1002
2018-11-26 18:22:24 +00:00
akwizgran 726d90145c Merge branch '1242-display-image-attachments' into 'master'
[android] display image attachments for conversation messages

See merge request briar/briar!997
2018-11-26 17:19:37 +00:00
Torsten Grote 165211eb9b Merge branch '1259-headless-mac-os' into 'master'
Enable headless app to start on MacOS

See merge request briar/briar!1003
2018-11-26 12:01:27 +00:00
akwizgran 868c61e5d6 Move tryToClose() methods into utility classes. 2018-11-23 15:02:27 +00:00
Torsten Grote 798bb6d4f7 [android] scale thumbnails to minimum size, don't upscale to maximum size 2018-11-23 11:25:18 -02:00
akwizgran bc352a2dc6 Enable Tor on Mac OS once binaries are available. 2018-11-23 13:07:12 +00:00
akwizgran ce7d6d3db5 Code cleanup. 2018-11-23 12:56:34 +00:00
akwizgran 61276c81d2 Make it possible to start the headless app on MacOS.
The app is still non-functional because we don't have a Tor plugin.
2018-11-23 12:52:40 +00:00
Torsten Grote c09abdb088 Merge branch 'location-permission-sdk-23' into 'master'
Change location permission to uses-permission-sdk-23

See merge request briar/briar!1001
2018-11-22 12:03:07 +00:00
akwizgran 45a11badd5 Change location permission to uses-permission-sdk-23. 2018-11-20 16:16:47 +00:00
Torsten Grote 152ac3df43 [android] improve bitmap transformation hashKey and DiskCacheKey 2018-11-20 11:49:21 -02:00
Torsten Grote dd5ad86db8 [android] Use DataFetcherFactory to create data fetchers and allow cancelling loads 2018-11-20 11:49:21 -02:00
Torsten Grote 10e9fb308d [android] Display Image Attachements: Address first round of review comments 2018-11-19 20:35:07 -02:00
Torsten Grote de8e95692a [android] support RTL languages when rounding thumbnail corners 2018-11-19 20:35:07 -02:00
Torsten Grote d6b52cf4ec [android] Use our own BitmapTransformation for rounded image corners 2018-11-19 20:35:07 -02:00
Torsten Grote 8a839fb5e4 [android] display image attachments for conversation messages 2018-11-19 20:35:07 -02:00
akwizgran fbf8642edb Merge branch '1464-message-status-mixed' into 'master'
[core] fix wrong order of message status flags in conversation headers

Closes #1464

See merge request briar/briar!998
2018-11-16 13:44:39 +00:00
Torsten Grote ade6a14342 Merge branch 'validation-refactoring' into 'master'
Reorganise validation code

See merge request briar/briar!991
2018-11-15 17:18:15 +00:00
Torsten Grote d500ff81c3 Merge branch 'require-non-null' into 'master'
Add static requireNonNull() method

See merge request briar/briar!996
2018-11-15 16:50:16 +00:00
Torsten Grote 3053e3cfa7 [core] fix wrong order of message status flags in conversation headers 2018-11-15 14:39:05 -02:00
akwizgran 6964a67ca3 Add static requireNonNull() method. 2018-11-15 11:13:15 +00:00
Torsten Grote f4b06e1fb3 Merge branch 'load-latest-message-eagerly' into 'master'
Load latest message eagerly

See merge request briar/briar!995
2018-11-14 16:01:59 +00:00
akwizgran 4db075d643 Only consider the latest item for preloading. 2018-11-14 15:13:25 +00:00
akwizgran 78a8ae6b8e Sort headers and eagerly load text of latest message. 2018-11-14 15:01:54 +00:00
Torsten Grote 7866037d02 Merge branch '1460-introduction-request-text' into 'master'
Show correct text when an existing contact is introduced

Closes #1460

See merge request briar/briar!994
2018-11-14 11:23:26 +00:00
akwizgran 35716051fb Show correct text when an existing contact is introduced. 2018-11-14 11:05:46 +00:00
Torsten Grote 6cafea836f Merge branch 'eager-singletons' into 'master'
Singletons that call registration methods must be eager

See merge request briar/briar!993
2018-11-13 18:03:28 +00:00
akwizgran bd0fd229c6 Merge branch '1242-attachment-input-stream' into 'master'
Attachments will use InputStream rather than ByteBuffer

See merge request briar/briar!992
2018-11-13 17:41:39 +00:00
akwizgran ea05a5c703 Singletons that call registration methods must be eager. 2018-11-13 17:40:06 +00:00
akwizgran 4103eaf639 Reorganise validation code (no functional changes). 2018-11-13 17:16:47 +00:00
Torsten Grote 753a25bc2a [core] Attachments will use InputStream rather than ByteBuffer 2018-11-13 15:12:34 -02:00
akwizgran 8f4c3c4528 Bump version numbers for 1.1.5 release. 2018-11-13 13:01:01 +00:00
akwizgran 636a7dfe72 Update translations. 2018-11-13 12:59:51 +00:00
akwizgran 08e99edd42 Merge branch 'unpack-tor-binaries' into 'master'
Always unpack and include latest Tor binaries

See merge request briar/briar!987
2018-11-13 12:56:47 +00:00
akwizgran e28bc475df Merge branch '1242-optional-message-text' into 'master'
Add support for private messages without text

See merge request briar/briar!990
2018-11-13 10:47:52 +00:00
Torsten Grote 88276a4d44 Add support for private messages without text 2018-11-12 18:11:03 -02:00
akwizgran f9987c89df Merge branch 'disable-tor-connection-padding' into 'master'
Disable Tor's connection padding

See merge request briar/briar!989
2018-11-12 14:03:22 +00:00
Torsten Grote 2c8cb8301f Merge branch '1455-stream-context-may-be-null' into 'master'
Stream context may be null

Closes #1455

See merge request briar/briar!988
2018-11-12 12:50:01 +00:00
akwizgran c00ee80f0f Update test expectations. 2018-11-12 12:20:04 +00:00
akwizgran 3bfedfdc3d Add action for nullable DB callables. 2018-11-12 12:16:42 +00:00
akwizgran ecb63d1acb Add interface for DB tasks will nullable results. 2018-11-12 12:13:26 +00:00
akwizgran b24914408d Stream context may be null. 2018-11-12 11:31:59 +00:00
akwizgran 5ede63edd5 Always unpack and include latest Tor binaries. 2018-11-08 17:48:26 +00:00
akwizgran 4e523c5fbc Merge branch '1242-display-image-attachments' into 'master'
[android] refactor conversation items and view holders

See merge request briar/briar!984
2018-11-08 16:08:58 +00:00
akwizgran cf79ed5633 IntentFilter may not be thread-safe. 2018-11-08 14:54:53 +00:00
akwizgran 0a0a6a6369 Disable Tor's connection padding on mobile data or battery. 2018-11-08 14:50:36 +00:00
akwizgran 4784980e7b No need to broadcast network status at startup. 2018-11-08 14:50:36 +00:00
akwizgran 3bfa5e2081 [android] Move ConversationListener to top level. 2018-11-08 10:27:36 -02:00
akwizgran f2b09deac4 [android] Remove type parameter from view holders. 2018-11-08 10:27:29 -02:00
Torsten Grote ad4729b2f9 [android] refactor conversation items and view holders
This is a preparation for image support.
2018-11-08 10:27:29 -02:00
akwizgran 50cc0a6815 Merge branch '1452-websocket-authentication' into 'master'
[headless] change websocket authentication from basic auth to token message

Closes #1452

See merge request briar/briar!986
2018-11-08 12:26:53 +00:00
Torsten Grote 32c8ac6576 [headless] change websocket authentication from basic auth to token message 2018-11-08 10:15:17 -02:00
akwizgran c12422d949 Merge branch '1434-android-conversation-package' into 'master'
Move conversation classes into their own package

See merge request briar/briar!978
2018-11-08 11:01:36 +00:00
akwizgran 3841713c18 Merge branch 'upgrade_roboletric_to_401' into 'master'
Upgrade robolectric to 4.0.1

See merge request briar/briar!980
2018-11-08 11:00:08 +00:00
akwizgran 79232eb558 Merge branch 'headless-fixes' into 'master'
Headless fixes

See merge request briar/briar!985
2018-11-08 10:55:28 +00:00
Torsten Grote d02b30e751 Merge branch 'use-transactional-db-api' into 'master'
Use transactional database API in Bramble

See merge request briar/briar!974
2018-11-07 19:06:26 +00:00
akwizgran 043662a092 Code cleanup. 2018-11-07 18:31:07 +00:00
Torsten Grote efc85fb88f [headless] don't use putAll for a single field 2018-11-07 15:24:20 -03:00
Torsten Grote 8b3983ef9e [headless] only offload to DatabaseExecutor when needed
when receiving a new conversation message
2018-11-07 15:24:20 -03:00
Torsten Grote 6766fb76b2 [headless] upgrade javalin and mockk 2018-11-07 15:18:46 -03:00
Torsten Grote 7f74bd1c38 [headless] Use --user for websocket example request
The authentication token can contain slashes.
When used as part of the URL, the URL becomes invalid.
Therefore, using curl's user parameter is preferrable.
2018-11-07 15:18:46 -03:00
akwizgran 951ee30b95 Update tests. 2018-11-07 18:18:30 +00:00
akwizgran c386a0f5eb Replace Maybe with nullable transaction method. 2018-11-07 18:18:30 +00:00
akwizgran 52c778dce3 Reformat code. 2018-11-07 18:18:27 +00:00
akwizgran e846a13f50 Use transactional database API in Bramble. 2018-11-07 18:14:10 +00:00
akwizgran 23e9b119d1 Merge branch '1434-message-attachments' into 'master'
Add attachment API for sending/retreiving private messages

See merge request briar/briar!976
2018-11-07 18:08:36 +00:00
akwizgran e6f380296f Merge branch '1451-briar-headless-test-other-modules' into 'master'
[headless] Limit tests in Android Studio to headless package

Closes #1451

See merge request briar/briar!983
2018-11-07 17:47:37 +00:00
Torsten Grote 794fb9686b [headless] Limit tests in Android Studio to headless package 2018-11-07 13:46:49 -03:00
Torsten Grote bb22b9db10 Merge branch 'remove-hamcrest-dependencies' into 'master'
Remove redundant dependency declarations

See merge request briar/briar!981
2018-11-07 16:37:30 +00:00
Julian Dehm d4f015d054 Upgrade robolectric to 4.0.1 2018-11-07 17:11:21 +01:00
akwizgran 41e5d8900c Remove redundant dependency declarations. 2018-11-07 16:10:39 +00:00
Torsten Grote c3cb966009 [android] move conversation classes into their own package 2018-11-07 11:48:20 -03:00
Torsten Grote f964d1ef07 Fix receivers of ConversationMessageReceivedEvent
These were only listening to private message events, ignoring all others
2018-11-07 11:34:11 -03:00
Torsten Grote cccaeeda6c [core] Add API to add messages with attachments 2018-11-07 11:34:11 -03:00
Torsten Grote 483106e00c [core] Add MessagingManager#getAttachment() 2018-11-07 11:34:11 -03:00
Torsten Grote 934f14ef31 [core] Add attachment support to private messages 2018-11-07 11:34:09 -03:00
Torsten Grote e3abff5ad8 Refactor PrivateMessageHeader to ConversationMessageHeader base-class
This is preparation for adding attachments to private messages
2018-11-07 11:33:37 -03:00
Torsten Grote 391732b239 Merge branch 'change-contact-name' into 'master'
Change button text to match name of action

See merge request briar/briar!979
2018-11-07 12:11:22 +00:00
akwizgran 4738bfdd85 Ignore missing translations. 2018-11-07 10:43:13 +00:00
akwizgran be1ca89309 Change button text to match name of action. 2018-11-07 10:40:59 +00:00
Torsten Grote 866be99179 Merge branch '41-alias-frontend' into 'master'
Add UI for changing contact aliases

Closes #41

See merge request briar/briar!965
2018-11-06 18:09:47 +00:00
akwizgran 48822e2133 Merge branch '1381-introduction-test-fails' into 'master'
Fix non-determinism of Introduction integration tests

Closes #1381

See merge request briar/briar!970
2018-11-06 18:00:48 +00:00
Torsten Grote 6883c5caa9 [android] address last contact aliases review issues 2018-11-06 14:57:39 -03:00
Torsten Grote 8b709969ab [android] pass ContactId via ViewModel to AliasDialogFragment 2018-11-06 13:42:51 -03:00
Torsten Grote fe94b65b3b [android] Fix double loading of conversation messages when rotating screen 2018-11-06 13:42:51 -03:00
akwizgran f54df1d787 Reduce visibility, remove unnecessary rethrow. 2018-11-06 13:42:51 -03:00
akwizgran a7e826ccf5 Remove qualification from java.lang.Runnable. 2018-11-06 13:42:51 -03:00
akwizgran 845eb3262b Use expression lambda. 2018-11-06 13:42:51 -03:00
akwizgran 0a46ad439f Check whether activity is null. 2018-11-06 13:42:51 -03:00
akwizgran d14d93ea35 Require observed data to be non-null. 2018-11-06 13:42:51 -03:00
akwizgran 12a1cf8f8b Reuse Observer interface. 2018-11-06 13:42:51 -03:00
akwizgran fb2ab861db Fix some lint warnings. 2018-11-06 13:42:51 -03:00
Torsten Grote aa15b68d24 [android] Reload conversation when contact name changes 2018-11-06 13:42:51 -03:00
Torsten Grote 7059f376f1 [android] Add UI for changing contact alias
This introduces the first ViewModel to share state between the
ConversationActivity and the AliasDialogFragment.
2018-11-06 13:42:51 -03:00
akwizgran 9313c191c1 Merge branch 'ui-fixes' into 'master'
Small UI fixes

See merge request briar/briar!975
2018-11-05 10:40:09 +00:00
akwizgran 7746364ae9 Merge branch '1437-reversed-emoji' into 'master'
[android] Add new emojis to the beginning of the list of recently used ones

Closes #1437

See merge request briar/briar!977
2018-11-05 10:27:03 +00:00
Torsten Grote 7429857b28 [android] Add new emojis to the beginning of the list of recently used ones
Otherwise the list will be reversed with most recently used at the end.
2018-11-04 11:08:05 -03:00
Torsten Grote 4db64f51a8 [android] Use same color for all messages in private groups 2018-11-02 15:59:49 -03:00
Torsten Grote 78172038ef [android] Always center selectable contacts vertically 2018-11-02 15:38:01 -03:00
Torsten Grote 7d0c418877 [android] Align short incoming messages on the left 2018-11-02 15:37:16 -03:00
Torsten Grote 5ae4f8f6cb [core] Fix non-determism in GroupInvitationIntegrationTest 2018-11-02 14:08:42 -03:00
Torsten Grote 45dd10db9d [core] Fix non-determinism in introduction integration tests 2018-11-02 14:08:42 -03:00
Torsten Grote 5cc8c268ca [core] Re-add message counter and put debug output behind flag 2018-11-02 14:08:42 -03:00
akwizgran 93a6bf2f52 Add logging to debug test failures. 2018-11-02 12:48:23 -03:00
akwizgran 852dd46a1b Utility class for converting BDF to strings.
(cherry picked from commit 9e94917)
2018-11-02 12:48:23 -03:00
Torsten Grote 4a42e767d3 [core] Add a detector for message delivery non-determinism 2018-11-02 12:48:13 -03:00
akwizgran 8547b4dc91 Merge branch 'upgrade-dagger' into 'master'
Upgrade dagger

See merge request briar/briar!973
2018-11-01 14:17:35 +00:00
akwizgran f6c8a8cec7 Move dagger.gradle to project root. 2018-11-01 14:05:46 +00:00
Torsten Grote db8796049e gradle: Factor out dagger apt code into its own file 2018-11-01 10:45:59 -03:00
Torsten Grote e1f31ad381 Remove gradle-apt-plugin since it isn't stricly needed anymore
Reference: https://github.com/tbroyer/gradle-apt-plugin/blob/6b2ee87fbf52ee09f70fb585d37e1d834da5ae3e/README.md
2018-10-31 16:01:57 -03:00
Torsten Grote 3a15e47ddd Upgrade Dagger to latest version 2018-10-31 15:57:21 -03:00
Torsten Grote cf616905d6 Merge branch 'introduction-manager-skip-session-parsing' into 'master'
Avoid some unnecessary session parsing when retrieving introduction messages

See merge request briar/briar!972
2018-10-31 16:36:59 +00:00
akwizgran d3f774f339 Avoid some unnecessary session parsing. 2018-10-31 16:18:33 +00:00
akwizgran 6c7c488892 Merge branch '41-alias-frontend-base' into 'master'
[android] Show contact aliases in UI

See merge request briar/briar!971
2018-10-31 16:16:38 +00:00
Torsten Grote 3fe7aae97e Contact aliases: address review comments 2018-10-31 13:06:19 -03:00
Torsten Grote ecf417c93b [android] Show contact alias in remaining places 2018-10-31 13:06:19 -03:00
Torsten Grote c1785c5b13 [android] Show contact alias in contact lists 2018-10-31 13:06:19 -03:00
Torsten Grote fb2c321a3d [android] Show contact alias inside private groups and their memberlist 2018-10-31 13:06:19 -03:00
Torsten Grote 6e3adc0874 Show alias for introduction notices in private conversation 2018-10-31 13:06:19 -03:00
Torsten Grote cdbe2a00f5 [android] Show alias for creator of private group in list of private groups 2018-10-31 11:40:17 -03:00
Torsten Grote a51dc7e0d5 [android] Show Author alias in AuthorView 2018-10-31 11:40:15 -03:00
Torsten Grote 0ee7465429 Merge branch '41-alias-author-info' into 'master'
Refactor Author.Status into dedicated AuthorInfo class and add alias

See merge request briar/briar!968
2018-10-30 19:33:39 +00:00
Torsten Grote 7c202189a2 [bramble] Implement equals() and hashCode() for AuthorView 2018-10-30 15:21:09 -03:00
akwizgran da3b2c1591 Merge branch '41-alias-backend' into 'master'
Add backend support for contact aliases

See merge request briar/briar!963
2018-10-30 16:43:52 +00:00
Torsten Grote 6c5e8ce4cf Rename remaining occurrences of status to authorInfo 2018-10-30 13:40:04 -03:00
Torsten Grote ca700d8d23 [bramble] address review comments 2018-10-30 13:32:56 -03:00
akwizgran db11dad61e Merge branch 'clean-tor-binaries' into 'master'
Delete Tor binaries when cleaning

See merge request briar/briar!969
2018-10-30 13:59:21 +00:00
akwizgran 69e7366226 Merge branch '1433-illegal-characters' into 'master'
Handle illegal byte sequences safely in BdfReaderImpl

Closes #1433

See merge request briar/briar!967
2018-10-30 13:58:36 +00:00
akwizgran 90b7b4e67f Merge branch '1416-obfs4' into 'master'
Add obfs4proxy and switch to obfs4 bridges

Closes #1417

See merge request briar/briar!964
2018-10-30 13:58:13 +00:00
akwizgran d29812a42b Delete Tor binaries when cleaning. 2018-10-30 13:06:06 +00:00
Torsten Grote baf64e1129 [bramble] Add transactionless method for retrieving AuthorInfo to ContactManager 2018-10-29 18:16:34 -03:00
Torsten Grote 88adfabe09 Refactor Author.Status into dedicated AuthorInfo class and add alias 2018-10-29 17:23:45 -03:00
akwizgran 6565172e10 Bump version numbers for 1.1.4 release. 2018-10-29 17:31:09 +00:00
akwizgran 7447468ce5 Update translations. 2018-10-29 17:30:04 +00:00
akwizgran 2db2a1a208 Replace a slow bridge with a faster one. 2018-10-29 17:25:12 +00:00
akwizgran 0d7e4feaf2 Throw AssertionError to make intent clearer. 2018-10-29 17:02:07 +00:00
akwizgran eb3983f6b2 Use safe ASCII decoding in ModemImpl. 2018-10-29 16:48:18 +00:00
akwizgran e2ce49c30e Use safe UTF-8 decoding in BdfReaderImpl. 2018-10-29 16:47:55 +00:00
akwizgran adc6fb2fd5 Add fuzzing test for illegal UTF-8 byte sequences. 2018-10-29 16:44:02 +00:00
Torsten Grote 969150bff0 [bramble] Factor out database type placeholder replacement
to make it available in database schema migrations
2018-10-29 12:50:08 -03:00
Torsten Grote 8fc622f85d [bramble] Add support for contact aliases
Foundation for #41
2018-10-29 12:50:08 -03:00
akwizgran 22eed91019 Merge branch 'javalin-access-manager' into 'master'
[headless] Set up access manager before starting server

See merge request briar/briar!966
2018-10-29 15:35:48 +00:00
akwizgran fcb88ed58c Merge branch '1147-bluetooth-discovery' into 'master'
Support Bluetooth discovery for adding contacts

See merge request briar/briar!954
2018-10-29 14:35:17 +00:00
Torsten Grote 0d940fc7d7 [headless] Set up access manager before starting server
This became necesary to due an upstream change we missed when bumping
the dependency:

https://github.com/tipsy/javalin/commit/ab19ff91b7963313479779636c557770d93a5098
2018-10-29 11:20:48 -03:00
Torsten Grote ca6dc33cdd Add obfs4 proxy and switch to obfs4 bridges 2018-10-25 09:38:44 -03:00
akwizgran 53da13794f Merge branch '1422-activity-log' into 'master'
Log when activities start and stop

See merge request briar/briar!959
2018-10-24 16:00:52 +00:00
akwizgran 2ab03f48cc Merge branch '1256-remove-contact' into 'master'
briar-headless: Add endpoint for removing a contact

See merge request briar/briar!962
2018-10-24 15:59:39 +00:00
Torsten Grote 436f45554d [briar-headless] update dependencies 2018-10-24 12:41:29 -03:00
Torsten Grote 51209b5eec briar-headless: Add endpoint for removing a contact 2018-10-24 12:12:33 -03:00
akwizgran 822597b4c6 Merge branch '1373-mirror-icons' into 'master'
Fix RTL icon mirroring in DevReportActivity

Closes #1373

See merge request briar/briar!960
2018-10-24 14:05:06 +00:00
akwizgran 7c01bc59c0 Merge branch '1252-dark-theme-system-default' into 'master'
Remove system default theme option on API < 28

Closes #1252

See merge request briar/briar!961
2018-10-24 13:52:20 +00:00
Torsten Grote 825d342f9b Remove system default theme option on API < 27
Closes #1252
2018-10-24 10:40:43 -03:00
Torsten Grote 34955fecbb Fix RTL icon mirroring in DevReportActivity
For some reason, the toolbar icon has a wrong layout direction,
so the autoMirrored attribute doesn't take any effect.
2018-10-22 16:53:17 -03:00
Torsten Grote 5c28b60a6b Log when activities start and stop
Remove BriarRecyclerView log messages
2018-10-22 14:11:36 -03:00
akwizgran 389b2b5b8e Merge branch '1423-check-lifecycle-state' into 'master'
Check lifecycle state before changing fragment

Closes #1423

See merge request briar/briar!958
2018-10-22 14:27:30 +00:00
Torsten Grote 78abfa3698 Check lifecycle state before changing fragment 2018-10-19 16:40:00 -03:00
akwizgran 9c4fb4fd34 Remove unused string. 2018-10-18 17:22:54 +01:00
akwizgran 3d6a336f6d Refactor permissions code, add comments, fix corner cases. 2018-10-18 17:16:49 +01:00
akwizgran e47d41596a Merge branch '1254-inject-object-mapper' into 'master'
briar-headless: Inject a singleton ObjectMapper for JSON parsing

See merge request briar/briar!957
2018-10-18 15:40:20 +00:00
Torsten Grote 8cf54bcedb briar-headless: Inject a singleton ObjectMapper for JSON parsing 2018-10-18 09:55:34 -03:00
akwizgran 89d5145665 Bump version numbers for 1.1.3 release. 2018-10-17 17:51:11 +01:00
Torsten Grote 0706498b03 Merge branch 'upgrade-android-gradle-plugin' into 'master'
Upgrade Android Gradle plugin to 3.2.1.

See merge request briar/briar!956
2018-10-17 16:36:24 +00:00
akwizgran b296500e7a Update translations. 2018-10-17 12:41:24 +01:00
akwizgran 60a8b03344 Upgrade Android Gradle plugin to 3.2.1. 2018-10-17 12:34:13 +01:00
Torsten Grote ae16a93522 Merge branch 'compact-at-startup' into 'master'
Compact the database at startup

See merge request briar/briar!955
2018-10-16 16:02:40 +00:00
Torsten Grote c9a2ff71ae Merge branch 'tor-v3-hidden-service-addresses' into 'master'
Add support for v3 hidden service addresses

See merge request briar/briar!952
2018-10-16 15:55:34 +00:00
akwizgran 16f4c60a56 Add test for compaction time. 2018-10-16 11:39:06 +01:00
akwizgran 76121eb871 Always compact the DB if migrations have been applied. 2018-10-16 11:24:47 +01:00
akwizgran 47c91a96ae Compact the database at startup. 2018-10-16 11:13:37 +01:00
akwizgran 14befb957b Add support for v3 hidden service addresses. 2018-10-16 10:15:18 +01:00
akwizgran 4b7a81177c Static imports. 2018-10-15 14:46:40 +01:00
Torsten Grote b464fe1653 Merge branch 'message-terminology' into 'master'
Use "text" to refer to message text

See merge request briar/briar!948
2018-10-15 13:22:31 +00:00
akwizgran 09c6f09805 Merge branch '1420-tor-status-update' into 'master'
Disable TorPlugin before applying changed settings

Closes #1420

See merge request briar/briar!953
2018-10-15 12:54:41 +00:00
Torsten Grote a93093182d Disable TorPlugin before applying changed settings
The is necessary for two reasons:

1. Since Tor 0.3.4.8, it doesn't reconnect when changing the value of
   UseBridges via the control connection without also resetting
   DisableNetwork
2. The TorPlugin needs to set itself to a disconnected state for the UI
   to properly reflect this new state

Fixes #1420
2018-10-15 09:43:12 -03:00
akwizgran 9515e93857 Cancel discovery after 10 seconds and try to connect. 2018-10-15 11:04:46 +01:00
akwizgran efe15df940 Remove static import of R's fields. 2018-10-15 11:04:46 +01:00
akwizgran de611857cf Discover BT devices if no address is provided. 2018-10-15 11:04:46 +01:00
akwizgran 8935ec2c2e Don't wait for state change if BT is already discoverable. 2018-10-15 11:04:45 +01:00
akwizgran bd00fb1c04 Ask for coarse location permission before adding a contact. 2018-10-15 11:04:45 +01:00
akwizgran 3192015cfd Ask for Bluetooth discoverability before adding a contact. 2018-10-15 11:04:45 +01:00
Torsten Grote e776ee02b0 Merge branch 'tor-0.3.4.8' into 'master'
Upgrade Tor to 0.3.4.8

See merge request briar/briar!951
2018-10-11 22:44:45 +00:00
akwizgran c0553ec11f Upgrade Linux Tor binaries to 0.3.4.8. 2018-10-11 15:05:39 +01:00
akwizgran 75a871a2f8 Upgrade Android Tor binaries to 0.3.4.8. 2018-10-11 14:38:18 +01:00
akwizgran d6d3d5acef Merge branch '1240-no-empty-messages' into 'master'
Don't allow empty message bodies

See merge request briar/briar!949
2018-10-10 14:52:34 +00:00
Torsten Grote a361a2613c Merge branch 'test-configurations' into 'master'
Update test configurations for Android Studio 3.2

See merge request briar/briar!950
2018-10-10 12:38:19 +00:00
akwizgran b68dbd6a75 Merge branch 'upgrade-dependencies' into 'master'
Upgrade some of the things

See merge request briar/briar!935
2018-10-10 11:42:45 +00:00
akwizgran f1e89a3ff4 Don't allow empty message bodies. 2018-10-10 10:57:41 +01:00
akwizgran 056c23167d Update test configurations for Android Studio 3.2. 2018-10-10 10:43:07 +01:00
akwizgran 79d5612645 Use "text" to refer to message text. 2018-10-10 10:40:30 +01:00
akwizgran a030f92275 Merge branch 'headless' into 'master'
Add Briar headless client that exposes a REST API

See merge request briar/briar!931
2018-10-09 15:43:31 +00:00
Torsten Grote b3615b4a77 briar-headless: Last round of review comments 2018-10-09 12:19:21 -03:00
akwizgran 8a15fb242a Merge branch 'briar-integration-test-transaction' into 'master'
Remove custom DB transaction code from BriarIntegrationTest

See merge request briar/briar!946
2018-10-09 14:16:23 +00:00
Torsten Grote e3686186ee Fix closing server with ^C 2018-10-08 18:40:21 -03:00
akwizgran 18ae388137 Merge branch '1395-low-memory-crash' into 'master'
Don't use non-AppCompat theme for AppCompat activities

Closes #1395

See merge request briar/briar!947
2018-10-08 12:03:20 +00:00
Torsten Grote 775031e893 Don't use non-AppCompat theme for AppCompat activities
Fixes #1395
2018-10-05 16:50:11 -03:00
Torsten Grote 9f91b91a4f Remove custom DB transaction code from BriarIntegrationTest 2018-10-05 15:41:29 -03:00
Torsten Grote 280f3ba1fc briar-headless: POST text as JSON in body instead of form parameter 2018-10-05 15:23:31 -03:00
Torsten Grote 66619fd3a4 briar-headless: Next round of review comments 2018-10-05 15:23:31 -03:00
akwizgran c7eb0cbb6d Include body of private request if present. 2018-10-05 15:23:31 -03:00
akwizgran 1617a95bb9 Only include "body" for headers that can have bodies. 2018-10-05 15:23:31 -03:00
Torsten Grote 6f54718756 Use short type labels in JSON API instead of long Java-like namespaces 2018-10-05 15:23:31 -03:00
Torsten Grote ea749f2128 Minor improvements to JsonDict output classes 2018-10-05 15:23:31 -03:00
akwizgran b4b0d3daa6 Allow null values in JsonDict. 2018-10-05 15:23:31 -03:00
akwizgran 609c90f57e Convert Map#put() to assignment. 2018-10-05 15:23:31 -03:00
akwizgran 5cf68fa134 Use JsonDict for blog post headers. 2018-10-05 15:23:31 -03:00
akwizgran 61c9c6b8eb Add visitor to dispatch output() dynamically. 2018-10-05 15:23:31 -03:00
akwizgran e97608da40 Add test to show that static dispatch won't work. 2018-10-05 15:23:31 -03:00
akwizgran 0bb80b1a15 Add JsonDict class for JSON output. 2018-10-05 15:23:31 -03:00
akwizgran bda52ea548 Use maps for JSON output. 2018-10-05 15:23:31 -03:00
Torsten Grote cf033dc29d briar-headless: Address second round of review comments 2018-10-05 15:23:31 -03:00
Torsten Grote c12cedc371 briar-headless: Address first round of review comments 2018-10-05 15:23:31 -03:00
Torsten Grote 4b5e9bd64f Ensure the use SecureRandom when creating authentication token 2018-10-05 15:23:31 -03:00
Torsten Grote 8d55911dab Add unit test for WebSocketController
Also move the controller into an event package
2018-10-05 15:23:31 -03:00
Torsten Grote e381f83512 Last code cleanup before submitting merge request 2018-10-05 15:23:31 -03:00
Torsten Grote e4c7f13832 Add a README.md with API documentation
Also fix some smaller issues found during writing the documentation
2018-10-05 15:23:31 -03:00
Torsten Grote b089a204d3 Add support for websocket authentication via basic auth
The token should be used as username and the password left empty
2018-10-05 15:23:31 -03:00
Torsten Grote 85fcb34997 Add briar-headless Android Studio run configuration 2018-10-05 15:23:31 -03:00
Torsten Grote d6d132a9cf Add Bearer Authentication to REST API 2018-10-05 15:23:31 -03:00
Torsten Grote 98d1ea7730 briar-headless: Add more controller tests
Current controller line coverage: 100%
2018-10-05 15:23:31 -03:00
Torsten Grote 159fd34c0c Use Conversation Manager for message retrieval 2018-10-05 15:23:31 -03:00
Torsten Grote 9e7a387ea4 Turn output classes into Kotlin data classes 2018-10-05 15:23:31 -03:00
Torsten Grote 138e520e6c briar-headless: Add command line arguments 2018-10-05 15:23:31 -03:00
Torsten Grote 5783c1dfd8 briar-headless: Add a websocket controller for private message events
Also version API URLs
2018-10-05 15:23:31 -03:00
Torsten Grote 348968018a Migrate REST classes to Kotlin and upgrade Javalin 2018-10-05 15:23:31 -03:00
Torsten Grote 33c509cd1f briar-headless: Add Kotlin and first unit test for blogs with Mockk 2018-10-05 15:23:31 -03:00
Torsten Grote bea77151bd briar-headless: Add API to list all contacts 2018-10-05 15:23:31 -03:00
Torsten Grote 787e62345f Add simple MessagingController 2018-10-05 15:23:31 -03:00
Torsten Grote 48f6a3b91f Add Tor plugin to headless client and introduce new ConfigurationManager 2018-10-05 15:23:31 -03:00
Torsten Grote a798e25bf2 Save app data always in $HOME/.briar for now 2018-10-05 15:23:31 -03:00
Torsten Grote 31e4045cf7 Try to shutdown cleanly when server stops or SIGINT is received 2018-10-05 15:23:31 -03:00
Torsten Grote 5334a8c9ca Add basic support for listing and writing blog posts 2018-10-05 15:23:31 -03:00
Torsten Grote d11f1d2805 Add a poor man's argument to explicitly turn on verbose logging 2018-10-05 15:23:31 -03:00
Torsten Grote 0d1ebddcd2 Allow account creation and reading password from STDIN 2018-10-05 15:23:31 -03:00
Torsten Grote 6c296c1348 Proof-of-Concept Headless Client 2018-10-05 15:23:31 -03:00
akwizgran 87701e5f07 Merge branch 'transactional-db' into 'master'
Transactional DB interface

See merge request briar/briar!945
2018-10-05 15:19:40 +00:00
Torsten Grote 3aae01d152 Merge branch 'panic-app-list' into 'master'
Update list of panic button apps after installing app

Closes #1392

See merge request briar/briar!940
2018-10-05 14:18:44 +00:00
akwizgran bc298ba68a Remove unnecessary final modifiers. 2018-10-05 09:34:41 +01:00
akwizgran 2623eaa149 Remove unnecessary throwing variants. 2018-10-05 09:32:01 +01:00
akwizgran 7359b6942a Use transactional DB interface for ForumManagerImpl. 2018-10-04 15:59:10 +01:00
akwizgran 3bcc532b4b Add transactional DB interface. 2018-10-04 15:56:21 +01:00
akwizgran 4d08c69779 Revert spurious changes to run configurations. 2018-10-03 13:08:00 +01:00
Torsten Grote a6cd8937f7 Remove space reserved for icons from preferences
Works around https://issuetracker.google.com/issues/111907042

Might be replacable with a solution from
https://issuetracker.google.com/issues/111907042 in the future.
2018-10-03 12:58:49 +01:00
akwizgran e8566906ef Update gradle-witness to exclude android.jar from dependencies. 2018-10-03 12:48:29 +01:00
akwizgran 929102ed60 Upgrade build tools to 28.0.3. 2018-10-03 12:48:29 +01:00
akwizgran 3b871f5932 Update ProGuard rules for new OkHttp version. 2018-10-03 12:48:29 +01:00
akwizgran b972d1fc13 Update ACRA usage for new version. 2018-10-03 12:48:28 +01:00
akwizgran ccbeee60a7 Upgrade Rome, OkHttp and jsoup libraries. 2018-10-03 12:48:28 +01:00
akwizgran 074b10e177 Upgrade JNA library. 2018-10-03 12:48:28 +01:00
akwizgran 031516ccce Upgrade curve25519-java library. 2018-10-03 12:48:28 +01:00
akwizgran 7d2f1abb94 Upgrade Gradle APT and Animal Sniffer plugins. 2018-10-03 12:48:28 +01:00
akwizgran 00b9c76bb8 Upgrade ACRA. 2018-10-03 12:48:28 +01:00
akwizgran 4d9fab85cb Upgrade zxing, material tap target libraries. 2018-10-03 12:48:28 +01:00
akwizgran bd2514a299 Upgrade support library to 28.0.0. 2018-10-03 12:48:27 +01:00
akwizgran e795efc7fc Bump compileSdkVersion for bramble-android. 2018-10-03 12:48:27 +01:00
akwizgran 6691d2164f Upgrade Gradle Android plugin and build tools. 2018-10-03 12:48:27 +01:00
Administrator a384450c36 Merge branch '1373-format-numbers' into 'master'
Format numbers in locale as well (not all languages use the same)

See merge request briar/briar!943
2018-10-03 11:41:56 +00:00
akwizgran b375e9873c Merge branch '1409-localize-crash-screen' into 'master'
Localize crash screen in language defined in settings

Closes #1409

See merge request briar/briar!944
2018-10-03 07:53:41 +00:00
Torsten Grote cb30c3885a Localize crash screen in language defined in settings 2018-10-02 17:56:33 -03:00
Torsten Grote 6ee81eb24c Format numbers in locale as well (not all languages use the same)
Done according to
https://developer.android.com/training/basics/supporting-devices/languages#FormatNumbers
2018-10-02 17:31:23 -03:00
Torsten Grote c14ebe82ce Merge branch '1365-keep-screen-on' into 'master'
Keep screen on while QR code viewfinder is open

See merge request briar/briar!942
2018-10-02 11:20:46 +00:00
Torsten Grote 00e9f894b1 Merge branch 'remove-tor-patch' into 'master'
Remove unused patches

See merge request briar/briar!941
2018-10-02 11:13:06 +00:00
akwizgran 499c586a59 Keep screen on while scanning QR code. 2018-10-02 12:03:29 +01:00
akwizgran 64f9ce7306 Remove unused patches. 2018-10-02 11:49:29 +01:00
akwizgran 39478a7914 Bump version numbers for 1.1.2 release. 2018-10-01 14:58:45 +01:00
akwizgran 112e71a9cb Bump version numbers for 1.0.2 release. 2018-10-01 14:56:08 +01:00
akwizgran 5650bef310 Update translations. 2018-10-01 14:56:08 +01:00
akwizgran 2a87171c49 Merge branch 'manual-screenshots' into 'master'
Create Screenshot of Conversation for Manual

Closes #1377

See merge request briar/briar!910
2018-10-01 13:41:05 +00:00
akwizgran 071d961ed1 Remove debug logging. 2018-09-28 11:31:22 +01:00
akwizgran cb9efc5fec Fix lint warnings. 2018-09-28 11:28:47 +01:00
akwizgran f9e292f734 Update panic app list after installing app. 2018-09-28 11:27:08 +01:00
akwizgran 15cb5409e7 Merge branch '1352-panic-ripple-fdroid' into 'master'
Fix Panic Button bugs

Closes #1109 and #1352

See merge request briar/briar!937
2018-09-28 09:57:18 +00:00
akwizgran fd07dc006d Update comment. 2018-09-28 09:55:47 +01:00
akwizgran cc87c4e37d Merge branch '1391-start-end-api15' into 'master'
RTL language layout fixes

Closes #1391

See merge request briar/briar!938
2018-09-28 08:45:17 +00:00
akwizgran 4a10e876f6 Merge branch '1389-notice-shadows' into 'master'
Fix notice shadows

Closes #1389

See merge request briar/briar!939
2018-09-28 08:43:06 +00:00
Torsten Grote fad0057c4a Fix notice shadows 2018-09-27 20:32:13 -03:00
Torsten Grote 5aabfcea9a Unmirror checkboxes in RTL layouts 2018-09-27 19:09:08 -03:00
Torsten Grote f7d928c774 Fix start/end margins for API 15
Fixes #1391
2018-09-27 19:07:13 -03:00
Torsten Grote bd983d9796 Remove non-functional uninstall panic action
Fixes #1109
2018-09-27 18:37:57 -03:00
Torsten Grote de8d1b7d96 Allow sign out by trusted non-paired panic apps 2018-09-27 18:25:31 -03:00
Torsten Grote 9155f62d0b Remove Amnesty International's key and add F-Droid Ripple key instead
Fixes #1352
2018-09-27 18:17:14 -03:00
akwizgran 86684e228a Merge branch 'slow-bridges' into 'master'
Update bridge list, test for slow bridges

See merge request briar/briar!936
2018-09-27 16:10:22 +00:00
akwizgran 9615eff649 Add new bridges to replace slow ones. 2018-09-27 16:11:52 +01:00
akwizgran 9381d46f51 Remove two bridges that are slow to bootstrap. 2018-09-27 16:08:14 +01:00
akwizgran e4a3a1ad40 Delete Tor state after testing each bridge. 2018-09-27 16:07:46 +01:00
akwizgran 905dc2a662 Merge branch 'qr-code-version-errors' into 'master'
Show different error message if QR code is too new

See merge request briar/briar!934
2018-09-24 16:42:43 +00:00
Torsten Grote c2b7f85b8e Remove code from TestDataCreator that breaks encapsulation 2018-09-24 12:37:11 -03:00
Torsten Grote ae81eb3737 Throw AssertionError when creating an account while a database key is in memory 2018-09-24 12:37:11 -03:00
Torsten Grote 60d949c342 Refactor tests so that all test data is created in the first test 2018-09-24 12:37:11 -03:00
Torsten Grote 1c90e64894 Split up UI and Screenshot tests
Closes #1377
2018-09-24 12:37:06 -03:00
Torsten Grote f0e2d5281f Create Screenshot of Conversation for Manual 2018-09-24 12:34:26 -03:00
akwizgran c7522dae1f Show different error message if QR code is too new. 2018-09-24 13:21:45 +01:00
Torsten Grote 097d14b9a1 Merge branch 'private-message-visitor' into 'master'
Use visitor pattern to create conversation items

See merge request briar/briar!933
2018-09-20 19:04:14 +00:00
akwizgran 0491c3cace Use a visitor to create ConversationItems. 2018-09-20 16:53:48 +01:00
akwizgran cbae13feca Merge branch 'gradle-4.10' into 'master'
Upgrade the gradle wrapper to version 4.10.2

See merge request briar/briar!932
2018-09-20 15:34:33 +00:00
Torsten Grote b7c8859c82 Upgrade the gradle wrapper to version 4.10.2 2018-09-20 11:52:19 -03:00
akwizgran 2e120f752c Add parameterised return type. 2018-09-20 15:19:22 +01:00
akwizgran 031eac54c5 Add private message visitor. 2018-09-20 14:43:19 +01:00
akwizgran 2c2596afdd Merge branch 'conversation-manager' into 'master'
Use ConversationManager for private message retrieval

See merge request briar/briar!912
2018-09-20 13:01:53 +00:00
akwizgran d1be14effe Merge branch '1386-app-lock-after-signout' into 'master'
Fix app lock after sign-out bug

Closes #1386

See merge request briar/briar!930
2018-09-20 11:05:37 +00:00
akwizgran b56e7ab07d Merge branch 'roboelectric-android-http-client' into 'master'
Remove AndroidHttpClient class after Roboelectric update

See merge request briar/briar!929
2018-09-20 11:04:52 +00:00
akwizgran 089e9589ed Merge branch '1378-rtl-support' into 'master'
Add support for right-to-left languages

Closes #1378, #1076, #1078, #964, #1080, and #1079

See merge request briar/briar!918
2018-09-20 10:59:44 +00:00
Torsten Grote 660ba16a14 Fix app lock after sign-out bug
It some cases, it was observered how the app was locked after the user
had signed out.
This commit ensures that set alarms are canceled and that no new ones
will be set after the LockManager service has been stopped.

Fixes #1386
2018-09-19 16:06:13 -03:00
Torsten Grote b101c4b636 Remove AndroidHttpClient class after Roboelectric update 2018-09-19 15:15:38 -03:00
Torsten Grote fdfddd2667 Fix small RTL UI glitches in blog post layouts 2018-09-19 14:56:45 -03:00
akwizgran 296546544f Remove auto-generated layout IDs. 2018-09-19 17:42:25 +01:00
akwizgran ad579a6ba3 Restore max of 50 contacts. 2018-09-19 17:42:09 +01:00
Torsten Grote 90e82357ba Move back to previous way of creating at least one test contact 2018-09-19 11:38:00 -03:00
Torsten Grote b3b40753d8 RTL support: Address review issues 2018-09-19 11:33:03 -03:00
Torsten Grote e60df3cece Don't crash when creating test data with 0 contacts
If no contacts exist, at least one will be created
2018-09-19 11:33:03 -03:00
Torsten Grote da3cb95151 Move TrustIndicator behind date in AuthorView
to prevent it from being pushed off-screen

Fixes #1076
2018-09-19 11:33:03 -03:00
Torsten Grote c27885072f Ellipzise long contact names in ConversationActivity
Fixes #1078
2018-09-19 11:33:03 -03:00
Torsten Grote 6557d564c9 Add RTL support to remaining layouts 2018-09-19 11:33:03 -03:00
Torsten Grote 53edcaf3e9 Add RTL support to remaining list items
Also fixes several small UI glitches with long texts
2018-09-19 11:33:03 -03:00
Torsten Grote 5122c961b4 Simplify dev reporter and add RTL support 2018-09-19 11:33:03 -03:00
Torsten Grote f83b9244d4 Clean up threaded discussion screen
Adds RTL support
Fixing cropping bug

Closes #964
2018-09-19 11:33:03 -03:00
Torsten Grote 81292967e0 Add RTL support to conversation message bubbles 2018-09-19 11:33:03 -03:00
Torsten Grote b72f6b4fc3 Migrate Introduction Screen to ConstraintLayout
Adds RTL support
Fixes issue with long contact names

Closes #1080
2018-09-19 11:33:03 -03:00
Torsten Grote 488be49c93 Convert contact lists to ConstraintLayout
Adds support for RTL languages
Fixes issues with long contact names

Closes #1079
2018-09-19 11:33:03 -03:00
Torsten Grote 90db45817a Add RTL language support to all activities and fragments 2018-09-19 11:33:03 -03:00
akwizgran 81863b9db6 Merge branch '1248-rename-lock-app' into 'master'
Rename "Screen lock" to "Lock app"

Closes #1248 and #1245

See merge request briar/briar!924
2018-09-19 14:28:34 +00:00
akwizgran da069adb57 Merge branch '1186-remove-lock-screen-notification-setting' into 'master'
Remove lockscreen notification setting

Closes #1186

See merge request briar/briar!925
2018-09-19 14:27:31 +00:00
Torsten Grote 46425b09fa Rename "Screen lock" to "App lock" 2018-09-19 10:22:43 -03:00
akwizgran 41e1a436c9 Merge branch 'centre-decrypting-db-message' into 'master'
Align "decrypting database" message to centre

See merge request briar/briar!926
2018-09-19 11:46:55 +00:00
Torsten Grote 989394d18b Merge branch 'fingerprint-permission' into 'master'
Add obsolete fingerprint permission to satisfy Android Studio

See merge request briar/briar!927
2018-09-19 11:32:58 +00:00
akwizgran b6b3f9c292 Align "decrypting database" message to centre. 2018-09-19 12:23:13 +01:00
akwizgran a52547f73b Add obsolete fingerprint permission. 2018-09-19 12:19:33 +01:00
akwizgran 24f823a3ce Remove lock screen notification setting. 2018-09-19 10:50:46 +01:00
Torsten Grote 7d479063a9 ConversationManager: Address review issues 2018-09-18 10:10:21 -03:00
Torsten Grote 2309e73216 Fix bug where available invitations were marked answered
Now an invitiation was answered when it is no longer available
2018-09-18 10:10:21 -03:00
akwizgran 4b325f797b Combine LiveData observers, avoid redundant loads. 2018-09-18 10:10:21 -03:00
Torsten Grote 9be83c3cc7 Refactor ConversationItem creation 2018-09-18 10:10:21 -03:00
Torsten Grote 86f650503b Re-introduce InvitationResponse
This was done, so private responses don't need to include a Nameable already.
Retreiving a nameable is tricky and requires a data migration,
so we just don't do it now.
2018-09-18 10:10:21 -03:00
Torsten Grote d430b4fd2d Move introduction role into IntroductionResponse 2018-09-18 10:10:21 -03:00
akwizgran fcf7cf72ea Refactor doesExist() method. 2018-09-18 10:10:21 -03:00
Torsten Grote b78dfea95f Remove ListenableFutureTask and replace it with LiveData 2018-09-18 10:10:21 -03:00
Torsten Grote 183fe08565 Rename object to nameable 2018-09-18 10:10:21 -03:00
Torsten Grote 7e32697696 Use ConversationManager to retrieve messages
This removes the public method for retrieving messages
from individual conversation clients
and just leaves methods that require a transaction
to be used by the ConversationManager only.
2018-09-18 10:10:21 -03:00
Torsten Grote 29758b174a Unify all events related to private messages 2018-09-18 10:10:21 -03:00
Torsten Grote 61e18f104e Unify all private message responses in one PrivateResponse class
This also adds `Shareable`s to invitation response
which is a precondition for #561
2018-09-18 10:10:21 -03:00
Torsten Grote ffeca8817f Prepare private message retrieval through ConversationManager 2018-09-18 10:10:21 -03:00
Torsten Grote 59fae2fa3c Unify all private message requests in one PrivateRequest class 2018-09-18 10:10:21 -03:00
Torsten Grote 2d9345c018 Remove unnecessary information from private message classes 2018-09-18 10:10:21 -03:00
1365 changed files with 54950 additions and 20857 deletions
+7 -1
View File
@@ -1,6 +1,11 @@
image: briar/ci-image-android:latest
stages:
- test
- check_reproducibility
test:
stage: test
before_script:
- set -e
- export GRADLE_USER_HOME=$PWD/.gradle
@@ -12,7 +17,7 @@ test:
script:
- ./gradlew --no-daemon -Djava.security.egd=file:/dev/urandom animalSnifferMain animalSnifferTest
- ./gradlew --no-daemon -Djava.security.egd=file:/dev/urandom test
- ./gradlew --no-daemon -Djava.security.egd=file:/dev/urandom check compileOfficialDebugAndroidTestSources compileScreenshotDebugAndroidTestSources
after_script:
# these file change every time but should not be cached
@@ -21,6 +26,7 @@ test:
test_reproducible:
stage: check_reproducibility
script:
- "curl -X POST -F token=${RELEASE_CHECK_TOKEN} -F ref=master -F variables[RELEASE_TAG]=${CI_COMMIT_REF_NAME} https://code.briarproject.org/api/v4/projects/61/trigger/pipeline"
only:
+23 -90
View File
@@ -1,16 +1,10 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<option name="RIGHT_MARGIN" value="100" />
<AndroidXmlCodeStyleSettings>
<option name="USE_CUSTOM_SETTINGS" value="true" />
<option name="ARRANGEMENT_SETTINGS_MIGRATED_TO_191" value="true" />
</AndroidXmlCodeStyleSettings>
<JavaCodeStyleSettings>
<option name="ANNOTATION_PARAMETER_WRAP" value="1" />
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
<value />
</option>
<option name="IMPORT_LAYOUT_TABLE">
<value>
<package name="android" withSubpackages="true" static="false" />
@@ -36,31 +30,9 @@
<option name="JD_ALIGN_PARAM_COMMENTS" value="false" />
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" />
</JavaCodeStyleSettings>
<Objective-C-extensions>
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="h" fileNamingConvention="NONE" />
<pair source="c" header="h" fileNamingConvention="NONE" />
</extensions>
</Objective-C-extensions>
<JetCodeStyleSettings>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<XML>
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
</XML>
@@ -99,7 +71,6 @@
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="XML">
<option name="FORCE_REARRANGE_MODE" value="1" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="true" />
@@ -112,7 +83,8 @@
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_NAMESPACE>Namespace:</XML_NAMESPACE>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
@@ -122,7 +94,8 @@
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_NAMESPACE>Namespace:</XML_NAMESPACE>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
@@ -133,6 +106,7 @@
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
@@ -143,6 +117,7 @@
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
@@ -153,6 +128,7 @@
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
@@ -163,6 +139,7 @@
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
@@ -173,6 +150,7 @@
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
@@ -183,64 +161,12 @@
<rule>
<match>
<AND>
<NAME>.*:layout_width</NAME>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_height</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_.*</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:width</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:height</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
@@ -248,6 +174,7 @@
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
@@ -257,5 +184,11 @@
</rules>
</arrangement>
</codeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
<option name="PARAMETER_ANNOTATION_WRAP" value="1" />
<option name="VARIABLE_ANNOTATION_WRAP" value="1" />
<option name="ENUM_CONSTANTS_WRAP" value="1" />
</codeStyleSettings>
</code_scheme>
</component>
+4 -13
View File
@@ -1,29 +1,20 @@
<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="WORKING_DIRECTORY" value="$PROJECT_DIR$/briar-android" />
<method v="2">
<option name="Android.Gradle.BeforeRunTask" enabled="true" />
<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-android" run_configuration_type="AndroidJUnit" />
<option name="RunConfigurationTask" enabled="true" run_configuration_name="All tests in bramble-java" run_configuration_type="AndroidJUnit" />
<option name="RunConfigurationTask" enabled="true" run_configuration_name="All tests in briar-core" run_configuration_type="AndroidJUnit" />
<option name="RunConfigurationTask" enabled="true" run_configuration_name="All tests in briar-headless" run_configuration_type="AndroidJUnit" />
</method>
</configuration>
</component>
@@ -1,6 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All tests in bramble-android" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="bramble-android" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
@@ -11,12 +10,10 @@
<option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/bramble-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>
-3
View File
@@ -1,6 +1,5 @@
<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" />
@@ -11,12 +10,10 @@
<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>
-3
View File
@@ -1,6 +1,5 @@
<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" />
@@ -11,12 +10,10 @@
<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>
-3
View File
@@ -1,6 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All tests in bramble-java" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="bramble-java" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
@@ -11,12 +10,10 @@
<option name="VM_PARAMETERS" value="-ea -Djava.library.path=libs" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/bramble-java" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<envs />
<patterns />
<method />
</configuration>
-3
View File
@@ -1,6 +1,5 @@
<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" />
@@ -11,12 +10,10 @@
<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>
-3
View File
@@ -1,6 +1,5 @@
<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" />
@@ -11,12 +10,10 @@
<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>
+15
View File
@@ -0,0 +1,15 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All tests in briar-headless" type="AndroidJUnit" factoryName="Android JUnit">
<module name="briar-headless" />
<option name="PACKAGE_NAME" value="org.briarproject.briar.headless" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="package" />
<option name="VM_PARAMETERS" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/briar-headless" />
<method v="2">
<option name="Android.Gradle.BeforeRunTask" enabled="true" />
</method>
</configuration>
</component>
-3
View File
@@ -1,6 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="H2 Performance Test" 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" />
@@ -11,12 +10,10 @@
<option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<envs />
<patterns />
<method />
</configuration>
-3
View File
@@ -1,6 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="HyperSQL Performance Test" 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" />
@@ -11,12 +10,10 @@
<option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<envs />
<patterns />
<method />
</configuration>
+17
View File
@@ -0,0 +1,17 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="briar-headless" type="JetRunConfigurationType" factoryName="Kotlin" singleton="true">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<option name="VM_PARAMETERS" value="" />
<option name="PROGRAM_PARAMETERS" value="-v" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="MAIN_CLASS_NAME" value="org.briarproject.briar.headless.MainKt" />
<option name="WORKING_DIRECTORY" value="" />
<module name="briar-headless" />
<envs />
<method>
<option name="Gradle.BeforeRunTask" enabled="true" tasks="jar" externalProjectPath="$PROJECT_DIR$/briar-headless" vmOptions="" scriptParameters="" />
</method>
</configuration>
</component>
+44 -15
View File
@@ -1,25 +1,35 @@
import com.android.build.gradle.tasks.MergeResources
apply plugin: 'com.android.library'
apply plugin: 'witness'
apply from: 'witness.gradle'
android {
compileSdkVersion 27
buildToolsVersion '27.0.3'
compileSdkVersion 29
buildToolsVersion '29.0.2'
defaultConfig {
minSdkVersion 14
targetSdkVersion 26
versionCode 10101
versionName "1.1.1"
minSdkVersion 16
targetSdkVersion 28
versionCode 10207
versionName "1.2.7"
consumerProguardFiles 'proguard-rules.txt'
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
lintOptions {
// FIXME
warning "LintError"
warning "InvalidPackage"
warning "MissingPermission"
warning "InlinedApi", "ObsoleteSdkInt", "Override", "NewApi", "UnusedAttribute"
}
}
configurations {
@@ -28,9 +38,10 @@ configurations {
dependencies {
implementation project(path: ':bramble-core', configuration: 'default')
tor 'org.briarproject:tor-android:0.2.9.16@zip'
tor 'org.briarproject:tor-android:0.3.5.9@zip'
tor 'org.briarproject:obfs4proxy-android:0.0.11-2@zip'
annotationProcessor 'com.google.dagger:dagger-compiler:2.0.2'
annotationProcessor 'com.google.dagger:dagger-compiler:2.24'
compileOnly 'javax.annotation:jsr250-api:1.0'
@@ -39,13 +50,31 @@ dependencies {
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"
}
project.afterEvaluate {
copy {
from configurations.tor.collect { zipTree(it) }
into 'src/main/res/raw'
def torBinariesDir = 'src/main/res/raw'
task cleanTorBinaries {
doLast {
delete fileTree(torBinariesDir) { include '*.zip' }
}
}
clean.dependsOn cleanTorBinaries
task unpackTorBinaries {
doLast {
copy {
from configurations.tor.collect { zipTree(it) }
into torBinariesDir
// TODO: Remove after next Tor upgrade, which won't include non-PIE binaries
include 'geoip.zip', '*_pie.zip'
}
}
dependsOn cleanTorBinaries
}
tasks.withType(MergeResources) {
inputs.dir torBinariesDir
dependsOn unpackTorBinaries
}
@@ -0,0 +1,24 @@
package org.briarproject.bramble;
import org.briarproject.bramble.battery.AndroidBatteryModule;
import org.briarproject.bramble.network.AndroidNetworkModule;
import org.briarproject.bramble.reporting.ReportingModule;
public interface BrambleAndroidEagerSingletons {
void inject(AndroidBatteryModule.EagerSingletons init);
void inject(AndroidNetworkModule.EagerSingletons init);
void inject(ReportingModule.EagerSingletons init);
class Helper {
public static void injectEagerSingletons(
BrambleAndroidEagerSingletons c) {
c.inject(new AndroidBatteryModule.EagerSingletons());
c.inject(new AndroidNetworkModule.EagerSingletons());
c.inject(new ReportingModule.EagerSingletons());
}
}
}
@@ -1,16 +1,21 @@
package org.briarproject.bramble;
import org.briarproject.bramble.battery.AndroidBatteryModule;
import org.briarproject.bramble.network.AndroidNetworkModule;
import org.briarproject.bramble.plugin.tor.CircumventionModule;
import org.briarproject.bramble.reporting.ReportingModule;
import org.briarproject.bramble.socks.SocksModule;
import org.briarproject.bramble.system.AndroidSystemModule;
import dagger.Module;
@Module(includes = {
AndroidBatteryModule.class,
AndroidNetworkModule.class,
AndroidSystemModule.class,
CircumventionModule.class
CircumventionModule.class,
ReportingModule.class,
SocksModule.class
})
public class BrambleAndroidModule {
}
@@ -9,21 +9,34 @@ import org.briarproject.bramble.api.account.AccountManager;
import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.db.DatabaseConfig;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.util.IoUtils;
import java.io.File;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;
import javax.inject.Inject;
import static android.os.Build.VERSION.SDK_INT;
import static java.util.Arrays.asList;
import static java.util.logging.Level.INFO;
import static org.briarproject.bramble.util.IoUtils.deleteFileOrDir;
import static org.briarproject.bramble.util.LogUtils.logFileOrDir;
class AndroidAccountManager extends AccountManagerImpl
implements AccountManager {
private static final Logger LOG =
Logger.getLogger(AndroidAccountManager.class.getName());
private static final String PREF_DB_KEY = "key";
/**
* Directories that shouldn't be deleted when deleting the user's account.
*/
private static final List<String> PROTECTED_DIR_NAMES =
asList("cache", "code_cache", "lib", "shared_prefs");
protected final Context appContext;
private final SharedPreferences prefs;
@@ -37,42 +50,30 @@ class AndroidAccountManager extends AccountManagerImpl
appContext = app.getApplicationContext();
}
// Locking: stateChangeLock
@Override
@Nullable
protected String loadEncryptedDatabaseKey() {
String key = getDatabaseKeyFromPreferences();
if (key == null) key = super.loadEncryptedDatabaseKey();
else migrateDatabaseKeyToFile(key);
return key;
}
// Locking: stateChangeLock
@Nullable
private String getDatabaseKeyFromPreferences() {
String key = prefs.getString(PREF_DB_KEY, null);
if (key == null) LOG.info("No database key in preferences");
else LOG.info("Found database key in preferences");
return key;
}
// Locking: stateChangeLock
private void migrateDatabaseKeyToFile(String key) {
if (storeEncryptedDatabaseKey(key)) {
if (prefs.edit().remove(PREF_DB_KEY).commit())
LOG.info("Database key migrated to file");
else LOG.warning("Database key not removed from preferences");
} else {
LOG.warning("Database key not migrated to file");
public boolean accountExists() {
boolean exists = super.accountExists();
if (!exists && LOG.isLoggable(INFO)) {
LOG.info("Account does not exist. Contents of account directory:");
logFileOrDir(LOG, INFO, getDataDir());
}
return exists;
}
@Override
public void deleteAccount() {
synchronized (stateChangeLock) {
if (LOG.isLoggable(INFO)) {
LOG.info("Contents of account directory before deleting:");
logFileOrDir(LOG, INFO, getDataDir());
}
super.deleteAccount();
SharedPreferences defaultPrefs = getDefaultSharedPreferences();
deleteAppData(prefs, defaultPrefs);
if (LOG.isLoggable(INFO)) {
LOG.info("Contents of account directory after deleting:");
logFileOrDir(LOG, INFO, getDataDir());
}
}
}
@@ -81,28 +82,56 @@ class AndroidAccountManager extends AccountManagerImpl
return PreferenceManager.getDefaultSharedPreferences(appContext);
}
// Locking: stateChangeLock
@GuardedBy("stateChangeLock")
private void deleteAppData(SharedPreferences... clear) {
// Clear and commit shared preferences
for (SharedPreferences prefs : clear) {
if (!prefs.edit().clear().commit())
LOG.warning("Could not clear shared preferences");
}
// Delete files, except lib and shared_prefs directories
File dataDir = new File(appContext.getApplicationInfo().dataDir);
File[] children = dataDir.listFiles();
if (children == null) {
// Delete files, except protected directories
Set<File> files = new HashSet<>();
File dataDir = getDataDir();
@Nullable
File[] fileArray = dataDir.listFiles();
if (fileArray == null) {
LOG.warning("Could not list files in app data dir");
} else {
for (File child : children) {
String name = child.getName();
if (!name.equals("lib") && !name.equals("shared_prefs")) {
IoUtils.deleteFileOrDir(child);
for (File file : fileArray) {
if (!PROTECTED_DIR_NAMES.contains(file.getName())) {
files.add(file);
}
}
}
// Recreate the cache dir as some OpenGL drivers expect it to exist
if (!new File(dataDir, "cache").mkdir())
LOG.warning("Could not recreate cache dir");
files.add(appContext.getFilesDir());
addIfNotNull(files, appContext.getExternalCacheDir());
if (SDK_INT >= 19) {
for (File file : appContext.getExternalCacheDirs()) {
addIfNotNull(files, file);
}
}
if (SDK_INT >= 21) {
for (File file : appContext.getExternalMediaDirs()) {
addIfNotNull(files, file);
}
}
// Clear the cache directory but don't delete it
File cacheDir = appContext.getCacheDir();
File[] children = cacheDir.listFiles();
if (children != null) files.addAll(asList(children));
for (File file : files) {
if (LOG.isLoggable(INFO)) {
LOG.info("Deleting " + file.getAbsolutePath());
}
deleteFileOrDir(file);
}
}
private File getDataDir() {
return new File(appContext.getApplicationInfo().dataDir);
}
private void addIfNotNull(Set<File> files, @Nullable File file) {
if (file != null) files.add(file);
}
}
@@ -0,0 +1,81 @@
package org.briarproject.bramble.battery;
import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import org.briarproject.bramble.api.battery.BatteryManager;
import org.briarproject.bramble.api.battery.event.BatteryEvent;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.lifecycle.Service;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Logger;
import javax.inject.Inject;
import static android.content.Intent.ACTION_BATTERY_CHANGED;
import static android.content.Intent.ACTION_POWER_CONNECTED;
import static android.content.Intent.ACTION_POWER_DISCONNECTED;
import static android.os.BatteryManager.EXTRA_PLUGGED;
import static java.util.logging.Level.INFO;
import static java.util.logging.Logger.getLogger;
class AndroidBatteryManager implements BatteryManager, Service {
private static final Logger LOG =
getLogger(AndroidBatteryManager.class.getName());
private final Context appContext;
private final EventBus eventBus;
private final AtomicBoolean used = new AtomicBoolean(false);
private volatile BroadcastReceiver batteryReceiver = null;
@Inject
AndroidBatteryManager(Application app, EventBus eventBus) {
this.appContext = app.getApplicationContext();
this.eventBus = eventBus;
}
@Override
public boolean isCharging() {
// Get the sticky intent for ACTION_BATTERY_CHANGED
IntentFilter filter = new IntentFilter(ACTION_BATTERY_CHANGED);
Intent i = appContext.registerReceiver(null, filter);
if (i == null) return false;
int status = i.getIntExtra(EXTRA_PLUGGED, 0);
return status != 0;
}
@Override
public void startService() {
if (used.getAndSet(true)) throw new IllegalStateException();
batteryReceiver = new BatteryReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_POWER_CONNECTED);
filter.addAction(ACTION_POWER_DISCONNECTED);
appContext.registerReceiver(batteryReceiver, filter);
}
@Override
public void stopService() {
if (batteryReceiver != null)
appContext.unregisterReceiver(batteryReceiver);
}
private class BatteryReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context ctx, Intent i) {
String action = i.getAction();
if (LOG.isLoggable(INFO)) LOG.info("Received broadcast " + action);
if (ACTION_POWER_CONNECTED.equals(action))
eventBus.broadcast(new BatteryEvent(true));
else if (ACTION_POWER_DISCONNECTED.equals(action))
eventBus.broadcast(new BatteryEvent(false));
}
}
}
@@ -0,0 +1,27 @@
package org.briarproject.bramble.battery;
import org.briarproject.bramble.api.battery.BatteryManager;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import javax.inject.Inject;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
@Module
public class AndroidBatteryModule {
public static class EagerSingletons {
@Inject
BatteryManager batteryManager;
}
@Provides
@Singleton
BatteryManager provideBatteryManager(LifecycleManager lifecycleManager,
AndroidBatteryManager batteryManager) {
lifecycleManager.registerService(batteryManager);
return batteryManager;
}
}
@@ -32,6 +32,7 @@ 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.net.wifi.p2p.WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION;
import static android.os.Build.VERSION.SDK_INT;
import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED;
import static java.util.concurrent.TimeUnit.MINUTES;
@@ -76,9 +77,9 @@ class AndroidNetworkManager implements NetworkManager, Service {
filter.addAction(ACTION_SCREEN_ON);
filter.addAction(ACTION_SCREEN_OFF);
filter.addAction(WIFI_AP_STATE_CHANGED_ACTION);
filter.addAction(WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
if (SDK_INT >= 23) filter.addAction(ACTION_DEVICE_IDLE_MODE_CHANGED);
appContext.registerReceiver(networkStateReceiver, filter);
}
@Override
@@ -136,7 +137,8 @@ class AndroidNetworkManager implements NetworkManager, Service {
}
private boolean isApEvent(@Nullable String action) {
return WIFI_AP_STATE_CHANGED_ACTION.equals(action);
return WIFI_AP_STATE_CHANGED_ACTION.equals(action) ||
WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action);
}
}
}
@@ -3,6 +3,7 @@ package org.briarproject.bramble.network;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.network.NetworkManager;
import javax.inject.Inject;
import javax.inject.Singleton;
import dagger.Module;
@@ -11,6 +12,11 @@ import dagger.Provides;
@Module
public class AndroidNetworkModule {
public static class EagerSingletons {
@Inject
NetworkManager networkManager;
}
@Provides
@Singleton
NetworkManager provideNetworkManager(LifecycleManager lifecycleManager,
@@ -8,26 +8,45 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.ParcelUuid;
import android.os.Parcelable;
import org.briarproject.bramble.api.Pair;
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.DiscoveryHandler;
import org.briarproject.bramble.api.plugin.PluginCallback;
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.properties.TransportProperties;
import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.util.AndroidUtils;
import org.briarproject.bramble.util.IoUtils;
import java.io.Closeable;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.UUID;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import static android.bluetooth.BluetoothAdapter.ACTION_DISCOVERY_FINISHED;
import static android.bluetooth.BluetoothAdapter.ACTION_DISCOVERY_STARTED;
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;
@@ -37,18 +56,41 @@ import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERA
import static android.bluetooth.BluetoothAdapter.SCAN_MODE_NONE;
import static android.bluetooth.BluetoothAdapter.STATE_OFF;
import static android.bluetooth.BluetoothAdapter.STATE_ON;
import static android.bluetooth.BluetoothDevice.ACTION_FOUND;
import static android.bluetooth.BluetoothDevice.ACTION_UUID;
import static android.bluetooth.BluetoothDevice.DEVICE_TYPE_LE;
import static android.bluetooth.BluetoothDevice.EXTRA_DEVICE;
import static android.bluetooth.BluetoothDevice.EXTRA_UUID;
import static android.os.Build.VERSION.SDK_INT;
import static java.nio.ByteOrder.LITTLE_ENDIAN;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.Collections.shuffle;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
import static org.briarproject.bramble.api.plugin.BluetoothConstants.PROP_ADDRESS;
import static org.briarproject.bramble.api.plugin.BluetoothConstants.PROP_UUID;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress;
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
private static final Logger LOG =
Logger.getLogger(AndroidBluetoothPlugin.class.getName());
getLogger(AndroidBluetoothPlugin.class.getName());
private static final int MIN_DEVICE_DISCOVERY_MS = 2_000;
private static final int MAX_DEVICE_DISCOVERY_MS = 30_000;
private static final int MAX_SERVICE_DISCOVERY_MS = 15_000;
private final AndroidExecutor androidExecutor;
private final Context appContext;
private final Clock clock;
private volatile boolean wasEnabledByUs = false;
private volatile BluetoothStateReceiver receiver = null;
@@ -58,12 +100,13 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
AndroidBluetoothPlugin(BluetoothConnectionLimiter connectionLimiter,
Executor ioExecutor, AndroidExecutor androidExecutor,
Context appContext, SecureRandom secureRandom, Backoff backoff,
DuplexPluginCallback callback, int maxLatency) {
Context appContext, SecureRandom secureRandom, Clock clock,
Backoff backoff, PluginCallback callback, int maxLatency) {
super(connectionLimiter, ioExecutor, secureRandom, backoff, callback,
maxLatency);
this.androidExecutor = androidExecutor;
this.appContext = appContext;
this.clock = clock;
}
@Override
@@ -117,17 +160,42 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
@Override
void disableAdapterIfEnabledByUs() {
if (isAdapterEnabled() && wasEnabledByUs) {
cancelDiscoverability();
if (adapter.disable()) LOG.info("Disabling Bluetooth");
else LOG.info("Could not disable Bluetooth");
wasEnabledByUs = false;
}
}
private void cancelDiscoverability() {
if (adapter.getScanMode() == SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
try {
Method setDiscoverableTimeout = BluetoothAdapter.class
.getDeclaredMethod("setDiscoverableTimeout", int.class);
setDiscoverableTimeout.setAccessible(true);
setDiscoverableTimeout.invoke(adapter, 1);
LOG.info("Cancelled discoverability");
} catch (NoSuchMethodException e) {
logException(LOG, WARNING, e);
} catch (IllegalAccessException e) {
logException(LOG, WARNING, e);
} catch (InvocationTargetException e) {
logException(LOG, WARNING, e);
}
}
}
@Override
void setEnabledByUs() {
wasEnabledByUs = true;
}
@Override
void onAdapterDisabled() {
super.onAdapterDisabled();
wasEnabledByUs = false;
}
@Override
@Nullable
String getBluetoothAddress() {
@@ -143,11 +211,7 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
@Override
void tryToClose(@Nullable BluetoothServerSocket ss) {
try {
if (ss != null) ss.close();
} catch (IOException e) {
logException(LOG, WARNING, e);
}
IoUtils.tryToClose(ss, LOG, WARNING);
}
@Override
@@ -177,18 +241,267 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
s.connect();
return wrapSocket(s);
} catch (IOException e) {
tryToClose(s);
IoUtils.tryToClose(s, LOG, WARNING);
throw e;
}
}
private void tryToClose(@Nullable Closeable c) {
@Override
@Nullable
DuplexTransportConnection discoverAndConnect(String uuid) {
if (adapter == null) return null;
for (BluetoothDevice d : discoverDevices()) {
String address = d.getAddress();
try {
if (c != null) c.close();
if (LOG.isLoggable(INFO))
LOG.info("Connecting to " + scrubMacAddress(address));
return connectTo(address, uuid);
} catch (IOException e) {
logException(LOG, WARNING, e);
if (LOG.isLoggable(INFO)) {
LOG.info("Could not connect to "
+ scrubMacAddress(address));
}
}
}
LOG.info("Could not connect to any devices");
return null;
}
@Override
public boolean supportsDiscovery() {
return true;
}
@Override
public void discoverPeers(
List<Pair<TransportProperties, DiscoveryHandler>> properties) {
// Discover all nearby devices
List<BluetoothDevice> devices = discoverDevices();
if (devices.isEmpty()) {
LOG.info("No devices discovered");
return;
}
List<Pair<TransportProperties, DiscoveryHandler>> discovered =
new ArrayList<>();
Map<String, Pair<TransportProperties, DiscoveryHandler>> byUuid =
new HashMap<>();
Map<String, Pair<TransportProperties, DiscoveryHandler>> byAddress =
new HashMap<>();
for (Pair<TransportProperties, DiscoveryHandler> pair : properties) {
TransportProperties p = pair.getFirst();
String uuid = p.get(PROP_UUID);
if (!isNullOrEmpty(uuid)) {
byUuid.put(uuid, pair);
String address = p.get(PROP_ADDRESS);
if (!isNullOrEmpty(address)) byAddress.put(address, pair);
}
}
List<BluetoothDevice> unknown = new ArrayList<>(devices);
for (BluetoothDevice d : devices) {
Pair<TransportProperties, DiscoveryHandler> pair =
byAddress.remove(d.getAddress());
if (pair == null) {
// Try cached UUIDs
for (String uuid : getUuids(d)) {
pair = byUuid.remove(uuid);
if (pair != null) {
if (LOG.isLoggable(INFO)) {
LOG.info("Matched "
+ scrubMacAddress(d.getAddress())
+ " by cached UUID");
}
TransportProperties p =
new TransportProperties(pair.getFirst());
p.put(PROP_ADDRESS, d.getAddress());
discovered.add(new Pair<>(p, pair.getSecond()));
unknown.remove(d);
break;
}
}
} else {
if (LOG.isLoggable(INFO)) {
LOG.info("Matched " + scrubMacAddress(d.getAddress())
+ " by address");
}
discovered.add(pair);
unknown.remove(d);
}
}
if (unknown.isEmpty()) {
LOG.info("All discovered devices are known, not fetching UUIDs");
return;
}
// Fetch up-to-date UUIDs
if (LOG.isLoggable(INFO))
LOG.info("Fetching UUIDs for " + unknown.size() + " devices");
BlockingQueue<Intent> intents = new LinkedBlockingQueue<>();
QueueingReceiver receiver = new QueueingReceiver(intents);
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_UUID);
appContext.registerReceiver(receiver, filter);
try {
List<BluetoothDevice> pending = new ArrayList<>();
for (BluetoothDevice d : unknown) {
if (d.fetchUuidsWithSdp()) {
if (LOG.isLoggable(INFO)) {
LOG.info("Fetching UUIDs for "
+ scrubMacAddress(d.getAddress()));
}
pending.add(d);
} else {
if (LOG.isLoggable(INFO)) {
LOG.info("Failed to fetch UUIDs for "
+ scrubMacAddress(d.getAddress()));
}
}
}
long now = clock.currentTimeMillis();
long end = now + MAX_SERVICE_DISCOVERY_MS;
while (now < end && !pending.isEmpty()) {
Intent i = intents.poll(end - now, MILLISECONDS);
if (i == null) break;
BluetoothDevice d = requireNonNull(
i.getParcelableExtra(EXTRA_DEVICE));
if (LOG.isLoggable(INFO)) {
LOG.info("Fetched UUIDs for "
+ scrubMacAddress(d.getAddress()));
}
Set<String> uuids = getUuids(d);
Parcelable[] extra = i.getParcelableArrayExtra(EXTRA_UUID);
if (extra != null) {
for (Parcelable p : extra) {
uuids.addAll(getUuidStrings((ParcelUuid) p));
}
}
for (String uuid : uuids) {
Pair<TransportProperties, DiscoveryHandler> pair =
byUuid.remove(uuid);
if (pair != null) {
if (LOG.isLoggable(INFO)) {
LOG.info("Matched "
+ scrubMacAddress(d.getAddress())
+ " by fetched UUID");
}
TransportProperties p =
new TransportProperties(pair.getFirst());
p.put(PROP_ADDRESS, d.getAddress());
discovered.add(new Pair<>(p, pair.getSecond()));
break;
}
}
pending.remove(d);
now = clock.currentTimeMillis();
}
if (LOG.isLoggable(INFO)) {
if (pending.isEmpty()) {
LOG.info("Finished fetching UUIDs");
} else {
LOG.info("Failed to fetch UUIDs for " + pending.size()
+ " devices");
}
}
} catch (InterruptedException e) {
LOG.info("Interrupted while fetching UUIDs");
Thread.currentThread().interrupt();
} finally {
appContext.unregisterReceiver(receiver);
}
if (LOG.isLoggable(INFO)) {
LOG.info("Discovered " + discovered.size() + " contacts");
}
for (Pair<TransportProperties, DiscoveryHandler> pair : discovered) {
pair.getSecond().handleDevice(pair.getFirst());
}
}
private Set<String> getUuids(BluetoothDevice d) {
Set<String> strings = new TreeSet<>();
ParcelUuid[] uuids = d.getUuids();
if (uuids == null) return strings;
for (ParcelUuid u : uuids) strings.addAll(getUuidStrings(u));
return strings;
}
// Workaround for https://code.google.com/p/android/issues/detail?id=197341
private List<String> getUuidStrings(ParcelUuid u) {
UUID forwards = u.getUuid();
ByteBuffer buf = ByteBuffer.allocate(16);
buf.putLong(forwards.getLeastSignificantBits());
buf.putLong(forwards.getMostSignificantBits());
buf.rewind();
buf.order(LITTLE_ENDIAN);
UUID backwards = new UUID(buf.getLong(), buf.getLong());
return asList(forwards.toString(), backwards.toString());
}
private List<BluetoothDevice> discoverDevices() {
if (adapter.isDiscovering()) {
LOG.info("Already discovering");
return emptyList();
}
List<BluetoothDevice> devices = new ArrayList<>();
BlockingQueue<Intent> intents = new LinkedBlockingQueue<>();
QueueingReceiver receiver = new QueueingReceiver(intents);
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_DISCOVERY_STARTED);
filter.addAction(ACTION_DISCOVERY_FINISHED);
filter.addAction(ACTION_FOUND);
appContext.registerReceiver(receiver, filter);
try {
if (adapter.startDiscovery()) {
long start = clock.currentTimeMillis();
long end = start + MAX_DEVICE_DISCOVERY_MS;
long now = start;
while (now < end) {
Intent i = intents.poll(end - now, MILLISECONDS);
if (i == null) break;
String action = i.getAction();
if (ACTION_DISCOVERY_STARTED.equals(action)) {
LOG.info("Discovery started");
} else if (ACTION_DISCOVERY_FINISHED.equals(action)) {
LOG.info("Discovery finished");
now = clock.currentTimeMillis();
if (now - start < MIN_DEVICE_DISCOVERY_MS) {
LOG.info("Discovery finished quickly, retrying");
if (!adapter.startDiscovery()) {
LOG.info("Could not restart discovery");
break;
}
} else {
break;
}
} else if (ACTION_FOUND.equals(action)) {
BluetoothDevice d = requireNonNull(
i.getParcelableExtra(EXTRA_DEVICE));
// Ignore Bluetooth LE devices
if (SDK_INT < 18 || d.getType() != DEVICE_TYPE_LE) {
if (LOG.isLoggable(INFO)) {
LOG.info("Discovered "
+ scrubMacAddress(d.getAddress()));
}
if (!devices.contains(d)) devices.add(d);
}
}
now = clock.currentTimeMillis();
}
} else {
LOG.info("Could not start discovery");
}
} catch (InterruptedException e) {
LOG.info("Interrupted while discovering devices");
Thread.currentThread().interrupt();
} finally {
LOG.info("Cancelling discovery");
adapter.cancelDiscovery();
appContext.unregisterReceiver(receiver);
}
// Shuffle the devices so we don't always try the same one first
shuffle(devices);
return devices;
}
private class BluetoothStateReceiver extends BroadcastReceiver {
@@ -207,4 +520,18 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
}
}
}
private static class QueueingReceiver extends BroadcastReceiver {
private final BlockingQueue<Intent> intents;
private QueueingReceiver(BlockingQueue<Intent> intents) {
this.intents = intents;
}
@Override
public void onReceive(Context ctx, Intent intent) {
intents.add(intent);
}
}
}
@@ -6,11 +6,12 @@ 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.PluginCallback;
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 org.briarproject.bramble.api.system.Clock;
import java.security.SecureRandom;
import java.util.concurrent.Executor;
@@ -33,17 +34,19 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
private final Context appContext;
private final SecureRandom secureRandom;
private final EventBus eventBus;
private final Clock clock;
private final BackoffFactory backoffFactory;
public AndroidBluetoothPluginFactory(Executor ioExecutor,
AndroidExecutor androidExecutor, Context appContext,
SecureRandom secureRandom, EventBus eventBus,
SecureRandom secureRandom, EventBus eventBus, Clock clock,
BackoffFactory backoffFactory) {
this.ioExecutor = ioExecutor;
this.androidExecutor = androidExecutor;
this.appContext = appContext;
this.secureRandom = secureRandom;
this.eventBus = eventBus;
this.clock = clock;
this.backoffFactory = backoffFactory;
}
@@ -58,14 +61,14 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
}
@Override
public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
public DuplexPlugin createPlugin(PluginCallback callback) {
BluetoothConnectionLimiter connectionLimiter =
new BluetoothConnectionLimiterImpl();
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
MAX_POLLING_INTERVAL, BACKOFF_BASE);
AndroidBluetoothPlugin plugin = new AndroidBluetoothPlugin(
connectionLimiter, ioExecutor, androidExecutor, appContext,
secureRandom, backoff, callback, MAX_LATENCY);
secureRandom, clock, backoff, callback, MAX_LATENCY);
eventBus.addListener(plugin);
return plugin;
}
@@ -9,17 +9,17 @@ import android.net.wifi.WifiManager;
import org.briarproject.bramble.PoliteExecutor;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventListener;
import org.briarproject.bramble.api.network.event.NetworkStatusEvent;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.Backoff;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
import org.briarproject.bramble.api.plugin.PluginCallback;
import org.briarproject.bramble.api.settings.Settings;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
@@ -32,25 +32,17 @@ import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.os.Build.VERSION.SDK_INT;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE;
import static org.briarproject.bramble.util.IoUtils.tryToClose;
@NotNullByDefault
class AndroidLanTcpPlugin extends LanTcpPlugin implements EventListener {
private static final byte[] WIFI_AP_ADDRESS_BYTES =
{(byte) 192, (byte) 168, 43, 1};
private static final InetAddress WIFI_AP_ADDRESS;
class AndroidLanTcpPlugin extends LanTcpPlugin {
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);
}
}
getLogger(AndroidLanTcpPlugin.class.getName());
private final Executor connectionStatusExecutor;
private final ConnectivityManager connectivityManager;
@@ -60,9 +52,10 @@ class AndroidLanTcpPlugin extends LanTcpPlugin implements EventListener {
private volatile SocketFactory socketFactory;
AndroidLanTcpPlugin(Executor ioExecutor, Context appContext,
Backoff backoff, DuplexPluginCallback callback, int maxLatency,
int maxIdleTime) {
super(ioExecutor, backoff, callback, maxLatency, maxIdleTime);
Backoff backoff, PluginCallback callback, int maxLatency,
int maxIdleTime, int connectionTimeout) {
super(ioExecutor, backoff, callback, maxLatency, maxIdleTime,
connectionTimeout);
// Don't execute more than one connection status check at a time
connectionStatusExecutor =
new PoliteExecutor("AndroidLanTcpPlugin", ioExecutor, 1);
@@ -78,32 +71,31 @@ class AndroidLanTcpPlugin extends LanTcpPlugin implements EventListener {
@Override
public void start() {
if (used.getAndSet(true)) throw new IllegalStateException();
running = true;
initialisePortProperty();
Settings settings = callback.getSettings();
state.setStarted(settings.getBoolean(PREF_PLUGIN_ENABLE, false));
updateConnectionStatus();
}
@Override
public void stop() {
running = false;
tryToClose(socket);
}
@Override
protected Socket createSocket() throws IOException {
return socketFactory.createSocket();
}
@Override
protected Collection<InetAddress> getLocalIpAddresses() {
protected List<InetAddress> getUsableLocalInetAddresses() {
// 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
// If we're connected to a wifi network, return its address
WifiInfo info = wifiManager.getConnectionInfo();
if (info != null && info.getIpAddress() != 0)
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);
for (InetAddress addr : getLocalInetAddresses()) {
if (addr.equals(WIFI_AP_ADDRESS)) return singletonList(addr);
if (addr.equals(WIFI_DIRECT_AP_ADDRESS)) return singletonList(addr);
}
// No suitable addresses
return emptyList();
}
@@ -137,29 +129,38 @@ class AndroidLanTcpPlugin extends LanTcpPlugin implements EventListener {
@Override
public void eventOccurred(Event e) {
super.eventOccurred(e);
if (e instanceof NetworkStatusEvent) updateConnectionStatus();
}
private void updateConnectionStatus() {
connectionStatusExecutor.execute(() -> {
if (!running) return;
Collection<InetAddress> addrs = getLocalIpAddresses();
if (addrs.contains(WIFI_AP_ADDRESS)) {
State s = getState();
if (s != ACTIVE && s != INACTIVE) return;
List<InetAddress> addrs = getLocalInetAddresses();
if (addrs.contains(WIFI_AP_ADDRESS)
|| addrs.contains(WIFI_DIRECT_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();
if (s == INACTIVE) bind();
} else if (addrs.isEmpty()) {
LOG.info("Not connected to wifi");
socketFactory = SocketFactory.getDefault();
tryToClose(socket);
// Server socket may not have been closed automatically when
// interface was taken down. Socket will be cleared and state
// updated in acceptContactConnections()
if (s == ACTIVE) {
LOG.info("Closing server socket");
tryToClose(state.getServerSocket(), LOG, WARNING);
}
} else {
LOG.info("Connected to wifi");
socketFactory = getSocketFactory();
if (socket == null || socket.isClosed()) bind();
if (s == INACTIVE) bind();
}
});
}
@@ -6,9 +6,9 @@ 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.PluginCallback;
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;
@@ -21,10 +21,11 @@ import static org.briarproject.bramble.api.plugin.LanTcpConstants.ID;
@NotNullByDefault
public class AndroidLanTcpPluginFactory implements DuplexPluginFactory {
private static final int MAX_LATENCY = 30 * 1000; // 30 seconds
private static final int MAX_IDLE_TIME = 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 int MAX_LATENCY = 30_000; // 30 seconds
private static final int MAX_IDLE_TIME = 30_000; // 30 seconds
private static final int CONNECTION_TIMEOUT = 3_000; // 3 seconds
private static final int MIN_POLLING_INTERVAL = 60_000; // 1 minute
private static final int MAX_POLLING_INTERVAL = 600_000; // 10 mins
private static final double BACKOFF_BASE = 1.2;
private final Executor ioExecutor;
@@ -51,11 +52,12 @@ public class AndroidLanTcpPluginFactory implements DuplexPluginFactory {
}
@Override
public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
public DuplexPlugin createPlugin(PluginCallback callback) {
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
MAX_POLLING_INTERVAL, BACKOFF_BASE);
AndroidLanTcpPlugin plugin = new AndroidLanTcpPlugin(ioExecutor,
appContext, backoff, callback, MAX_LATENCY, MAX_IDLE_TIME);
appContext, backoff, callback, MAX_LATENCY, MAX_IDLE_TIME,
CONNECTION_TIMEOUT);
eventBus.addListener(plugin);
return plugin;
}
@@ -6,11 +6,12 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.PowerManager;
import org.briarproject.bramble.api.battery.BatteryManager;
import org.briarproject.bramble.api.network.NetworkManager;
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.duplex.DuplexPluginCallback;
import org.briarproject.bramble.api.plugin.PluginCallback;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.api.system.ResourceProvider;
@@ -31,9 +32,6 @@ import static java.util.concurrent.TimeUnit.MINUTES;
@ParametersNotNullByDefault
class AndroidTorPlugin extends TorPlugin {
// This tag may prevent Huawei's power manager from killing us
private static final String WAKE_LOCK_TAG = "LocationManagerService";
private final Context appContext;
private final RenewableWakeLock wakeLock;
@@ -41,19 +39,21 @@ class AndroidTorPlugin extends TorPlugin {
Context appContext, NetworkManager networkManager,
LocationUtils locationUtils, SocketFactory torSocketFactory,
Clock clock, ResourceProvider resourceProvider,
CircumventionProvider circumventionProvider, Backoff backoff,
DuplexPluginCallback callback, String architecture, int maxLatency,
CircumventionProvider circumventionProvider,
BatteryManager batteryManager, Backoff backoff,
TorRendezvousCrypto torRendezvousCrypto,
PluginCallback callback, String architecture, int maxLatency,
int maxIdleTime) {
super(ioExecutor, networkManager, locationUtils, torSocketFactory,
clock, resourceProvider, circumventionProvider, backoff,
callback, architecture, maxLatency, maxIdleTime,
clock, resourceProvider, circumventionProvider, batteryManager,
backoff, torRendezvousCrypto, callback, architecture, maxLatency, maxIdleTime,
appContext.getDir("tor", MODE_PRIVATE));
this.appContext = appContext;
PowerManager pm = (PowerManager)
appContext.getSystemService(POWER_SERVICE);
assert pm != null;
if (pm == null) throw new AssertionError();
wakeLock = new RenewableWakeLock(pm, scheduler, PARTIAL_WAKE_LOCK,
WAKE_LOCK_TAG, 1, MINUTES);
getWakeLockTag(), 1, MINUTES);
}
@Override
@@ -74,7 +74,6 @@ class AndroidTorPlugin extends TorPlugin {
@Override
protected void enableNetwork(boolean enable) throws IOException {
if (!running) return;
if (enable) wakeLock.acquire();
super.enableNetwork(enable);
if (!enable) wakeLock.release();
@@ -85,4 +84,17 @@ class AndroidTorPlugin extends TorPlugin {
super.stop();
wakeLock.release();
}
private String getWakeLockTag() {
PackageManager pm = appContext.getPackageManager();
for (PackageInfo info : pm.getInstalledPackages(0)) {
String name = info.packageName.toLowerCase();
if (name.startsWith("com.huawei.powergenie")) {
return "LocationManagerService";
} else if (name.startsWith("com.evenwell.powermonitor")) {
return "AudioIn";
}
}
return getClass().getSimpleName();
}
}
@@ -1,17 +1,17 @@
package org.briarproject.bramble.plugin.tor;
import android.content.Context;
import android.os.Build;
import org.briarproject.bramble.api.battery.BatteryManager;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.network.NetworkManager;
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.PluginCallback;
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.system.Clock;
import org.briarproject.bramble.api.system.LocationUtils;
@@ -48,6 +48,7 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
private final BackoffFactory backoffFactory;
private final ResourceProvider resourceProvider;
private final CircumventionProvider circumventionProvider;
private final BatteryManager batteryManager;
private final Clock clock;
public AndroidTorPluginFactory(Executor ioExecutor,
@@ -55,7 +56,8 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
NetworkManager networkManager, LocationUtils locationUtils,
EventBus eventBus, SocketFactory torSocketFactory,
BackoffFactory backoffFactory, ResourceProvider resourceProvider,
CircumventionProvider circumventionProvider, Clock clock) {
CircumventionProvider circumventionProvider,
BatteryManager batteryManager, Clock clock) {
this.ioExecutor = ioExecutor;
this.scheduler = scheduler;
this.appContext = appContext;
@@ -66,6 +68,7 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
this.backoffFactory = backoffFactory;
this.resourceProvider = resourceProvider;
this.circumventionProvider = circumventionProvider;
this.batteryManager = batteryManager;
this.clock = clock;
}
@@ -80,14 +83,20 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
}
@Override
public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
public DuplexPlugin createPlugin(PluginCallback callback) {
// Check that we have a Tor binary for this architecture
String architecture = null;
for (String abi : AndroidUtils.getSupportedArchitectures()) {
if (abi.startsWith("x86")) {
if (abi.startsWith("x86_64")) {
architecture = "x86_64";
break;
} else if (abi.startsWith("x86")) {
architecture = "x86";
break;
} else if (abi.startsWith("arm64")) {
architecture = "arm64";
break;
} else if (abi.startsWith("armeabi")) {
architecture = "arm";
break;
@@ -97,15 +106,17 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
LOG.info("Tor is not supported on this architecture");
return null;
}
// Use position-independent executable for SDK >= 16
if (Build.VERSION.SDK_INT >= 16) architecture += "_pie";
// Use position-independent executable
architecture += "_pie";
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
MAX_POLLING_INTERVAL, BACKOFF_BASE);
TorRendezvousCrypto torRendezvousCrypto = new TorRendezvousCryptoImpl();
AndroidTorPlugin plugin = new AndroidTorPlugin(ioExecutor, scheduler,
appContext, networkManager, locationUtils, torSocketFactory,
clock, resourceProvider, circumventionProvider, backoff,
callback, architecture, MAX_LATENCY, MAX_IDLE_TIME);
clock, resourceProvider, circumventionProvider, batteryManager,
backoff, torRendezvousCrypto, callback, architecture,
MAX_LATENCY, MAX_IDLE_TIME);
eventBus.addListener(plugin);
return plugin;
}
@@ -61,12 +61,12 @@ class AndroidLocationUtils implements LocationUtils {
private String getCountryFromPhoneNetwork() {
Object o = appContext.getSystemService(TELEPHONY_SERVICE);
TelephonyManager tm = (TelephonyManager) o;
return tm.getNetworkCountryIso();
return tm == null ? "" : tm.getNetworkCountryIso();
}
private String getCountryFromSimCard() {
Object o = appContext.getSystemService(TELEPHONY_SERVICE);
TelephonyManager tm = (TelephonyManager) o;
return tm.getSimCountryIso();
return tm == null ? "" : tm.getSimCountryIso();
}
}
@@ -1,5 +1,6 @@
package org.briarproject.bramble.system;
import android.annotation.SuppressLint;
import android.app.Application;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
@@ -22,11 +23,12 @@ import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static android.content.Context.WIFI_SERVICE;
import static android.os.Build.VERSION.SDK_INT;
import static android.provider.Settings.Secure.ANDROID_ID;
@Immutable
@NotNullByDefault
class AndroidSecureRandomProvider extends LinuxSecureRandomProvider {
class AndroidSecureRandomProvider extends UnixSecureRandomProvider {
private static final int SEED_LENGTH = 32;
@@ -37,6 +39,7 @@ class AndroidSecureRandomProvider extends LinuxSecureRandomProvider {
appContext = app.getApplicationContext();
}
@SuppressLint("HardwareIds")
@Override
protected void writeToEntropyPool(DataOutputStream out) throws IOException {
super.writeToEntropyPool(out);
@@ -49,13 +52,15 @@ class AndroidSecureRandomProvider extends LinuxSecureRandomProvider {
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);
WifiManager wm = (WifiManager) appContext.getApplicationContext()
.getSystemService(WIFI_SERVICE);
if (wm != null) {
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())
@@ -70,20 +75,19 @@ class AndroidSecureRandomProvider extends LinuxSecureRandomProvider {
// Silence strict mode
StrictMode.ThreadPolicy tp = StrictMode.allowThreadDiskWrites();
super.writeSeed();
if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT <= 18)
applyOpenSslFix();
if (SDK_INT <= 18) applyOpenSslFix();
StrictMode.setThreadPolicy(tp);
}
// Based on https://android-developers.googleblog.com/2013/08/some-securerandom-thoughts.html
private void applyOpenSslFix() {
byte[] seed = new LinuxSecureRandomSpi().engineGenerateSeed(
byte[] seed = new UnixSecureRandomSpi().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);
.invoke(null, (Object) seed);
// Mix the output of the Linux PRNG into the OpenSSL PRNG
int bytesRead = (Integer) Class.forName(
"org.apache.harmony.xnet.provider.jsse.NativeCrypto")
@@ -1,10 +1,13 @@
package org.briarproject.bramble.system;
import org.briarproject.bramble.api.event.EventExecutor;
import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.api.system.ResourceProvider;
import org.briarproject.bramble.api.system.SecureRandomProvider;
import java.util.concurrent.Executor;
import javax.inject.Singleton;
import dagger.Module;
@@ -32,6 +35,13 @@ public class AndroidSystemModule {
return androidExecutor;
}
@Provides
@Singleton
@EventExecutor
Executor provideEventExecutor(AndroidExecutor androidExecutor) {
return androidExecutor::runOnUiThread;
}
@Provides
@Singleton
ResourceProvider provideResourceProvider(AndroidResourceProvider provider) {
@@ -6,30 +6,36 @@ import android.content.Context;
import android.os.Build;
import android.provider.Settings;
import org.briarproject.bramble.api.Pair;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import static android.content.Context.MODE_PRIVATE;
import static android.os.Build.VERSION.SDK_INT;
import static java.util.Arrays.asList;
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
@NotNullByDefault
public class AndroidUtils {
private static final Logger LOG =
Logger.getLogger(AndroidUtils.class.getName());
// 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));
if (SDK_INT >= 21) {
abis.addAll(asList(Build.SUPPORTED_ABIS));
} else {
abis.add(Build.CPU_ABI);
if (Build.CPU_ABI2 != null) abis.add(Build.CPU_ABI2);
@@ -39,25 +45,76 @@ public class AndroidUtils {
public static String getBluetoothAddress(Context ctx,
BluetoothAdapter adapter) {
return getBluetoothAddressAndMethod(ctx, adapter).getFirst();
}
public static Pair<String, String> getBluetoothAddressAndMethod(Context ctx,
BluetoothAdapter adapter) {
// Return the adapter's address if it's valid and not fake
@SuppressLint("HardwareIds")
String address = adapter.getAddress();
if (isValidBluetoothAddress(address)) return address;
if (isValidBluetoothAddress(address)) {
return new Pair<>(address, "adapter");
}
// 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;
if (isValidBluetoothAddress(address)) {
return new Pair<>(address, "settings");
}
// Try to get the address via reflection
address = getBluetoothAddressByReflection(adapter);
if (isValidBluetoothAddress(address)) {
return new Pair<>(requireNonNull(address), "reflection");
}
// Let the caller know we can't find the address
return "";
return new Pair<>("", "");
}
private static boolean isValidBluetoothAddress(String address) {
private static boolean isValidBluetoothAddress(@Nullable String address) {
return !StringUtils.isNullOrEmpty(address)
&& BluetoothAdapter.checkBluetoothAddress(address)
&& !address.equals(FAKE_BLUETOOTH_ADDRESS);
}
@Nullable
private static String getBluetoothAddressByReflection(
BluetoothAdapter adapter) {
try {
Field mServiceField =
adapter.getClass().getDeclaredField("mService");
mServiceField.setAccessible(true);
Object mService = mServiceField.get(adapter);
// mService may be null when Bluetooth is disabled
if (mService == null) throw new NoSuchFieldException();
Method getAddressMethod =
mService.getClass().getMethod("getAddress");
return (String) getAddressMethod.invoke(mService);
} catch (NoSuchFieldException e) {
return null;
} catch (IllegalAccessException e) {
return null;
} catch (NoSuchMethodException e) {
return null;
} catch (InvocationTargetException e) {
return null;
} catch (SecurityException e) {
return null;
}
}
public static File getReportDir(Context ctx) {
return ctx.getDir(STORED_REPORTS, MODE_PRIVATE);
}
/**
* Returns an array of supported content types for image attachments.
* GIFs can't be compressed on API < 24 so they're not supported.
* <p>
* TODO: Remove this restriction when large message support is added
*/
public static String[] getSupportedImageContentTypes() {
if (SDK_INT < 24) return new String[] {"image/jpeg", "image/png"};
else return new String[] {"image/jpeg", "image/png", "image/gif"};
}
}
@@ -16,13 +16,10 @@ import org.junit.Test;
import java.io.File;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
import static org.briarproject.bramble.util.StringUtils.toHexString;
public class AndroidAccountManagerTest extends BrambleMockTestCase {
@@ -40,11 +37,8 @@ public class AndroidAccountManagerTest extends BrambleMockTestCase {
private final Application app;
private final ApplicationInfo applicationInfo;
private final String encryptedKeyHex = toHexString(getRandomBytes(123));
private final File testDir = getTestDirectory();
private final File keyDir = new File(testDir, "key");
private final File keyFile = new File(keyDir, "db.key");
private final File keyBackupFile = new File(keyDir, "db.key.bak");
private final File dbDir = new File(testDir, "db");
private AndroidAccountManager accountManager;
@@ -75,33 +69,12 @@ public class AndroidAccountManagerTest extends BrambleMockTestCase {
};
}
@Test
public void testDbKeyIsMigratedFromPreferencesToFile() {
context.checking(new Expectations() {{
oneOf(prefs).getString("key", null);
will(returnValue(encryptedKeyHex));
oneOf(prefs).edit();
will(returnValue(editor));
oneOf(editor).remove("key");
will(returnValue(editor));
oneOf(editor).commit();
will(returnValue(true));
}});
assertFalse(keyFile.exists());
assertFalse(keyBackupFile.exists());
assertEquals(encryptedKeyHex,
accountManager.loadEncryptedDatabaseKey());
assertTrue(keyFile.exists());
assertTrue(keyBackupFile.exists());
}
@Test
public void testDeleteAccountClearsSharedPrefsAndDeletesFiles()
throws Exception {
// Directories 'lib' and 'shared_prefs' should be spared
// Directories 'code_cache', 'lib' and 'shared_prefs' should be spared
File codeCacheDir = new File(testDir, "code_cache");
File codeCacheFile = new File(codeCacheDir, "file");
File libDir = new File(testDir, "lib");
File libFile = new File(libDir, "file");
File sharedPrefsDir = new File(testDir, "shared_prefs");
@@ -112,6 +85,8 @@ public class AndroidAccountManagerTest extends BrambleMockTestCase {
// Other directories should be deleted
File potatoDir = new File(testDir, ".potato");
File potatoFile = new File(potatoDir, "file");
File filesDir = new File(testDir, "filesDir");
File externalCacheDir = new File(testDir, "externalCacheDir");
context.checking(new Expectations() {{
oneOf(prefs).edit();
@@ -126,12 +101,20 @@ public class AndroidAccountManagerTest extends BrambleMockTestCase {
will(returnValue(editor));
oneOf(editor).commit();
will(returnValue(true));
oneOf(app).getApplicationInfo();
allowing(app).getApplicationInfo();
will(returnValue(applicationInfo));
oneOf(app).getFilesDir();
will(returnValue(filesDir));
oneOf(app).getCacheDir();
will(returnValue(cacheDir));
oneOf(app).getExternalCacheDir();
will(returnValue(externalCacheDir));
}});
assertTrue(dbDir.mkdirs());
assertTrue(keyDir.mkdirs());
assertTrue(codeCacheDir.mkdirs());
assertTrue(codeCacheFile.createNewFile());
assertTrue(libDir.mkdirs());
assertTrue(libFile.createNewFile());
assertTrue(sharedPrefsDir.mkdirs());
@@ -140,11 +123,15 @@ public class AndroidAccountManagerTest extends BrambleMockTestCase {
assertTrue(cacheFile.createNewFile());
assertTrue(potatoDir.mkdirs());
assertTrue(potatoFile.createNewFile());
assertTrue(filesDir.mkdirs());
assertTrue(externalCacheDir.mkdirs());
accountManager.deleteAccount();
assertFalse(dbDir.exists());
assertFalse(keyDir.exists());
assertTrue(codeCacheDir.exists());
assertTrue(codeCacheFile.exists());
assertTrue(libDir.exists());
assertTrue(libFile.exists());
assertTrue(sharedPrefsDir.exists());
@@ -153,6 +140,8 @@ public class AndroidAccountManagerTest extends BrambleMockTestCase {
assertFalse(cacheFile.exists());
assertFalse(potatoDir.exists());
assertFalse(potatoFile.exists());
assertFalse(filesDir.exists());
assertFalse(externalCacheDir.exists());
}
@After
+64 -52
View File
@@ -1,78 +1,90 @@
dependencyVerification {
verify = [
'cglib:cglib:3.2.0:cglib-3.2.0.jar:adb13bab79712ad6bdf1bd59f2a3918018a8016e722e8a357065afb9e6690861',
'com.android.tools.analytics-library:protos:26.1.3:protos-26.1.3.jar:818c9f256f141d9dafec03a1aa2b94d240b2c140acfd7ee31a8b3e6c2b9479e3',
'com.android.tools.analytics-library:shared:26.1.3:shared-26.1.3.jar:7110706c7ada96c8b6f5ca80c478291bc7899d46277de2c48527e045442401a3',
'com.android.tools.analytics-library:tracker:26.1.3:tracker-26.1.3.jar:4155424bf2ce4872da83332579a1707252bc66cbd77c5144fdc4483d0f2e1418',
'com.android.tools.build:apksig:3.1.3:apksig-3.1.3.jar:7e1f8e675a6e768e5b56405e41d6c3cc05befe62e601b04177de1029902c9c89',
'com.android.tools.build:builder-model:3.1.3:builder-model-3.1.3.jar:06ad1c422d679fc698451479cb40ba863849d67bfd1de23f6d2c16d78b024b0b',
'com.android.tools.build:builder-test-api:3.1.3:builder-test-api-3.1.3.jar:4d989f780436794f0f8b2f50e9e079b786571eac90f26c208ab2ae6d4012f389',
'com.android.tools.build:builder:3.1.3:builder-3.1.3.jar:8a1092012c89d0ec1ee2eff09c5708c71ef4482a6862df8d3a44a67fccace01c',
'com.android.tools.build:gradle-api:3.1.3:gradle-api-3.1.3.jar:01e4df521456aef66514336f1d492346730dd1fb8f6433a89f62da834941ed72',
'com.android.tools.build:manifest-merger:26.1.3:manifest-merger-26.1.3.jar:1e4fc7e932adb4607082409800e5e6fccb42e6c5360ae5990094bf522f3ada55',
'com.android.tools.ddms:ddmlib:26.1.3:ddmlib-26.1.3.jar:c54931cd68df5d1ea2923b3b320eae47cd2307a5a916bb8674c0acf93cd1d3cd',
'com.android.tools.external.com-intellij:intellij-core:26.1.3:intellij-core-26.1.3.jar:af67f5535fef2e1a28b1007a4acb8c5deb6a1e33b8afe7b11d012c9e778ebcec',
'com.android.tools.external.com-intellij:kotlin-compiler:26.1.3:kotlin-compiler-26.1.3.jar:c746d2859dc11cc05c84b692b3498d3a621e0929511f8440ee009c6557838fd4',
'com.android.tools.external.org-jetbrains:uast:26.1.3:uast-26.1.3.jar:3f3f6651d0c7685a77ecb22e9c82d6b49fdf24322c17360768dc530678f43265',
'com.android.tools.layoutlib:layoutlib-api:26.1.3:layoutlib-api-26.1.3.jar:10bc73ce706c45629872d6a999dbe12116df64e24f47ff93b7b13121ff57b4b0',
'com.android.tools.lint:lint-api:26.1.3:lint-api-26.1.3.jar:6f97323f9af8deda86278717885b5c927f3766757db89709f52d11d42b6fb751',
'com.android.tools.lint:lint-checks:26.1.3:lint-checks-26.1.3.jar:73c3d53784c9ce3e6d5968506581918e0179645d20809927ca4a001dd766b001',
'com.android.tools.lint:lint-gradle-api:26.1.3:lint-gradle-api-26.1.3.jar:7ca3c4866ec21dc21d53a9d86f752b77ace6f6c610a0c9dc877313856c733d9d',
'com.android.tools.lint:lint-gradle:26.1.3:lint-gradle-26.1.3.jar:db0c354b8f4b6f6637e31f91c564785a59ff896325331fcbc3de7458e0b6c067',
'com.android.tools.lint:lint-kotlin:26.1.3:lint-kotlin-26.1.3.jar:94e2b0f4565a241561cfb8fc1222bb3f132a3b98d2a90421dbb72ee8358e7d68',
'com.android.tools.lint:lint:26.1.3:lint-26.1.3.jar:8d5f32c989c6d191d712e90ad3ca2d1c409313599551d04d834caa44d26c78df',
'com.android.tools:annotations:26.1.3:annotations-26.1.3.jar:c950430b24ac5d58fc97e7283b8f0115f99587e76e08b4e1e2aaa780f2d77323',
'com.android.tools:common:26.1.3:common-26.1.3.jar:7c31a90581a148ab219f615a59667f0dded7fa39b248529784474da3c2274ef2',
'com.android.tools:dvlib:26.1.3:dvlib-26.1.3.jar:0cae87906f53d3f1088366a916ed180a7312b6d9919b90797f238875c8492855',
'com.android.tools:repository:26.1.3:repository-26.1.3.jar:52d4539cc68db91b261e2a33b2c8206b26e05539078758dc28cfb3854adb4f59',
'com.android.tools:sdk-common:26.1.3:sdk-common-26.1.3.jar:1948603ca9ff22c7ebb3178000bffa3a9dd2ca1cc5cb0c793cae08468b8fcfc1',
'com.android.tools:sdklib:26.1.3:sdklib-26.1.3.jar:4adcfaad9514607098d2c51503c39811112d3050f4d1e744c01c7f08f591032b',
'com.google.code.findbugs:jsr305:1.3.9:jsr305-1.3.9.jar:905721a0eea90a81534abb7ee6ef4ea2e5e645fa1def0a5cd88402df1b46c9ed',
'com.google.code.gson:gson:2.7:gson-2.7.jar:2d43eb5ea9e133d2ee2405cc14f5ee08951b8361302fdd93494a3a997b508d32',
'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.errorprone:error_prone_annotations:2.0.18:error_prone_annotations-2.0.18.jar:cb4cfad870bf563a07199f3ebea5763f0dec440fcda0b318640b1feaa788656b',
'com.google.guava:guava:18.0:guava-18.0.jar:d664fbfc03d2e5ce9cab2a44fb01f1d0bf9dfebeccc1a473b1f9ea31f79f6f99',
'com.google.guava:guava:22.0:guava-22.0.jar:1158e94c7de4da480873f0b4ab4a1da14c0d23d4b1902cc94a58a6f0f9ab579e',
'com.google.j2objc:j2objc-annotations:1.1:j2objc-annotations-1.1.jar:40ceb7157feb263949e0f503fe5f71689333a621021aa20ce0d0acee3badaa0f',
'com.android.tools.analytics-library:protos:26.5.1:protos-26.5.1.jar:8dde1130725461fe827f2a343d353f2b51e8870661fc860d7d5ebddb097ead4e',
'com.android.tools.analytics-library:shared:26.5.1:shared-26.5.1.jar:ccc2f3b00ec17b11401610ba68553544fc8fc517120e84439ac6eb86b875e18d',
'com.android.tools.analytics-library:tracker:26.5.1:tracker-26.5.1.jar:3a76984c0fe2e847ca7a8b35b4780ef0447a9d1666946cb8e60466318e0ab5ae',
'com.android.tools.build:aapt2-proto:0.4.0:aapt2-proto-0.4.0.jar:fac0435e08898f89eeeb9ca236bea707155ff816c12205ced285ad53604133ca',
'com.android.tools.build:apksig:3.5.1:apksig-3.5.1.jar:1fd33e7f009a2a0da766cfeec4211a09f548034b015c289a66d75dd8a9302f4a',
'com.android.tools.build:apkzlib:3.5.1:apkzlib-3.5.1.jar:9f330167cbe973b7db407692f74f4f6453b7ffa5f2048934b06280c2ceee60fa',
'com.android.tools.build:builder-model:3.5.1:builder-model-3.5.1.jar:39ea3c82b76b6e0c9f9fa88d93e0edc1dd4a0f1dfae0ef6fbf2d451da47e5450',
'com.android.tools.build:builder-test-api:3.5.1:builder-test-api-3.5.1.jar:a1b59305584cbcaa078fdc9cfb80871012755b822dd32e8da19add6f7bbcb762',
'com.android.tools.build:builder:3.5.1:builder-3.5.1.jar:e3a8d382434c5f60990730c4719fc814e85a898a33a1e96c1df8d627d3c6eea6',
'com.android.tools.build:gradle-api:3.5.1:gradle-api-3.5.1.jar:be9b41859bace11998f66b04ed944f87e413f3ad6da3c4665587699da125addc',
'com.android.tools.build:manifest-merger:26.5.1:manifest-merger-26.5.1.jar:dcad9ecb967251f4d750f55a4204a2b400e8fbfe5cb930a1d0d5dbe10ae8bdfc',
'com.android.tools.ddms:ddmlib:26.5.1:ddmlib-26.5.1.jar:b081aef2a4ed3f4d47cae4cdb128469735f25a114e026d37123bf9ffdec742a8',
'com.android.tools.external.com-intellij:intellij-core:26.5.1:intellij-core-26.5.1.jar:20eced30adc124805bd93488d9cd9d3e33e6bf7b48e9fe5a703d4983f894d450',
'com.android.tools.external.com-intellij:kotlin-compiler:26.5.1:kotlin-compiler-26.5.1.jar:5aed762dd54875b77ae7018d97c05756ff0c5b9fd02ec595dd396ccd14cc22cb',
'com.android.tools.external.org-jetbrains:uast:26.5.1:uast-26.5.1.jar:4bc8653d6c0943f40fee963a149e36c6baa45683d2530968a13f5007e3c40740',
'com.android.tools.layoutlib:layoutlib-api:26.5.1:layoutlib-api-26.5.1.jar:88732f11396c427273e515d23042e35633f4fe4295528a99b866aa2adf0efd9c',
'com.android.tools.lint:lint-api:26.5.1:lint-api-26.5.1.jar:ec33fcd72bfaf70dd841e03fbfd93f109c2e575aec146067c606689c3972f0de',
'com.android.tools.lint:lint-checks:26.5.1:lint-checks-26.5.1.jar:a1b9607d484aaae7a71dcecdc76f8003d8239af226c776894a2cf63f9e6c60d7',
'com.android.tools.lint:lint-gradle-api:26.5.1:lint-gradle-api-26.5.1.jar:82453fd98a8394cc84ed995c04d2cd744abd1d6589403427ba7eef53115406f3',
'com.android.tools.lint:lint-gradle:26.5.1:lint-gradle-26.5.1.jar:59465b56cf7db77c656d5f8195d721c3d48b6bdd0502d774de335bfe4baff00b',
'com.android.tools.lint:lint:26.5.1:lint-26.5.1.jar:336e4b04ec6f8b0f25879131b7a7862d77df83a1879ee5b71be26128755f8e2e',
'com.android.tools:annotations:26.5.1:annotations-26.5.1.jar:2c43c82f8c59d8f7a61e3239e1a2dc9f69dc342ec09af9b7c9f69b25337c0b6e',
'com.android.tools:common:26.5.1:common-26.5.1.jar:eccfa54486ed54c4e3123cc42195d023bd0dd21bcd2f0e4868e8c6fc70f8ef6b',
'com.android.tools:dvlib:26.5.1:dvlib-26.5.1.jar:46f93ad498b4756e7d867d2fe38c38890a80e7407a4ae459e4a8c8d5c5aeacfe',
'com.android.tools:repository:26.5.1:repository-26.5.1.jar:2b3ee791aa4c3e8ce60498c161a27ca7228816fc630eed4d9f25f2f36a106dce',
'com.android.tools:sdk-common:26.5.1:sdk-common-26.5.1.jar:365f749676c3574676fd465177c8a492f340816db2b520d6ed114d3b6e77bea7',
'com.android.tools:sdklib:26.5.1:sdklib-26.5.1.jar:007da104afb27c8c682a1628023fe9ec438249c8d15ef0fd6624c5bb8e23b696',
'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
'com.google.code.gson:gson:2.8.5:gson-2.8.5.jar:233a0149fc365c9f6edbd683cfe266b19bdc773be98eabdaf6b3c924b48e7d81',
'com.google.dagger:dagger-compiler:2.24:dagger-compiler-2.24.jar:3c5afb955fb188da485cb2c048eff37dce0e1530b9780a0f2f7187d16d1ccc1f',
'com.google.dagger:dagger-producers:2.24:dagger-producers-2.24.jar:f10f45b95191954d5d6b043fca9e62fb621d21bf70634b8f8476c7988b504c3a',
'com.google.dagger:dagger-spi:2.24:dagger-spi-2.24.jar:c038445d14dbcb4054e61bf49e05009edf26fce4fdc7ec1a9db544784f68e718',
'com.google.dagger:dagger:2.24:dagger-2.24.jar:550a6e46a6dfcdf1d764887b6090cea94f783327e50e5c73754f18facfc70b64',
'com.google.errorprone:error_prone_annotations:2.2.0:error_prone_annotations-2.2.0.jar:6ebd22ca1b9d8ec06d41de8d64e0596981d9607b42035f9ed374f9de271a481a',
'com.google.errorprone:javac-shaded:9-dev-r4023-3:javac-shaded-9-dev-r4023-3.jar:65bfccf60986c47fbc17c9ebab0be626afc41741e0a6ec7109e0768817a36f30',
'com.google.googlejavaformat:google-java-format:1.5:google-java-format-1.5.jar:aa19ad7850fb85178aa22f2fddb163b84d6ce4d0035872f30d4408195ca1144e',
'com.google.guava:failureaccess:1.0.1:failureaccess-1.0.1.jar:a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26',
'com.google.guava:guava:27.0.1-jre:guava-27.0.1-jre.jar:e1c814fd04492a27c38e0317eabeaa1b3e950ec8010239e400fe90ad6c9107b4',
'com.google.guava:guava:27.1-jre:guava-27.1-jre.jar:4a5aa70cc968a4d137e599ad37553e5cfeed2265e8c193476d7119036c536fe7',
'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava:listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99',
'com.google.j2objc:j2objc-annotations:1.1:j2objc-annotations-1.1.jar:2994a7eb78f2710bd3d3bfb639b2c94e219cedac0d4d084d516e78c16dddecf6',
'com.google.jimfs:jimfs:1.1:jimfs-1.1.jar:c4828e28d7c0a930af9387510b3bada7daa5c04d7c25a75c7b8b081f1c257ddd',
'com.google.protobuf:protobuf-java:3.4.0:protobuf-java-3.4.0.jar:dce7e66b32456a1b1198da0caff3a8acb71548658391e798c79369241e6490a4',
'com.googlecode.json-simple:json-simple:1.1:json-simple-1.1.jar:2d9484f4c649f708f47f9a479465fc729770ee65617dca3011836602264f6439',
'com.squareup:javapoet:1.11.1:javapoet-1.11.1.jar:9cbf2107be499ec6e95afd36b58e3ca122a24166cdd375732e51267d64058e90',
'com.squareup:javawriter:2.5.0:javawriter-2.5.0.jar:fcfb09fb0ea0aa97d3cfe7ea792398081348e468f126b3603cb3803f240197f0',
'com.sun.activation:javax.activation:1.2.0:javax.activation-1.2.0.jar:993302b16cd7056f21e779cc577d175a810bb4900ef73cd8fbf2b50f928ba9ce',
'com.sun.istack:istack-commons-runtime:2.21:istack-commons-runtime-2.21.jar:c33e67a0807095f02a0e2da139412dd7c4f9cc1a4c054b3e434f96831ba950f4',
'com.sun.xml.fastinfoset:FastInfoset:1.2.13:FastInfoset-1.2.13.jar:27a77db909f3c2833c0b1a37c55af1db06045118ad2eed96ce567b6632bce038',
'commons-codec:commons-codec:1.6:commons-codec-1.6.jar:54b34e941b8e1414bd3e40d736efd3481772dc26db3296f6aa45cec9f6203d86',
'commons-logging:commons-logging:1.1.1:commons-logging-1.1.1.jar:ce6f913cad1f0db3aad70186d65c5bc7ffcc9a99e3fe8e0b137312819f7c362f',
'commons-codec:commons-codec:1.10:commons-codec-1.10.jar:4241dfa94e711d435f29a4604a3e2de5c4aa3c165e23bd066be6fc1fc4309569',
'commons-logging:commons-logging:1.2:commons-logging-1.2.jar:daddea1ea0be0f56978ab3006b8ac92834afeefbd9b7e4e6316fca57df0fa636',
'it.unimi.dsi:fastutil:7.2.0:fastutil-7.2.0.jar:74fa208043740642f7e6eb09faba15965218ad2f50ce3020efb100136e4b591c',
'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f',
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
'javax.xml.bind:jaxb-api:2.2.12-b140109.1041:jaxb-api-2.2.12-b140109.1041.jar:b5e60cd8b7b5ff01ce4a74c5dd008f4fbd14ced3495d0b47b85cfedc182211f2',
'junit:junit:4.12:junit-4.12.jar:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a',
'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd',
'net.sf.jopt-simple:jopt-simple:4.9:jopt-simple-4.9.jar:26c5856e954b5f864db76f13b86919b59c6eecf9fd930b96baa8884626baf2f5',
'net.sf.kxml:kxml2:2.3.0:kxml2-2.3.0.jar:f264dd9f79a1fde10ce5ecc53221eff24be4c9331c830b7d52f2f08a7b633de2',
'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.apache.commons:commons-compress:1.12:commons-compress-1.12.jar:2c1542faf343185b7cab9c3d55c8ae5471d6d095d3887a4adefdbdf2984dc0b6',
'org.apache.httpcomponents:httpclient:4.2.6:httpclient-4.2.6.jar:362e9324ee7c697e21279e20077b52737ddef3f1b2c1a7abe5ad34b465145550',
'org.apache.httpcomponents:httpcore:4.2.5:httpcore-4.2.5.jar:e5e82da4cc66c8d917bbf743e3c0752efe8522735e7fc9dbddb65bccea81cfe9',
'org.apache.httpcomponents:httpmime:4.1:httpmime-4.1.jar:31629566148e8a47688ae43b420abc3ecd783ed15b33bebc00824bf24c9b15aa',
'org.apache.httpcomponents:httpclient:4.5.6:httpclient-4.5.6.jar:c03f813195e7a80e3608d0ddd8da80b21696a4c92a6a2298865bf149071551c7',
'org.apache.httpcomponents:httpcore:4.4.10:httpcore-4.4.10.jar:78ba1096561957db1b55200a159b648876430342d15d461277e62360da19f6fd',
'org.apache.httpcomponents:httpmime:4.5.6:httpmime-4.5.6.jar:0b2b1102c18d3c7e05a77214b9b7501a6f6056174ae5604e0e256776eda7553e',
'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8',
'org.bouncycastle:bcpkix-jdk15on:1.56:bcpkix-jdk15on-1.56.jar:7043dee4e9e7175e93e0b36f45b1ec1ecb893c5f755667e8b916eb8dd201c6ca',
'org.bouncycastle:bcprov-jdk15on:1.56:bcprov-jdk15on-1.56.jar:963e1ee14f808ffb99897d848ddcdb28fa91ddda867eb18d303e82728f878349',
'org.briarproject:tor-android:0.2.9.16:tor-android-0.2.9.16.zip:515e33dda6a30853c885a2de2c79ae1ab9ad8b6db44f5db8890333ec2e24f4ae',
'org.codehaus.groovy:groovy-all:2.4.12:groovy-all-2.4.12.jar:6a56af4bd48903d56bec62821876cadefafd007360cc6bd0d8f7aa8d72b38be4',
'org.codehaus.mojo:animal-sniffer-annotations:1.14:animal-sniffer-annotations-1.14.jar:2068320bd6bad744c3673ab048f67e30bef8f518996fa380033556600669905d',
'org.briarproject:obfs4proxy-android:0.0.11-2:obfs4proxy-android-0.0.11-2.zip:57e55cbe87aa2aac210fdbb6cd8cdeafe15f825406a08ebf77a8b787aa2c6a8a',
'org.briarproject:tor-android:0.3.5.9:tor-android-0.3.5.9.zip:853b0440feccd6904bd03e6b2de53a62ebcde1d58068beeadc447a7dff950bc8',
'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d',
'org.checkerframework:checker-qual:2.5.2:checker-qual-2.5.2.jar:64b02691c8b9d4e7700f8ee2e742dce7ea2c6e81e662b7522c9ee3bf568c040a',
'org.codehaus.groovy:groovy-all:2.4.15:groovy-all-2.4.15.jar:51d6c4e71782e85674239189499854359d380fb75e1a703756e3aaa5b98a5af0',
'org.codehaus.mojo:animal-sniffer-annotations:1.17:animal-sniffer-annotations-1.17.jar:92654f493ecfec52082e76354f0ebf87648dc3d5cec2e3c3cdb947c016747a53',
'org.glassfish.jaxb:jaxb-core:2.2.11:jaxb-core-2.2.11.jar:37bcaee8ebb04362c8352a5bf6221b86967ecdab5164c696b10b9a2bb587b2aa',
'org.glassfish.jaxb:jaxb-runtime:2.2.11:jaxb-runtime-2.2.11.jar:a874f2351cfba8e2946be3002d10c18a6da8f21b52ba2acf52f2b85d5520ed70',
'org.glassfish.jaxb:txw2:2.2.11:txw2-2.2.11.jar:272a3ccad45a4511351920cd2a8633c53cab8d5220c7a92954da5526bb5eafea',
'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.jetbrains.kotlin:kotlin-reflect:1.2.0:kotlin-reflect-1.2.0.jar:4f48a872bad6e4d9c053f4ad610d11e4012ad7e58dc19a03dd5eb811f36069dd',
'org.jetbrains.kotlin:kotlin-stdlib-jre7:1.2.0:kotlin-stdlib-jre7-1.2.0.jar:c7a20fb951d437797afe8980aff6c1e5a03f310c661ba58ba1d4fa90cb0f2926',
'org.jetbrains.kotlin:kotlin-stdlib-jre8:1.2.0:kotlin-stdlib-jre8-1.2.0.jar:633524eee6ef1941f7cb1dab7ee3927b0a221ceee9047aeb5515f4cbb990c82a',
'org.jetbrains.kotlin:kotlin-stdlib:1.2.0:kotlin-stdlib-1.2.0.jar:05cfd9f5ac0b41910703a8925f7211a495909b27a2ffdd1c5106f1689aeafcd4',
'org.jetbrains.kotlin:kotlin-reflect:1.3.50:kotlin-reflect-1.3.50.jar:64583199ea5a54aefd1bd1595288925f784226ee562d1dd279011c6075b3d7a4',
'org.jetbrains.kotlin:kotlin-stdlib-common:1.3.50:kotlin-stdlib-common-1.3.50.jar:8ce678e88e4ba018b66dacecf952471e4d7dfee156a8a819760a5a5ff29d323c',
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.50:kotlin-stdlib-jdk7-1.3.50.jar:9a026639e76212f8d57b86d55b075394c2e009f1979110751d34c05c5f75d57b',
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.50:kotlin-stdlib-jdk8-1.3.50.jar:1b351fb6e09c14b55525c74c1f4cf48942eae43c348b7bc764a5e6e423d4da0c',
'org.jetbrains.kotlin:kotlin-stdlib:1.3.50:kotlin-stdlib-1.3.50.jar:e6f05746ee0366d0b52825a090fac474dcf44082c9083bbb205bd16976488d6c',
'org.jetbrains.trove4j:trove4j:20160824:trove4j-20160824.jar:1917871c8deb468307a584680c87a44572f5a8b0b98c6d397fc0f5f86596dbe7',
'org.jetbrains:annotations:13.0:annotations-13.0.jar:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478',
'org.jmock:jmock-junit4:2.8.2:jmock-junit4-2.8.2.jar:f7ee4df4f7bd7b7f1cafad3b99eb74d579f109d5992ff625347352edb55e674c',
@@ -81,11 +93,11 @@ dependencyVerification {
'org.jmock:jmock:2.8.2:jmock-2.8.2.jar:6c73cb4a2e6dbfb61fd99c9a768539c170ab6568e57846bd60dbf19596b65b16',
'org.jvnet.staxex:stax-ex:1.7.7:stax-ex-1.7.7.jar:a31ff7d77163c0deb09e7fee59ad35ae44c2cee2cc8552a116ccd1583d813fb4',
'org.objenesis:objenesis:2.1:objenesis-2.1.jar:c74330cc6b806c804fd37e74487b4fe5d7c2750c5e15fbc6efa13bdee1bdef80',
'org.ow2.asm:asm-analysis:5.1:asm-analysis-5.1.jar:a34658f5c5de4b573eef21131cc32cc25f7b66407944f312b28ec2e56abb1fa9',
'org.ow2.asm:asm-commons:5.1:asm-commons-5.1.jar:97b3786e1f55e74bddf8ad102bf50e33bbcbc1f6b7fd7b36f0bbbb25cd4981be',
'org.ow2.asm:asm-tree:5.1:asm-tree-5.1.jar:c0de2bbc4cb8297419659813ecd4ed1d077ed1dd5c1f5544cc5143e493e84c10',
'org.ow2.asm:asm-util:5.1:asm-util-5.1.jar:ee032c39ae5e3cd099148fbba9a2124f9ed613e5cb93e03ee0fa8808ce364040',
'org.ow2.asm:asm-analysis:6.0:asm-analysis-6.0.jar:2f1a6387219c3a6cc4856481f221b03bd9f2408a326d416af09af5d6f608c1f4',
'org.ow2.asm:asm-commons:6.0:asm-commons-6.0.jar:f1bce5c648a96a017bdcd01fe5d59af9845297fd7b79b81c015a6fbbd9719abf',
'org.ow2.asm:asm-tree:6.0:asm-tree-6.0.jar:887998fb69727c8759e4d253f856822801e33f9fd4caa566b3ac58ee92106215',
'org.ow2.asm:asm-util:6.0:asm-util-6.0.jar:356afebdb0f870175262e5188f8709a3b17aa2a5a6a4b0340b04d4b449bca5f6',
'org.ow2.asm:asm:5.0.4:asm-5.0.4.jar:896618ed8ae62702521a78bc7be42b7c491a08e6920a15f89a3ecdec31e9a220',
'org.ow2.asm:asm:5.1:asm-5.1.jar:d2da399a9967c69f0a21739256fa79d284222c223082cacadc17372244764b54',
'org.ow2.asm:asm:6.0:asm-6.0.jar:dd8971c74a4e697899a8e95caae4ea8760ea6c486dc6b97b1795e75760420461',
]
}
+1 -3
View File
@@ -7,15 +7,13 @@ apply plugin: 'witness'
apply from: 'witness.gradle'
dependencies {
implementation "com.google.dagger:dagger:2.0.2"
implementation "com.google.dagger:dagger:2.24"
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"
signature 'org.codehaus.mojo.signature:java16:1.1@signature'
}
@@ -4,8 +4,8 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.util.StringUtils;
import java.util.Arrays;
import java.util.Comparator;
import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
/**
@@ -15,8 +15,6 @@ import javax.annotation.concurrent.ThreadSafe;
@NotNullByDefault
public class Bytes implements Comparable<Bytes> {
public static final BytesComparator COMPARATOR = new BytesComparator();
private final byte[] bytes;
private int hashCode = -1;
@@ -38,20 +36,13 @@ public class Bytes implements Comparable<Bytes> {
}
@Override
public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
return o instanceof Bytes && Arrays.equals(bytes, ((Bytes) o).bytes);
}
@Override
public int compareTo(Bytes other) {
byte[] aBytes = bytes, bBytes = other.bytes;
int length = Math.min(aBytes.length, bBytes.length);
for (int i = 0; i < length; i++) {
int aUnsigned = aBytes[i] & 0xFF, bUnsigned = bBytes[i] & 0xFF;
if (aUnsigned < bUnsigned) return -1;
if (aUnsigned > bUnsigned) return 1;
}
return aBytes.length - bBytes.length;
return compare(bytes, other.bytes);
}
@Override
@@ -60,11 +51,13 @@ public class Bytes implements Comparable<Bytes> {
"(" + StringUtils.toHexString(getBytes()) + ")";
}
public static class BytesComparator implements Comparator<Bytes> {
@Override
public int compare(Bytes a, Bytes b) {
return a.compareTo(b);
public static int compare(byte[] a, byte[] b) {
int length = Math.min(a.length, b.length);
for (int i = 0; i < length; i++) {
int aUnsigned = a[i] & 0xFF, bUnsigned = b[i] & 0xFF;
if (aUnsigned < bUnsigned) return -1;
if (aUnsigned > bUnsigned) return 1;
}
return a.length - b.length;
}
}
@@ -0,0 +1,9 @@
package org.briarproject.bramble.api;
/**
* Interface for specifying which features are enabled in a build.
*/
public interface FeatureFlags {
boolean shouldEnableImageAttachments();
}
@@ -0,0 +1,10 @@
package org.briarproject.bramble.api;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface Nameable {
String getName();
}
@@ -0,0 +1,26 @@
package org.briarproject.bramble.api;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
@Immutable
@NotNullByDefault
public class Pair<A, B> {
private final A first;
private final B second;
public Pair(A first, B second) {
this.first = first;
this.second = second;
}
public A getFirst() {
return first;
}
public B getSecond() {
return second;
}
}
@@ -0,0 +1,9 @@
package org.briarproject.bramble.api;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface Predicate<T> {
boolean test(T t);
}
@@ -38,4 +38,18 @@ public abstract class StringMap extends Hashtable<String, String> {
public void putInt(String key, int value) {
put(key, String.valueOf(value));
}
public long getLong(String key, long defaultValue) {
String s = get(key);
if (s == null) return defaultValue;
try {
return Long.valueOf(s);
} catch (NumberFormatException e) {
return defaultValue;
}
}
public void putLong(String key, long value) {
put(key, String.valueOf(value));
}
}
@@ -1,9 +1,18 @@
package org.briarproject.bramble.api;
import java.io.IOException;
/**
* An exception that indicates an unrecoverable version mismatch.
* Thrown when data being parsed uses a protocol or format version that is not
* supported.
*/
public class UnsupportedVersionException extends IOException {
public class UnsupportedVersionException extends FormatException {
private final boolean tooOld;
public UnsupportedVersionException(boolean tooOld) {
this.tooOld = tooOld;
}
public boolean isTooOld() {
return tooOld;
}
}
@@ -0,0 +1,6 @@
package org.briarproject.bramble.api.battery;
public interface BatteryManager {
boolean isCharging();
}
@@ -0,0 +1,19 @@
package org.briarproject.bramble.api.battery.event;
import org.briarproject.bramble.api.event.Event;
/**
* An event that is broadcast when the device starts or stops charging.
*/
public class BatteryEvent extends Event {
private final boolean charging;
public BatteryEvent(boolean charging) {
this.charging = charging;
}
public boolean isCharging() {
return charging;
}
}
@@ -1,7 +1,6 @@
package org.briarproject.briar.client;
package org.briarproject.bramble.api.client;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.data.MetadataParser;
@@ -12,7 +11,7 @@ import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.InvalidMessageException;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.ValidationManager.IncomingMessageHook;
import org.briarproject.bramble.api.sync.validation.IncomingMessageHook;
import javax.annotation.concurrent.Immutable;
@@ -34,7 +33,8 @@ public abstract class BdfIncomingMessageHook implements IncomingMessageHook {
/**
* Called once for each incoming message that passes validation.
*
* @return whether or not this message should be shared
* @param txn A read-write transaction
* @return Whether or not this message should be shared
* @throws DbException Should only be used for real database errors.
* If this is thrown, delivery will be attempted again at next startup,
* whereas if a FormatException is thrown, the message will be permanently
@@ -62,5 +62,4 @@ public abstract class BdfIncomingMessageHook implements IncomingMessageHook {
throw new InvalidMessageException(e);
}
}
}
@@ -9,7 +9,7 @@ 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.sync.validation.MessageValidator;
import org.briarproject.bramble.api.system.Clock;
import java.util.logging.Logger;
@@ -48,12 +48,8 @@ public abstract class BdfMessageValidator implements MessageValidator {
throw new InvalidMessageException(
"Timestamp is too far in the future");
}
byte[] body = m.getBody();
if (body.length == 0) {
throw new InvalidMessageException("Message is too short");
}
try {
BdfList bodyList = clientHelper.toList(body);
BdfList bodyList = clientHelper.toList(m.getBody());
BdfMessageContext result = validateMessage(m, g, bodyList);
Metadata meta = metadataEncoder.encode(result.getDictionary());
return new MessageContext(meta, result.getDependencies());
@@ -1,6 +1,8 @@
package org.briarproject.bramble.api.client;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.db.DbException;
@@ -23,7 +25,10 @@ public interface ClientHelper {
throws DbException, FormatException;
void addLocalMessage(Transaction txn, Message m, BdfDictionary metadata,
boolean shared) throws DbException, FormatException;
boolean shared, boolean temporary)
throws DbException, FormatException;
Message createMessage(GroupId g, long timestamp, byte[] body);
Message createMessage(GroupId g, long timestamp, BdfList body)
throws FormatException;
@@ -96,14 +101,18 @@ public interface ClientHelper {
BdfList toList(Author a);
byte[] sign(String label, BdfList toSign, byte[] privateKey)
byte[] sign(String label, BdfList toSign, PrivateKey privateKey)
throws FormatException, GeneralSecurityException;
void verifySignature(byte[] signature, String label, BdfList signed,
byte[] publicKey) throws FormatException, GeneralSecurityException;
PublicKey publicKey)
throws FormatException, GeneralSecurityException;
Author parseAndValidateAuthor(BdfList author) throws FormatException;
PublicKey parseAndValidateAgreementPublicKey(byte[] publicKeyBytes)
throws FormatException;
TransportProperties parseAndValidateTransportProperties(
BdfDictionary properties) throws FormatException;
@@ -1,11 +1,16 @@
package org.briarproject.bramble.api.contact;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.util.StringUtils.toUtf8;
@Immutable
@NotNullByDefault
public class Contact {
@@ -13,15 +18,26 @@ public class Contact {
private final ContactId id;
private final Author author;
private final AuthorId localAuthorId;
private final boolean verified, active;
@Nullable
private final String alias;
@Nullable
private final PublicKey handshakePublicKey;
private final boolean verified;
public Contact(ContactId id, Author author, AuthorId localAuthorId,
boolean verified, boolean active) {
@Nullable String alias, @Nullable PublicKey handshakePublicKey,
boolean verified) {
if (alias != null) {
int aliasLength = toUtf8(alias).length;
if (aliasLength == 0 || aliasLength > MAX_AUTHOR_NAME_LENGTH)
throw new IllegalArgumentException();
}
this.id = id;
this.author = author;
this.localAuthorId = localAuthorId;
this.alias = alias;
this.handshakePublicKey = handshakePublicKey;
this.verified = verified;
this.active = active;
}
public ContactId getId() {
@@ -36,12 +52,18 @@ public class Contact {
return localAuthorId;
}
public boolean isVerified() {
return verified;
@Nullable
public String getAlias() {
return alias;
}
public boolean isActive() {
return active;
@Nullable
public PublicKey getHandshakePublicKey() {
return handshakePublicKey;
}
public boolean isVerified() {
return verified;
}
@Override
@@ -1,20 +0,0 @@
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();
}
@@ -0,0 +1,37 @@
package org.briarproject.bramble.api.contact;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.ContactExistsException;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
import java.io.IOException;
@NotNullByDefault
public interface ContactExchangeManager {
/**
* Exchanges contact information with a remote peer and adds the peer
* as a contact.
*
* @param alice Whether the local peer takes the role of Alice
* @return The newly added contact
* @throws ContactExistsException If the contact already exists
*/
Contact exchangeContacts(DuplexTransportConnection conn,
SecretKey masterKey, boolean alice, boolean verified)
throws IOException, DbException;
/**
* Exchanges contact information with a remote peer and adds the peer
* as a contact, replacing the given pending contact.
*
* @param alice Whether the local peer takes the role of Alice
* @return The newly added contact
* @throws ContactExistsException If the contact already exists
*/
Contact exchangeContacts(PendingContactId p, DuplexTransportConnection conn,
SecretKey masterKey, boolean alice, boolean verified)
throws IOException, DbException;
}
@@ -1,48 +0,0 @@
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 {
/**
* The current version of the contact exchange protocol.
*/
byte PROTOCOL_VERSION = 1;
/**
* Label for deriving Alice's header key from the master secret.
*/
String ALICE_KEY_LABEL =
"org.briarproject.bramble.contact/ALICE_HEADER_KEY";
/**
* Label for deriving Bob's header key from the master secret.
*/
String BOB_KEY_LABEL = "org.briarproject.bramble.contact/BOB_HEADER_KEY";
/**
* Label for deriving Alice's key binding nonce from the master secret.
*/
String ALICE_NONCE_LABEL = "org.briarproject.bramble.contact/ALICE_NONCE";
/**
* Label for deriving Bob's key binding nonce from the master secret.
*/
String BOB_NONCE_LABEL = "org.briarproject.bramble.contact/BOB_NONCE";
/**
* Exchanges contact information with a remote peer.
*/
void startExchange(ContactExchangeListener listener,
LocalAuthor localAuthor, SecretKey masterSecret,
DuplexTransportConnection conn, TransportId transportId,
boolean alice);
}
@@ -2,6 +2,7 @@ package org.briarproject.bramble.api.contact;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
/**
@@ -28,7 +29,7 @@ public class ContactId {
}
@Override
public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
return o instanceof ContactId && id == ((ContactId) o).id;
}
}
@@ -1,15 +1,25 @@
package org.briarproject.bramble.api.contact;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.Pair;
import org.briarproject.bramble.api.UnsupportedVersionException;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.ContactExistsException;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.NoSuchContactException;
import org.briarproject.bramble.api.db.PendingContactExistsException;
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.identity.AuthorInfo;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.security.GeneralSecurityException;
import java.util.Collection;
import javax.annotation.Nullable;
@NotNullByDefault
public interface ContactManager {
@@ -22,60 +32,152 @@ public interface ContactManager {
/**
* Stores a contact associated with the given local and remote pseudonyms,
* derives and stores transport keys for each transport, and returns an ID
* for the contact.
* derives and stores rotation mode transport keys for each transport, and
* returns an ID for the contact.
*
* @param alice true if the local party is Alice
* @param rootKey The root key for a set of rotation mode transport keys
* @param timestamp The timestamp for deriving rotation mode transport
* keys from the root key
* @param alice True if the local party is Alice
* @param verified True if the contact's identity has been verified, which
* is true if the contact was added in person or false if the contact was
* introduced or added remotely
* @param active True if the rotation mode transport keys can be used for
* outgoing streams
*/
ContactId addContact(Transaction txn, Author remote, AuthorId local,
SecretKey master, long timestamp, boolean alice, boolean verified,
SecretKey rootKey, long timestamp, boolean alice, boolean verified,
boolean active) throws DbException;
/**
* Stores a contact associated with the given local and remote pseudonyms,
* replacing the given pending contact, derives and stores handshake mode
* and rotation mode transport keys for each transport, and returns an ID
* for the contact.
*
* @param rootKey The root key for a set of rotation mode transport keys
* @param timestamp The timestamp for deriving rotation mode transport
* keys from the root key
* @param alice True if the local party is Alice
* @param verified True if the contact's identity has been verified, which
* is true if the contact was added in person or false if the contact was
* introduced or added remotely
* @param active True if the rotation mode transport keys can be used for
* outgoing streams
* @throws GeneralSecurityException If the pending contact's handshake
* public key is invalid
*/
ContactId addContact(Transaction txn, PendingContactId p, Author remote,
AuthorId local, SecretKey rootKey, long timestamp, boolean alice,
boolean verified, boolean active)
throws DbException, GeneralSecurityException;
/**
* Stores a contact associated with the given local and remote pseudonyms
* and returns an ID for the contact.
*
* @param verified True if the contact's identity has been verified, which
* is true if the contact was added in person or false if the contact was
* introduced or added remotely
*/
ContactId addContact(Transaction txn, Author remote, AuthorId local,
boolean verified, boolean active) throws DbException;
boolean verified) throws DbException;
/**
* Stores a contact associated with the given local and remote pseudonyms,
* derives and stores transport keys for each transport, and returns an ID
* for the contact.
* derives and stores rotation mode transport keys for each transport, and
* returns an ID for the contact.
*
* @param alice true if the local party is Alice
* @param rootKey The root key for a set of rotation mode transport keys
* @param timestamp The timestamp for deriving rotation mode transport
* keys from the root key
* @param alice True if the local party is Alice
* @param verified True if the contact's identity has been verified, which
* is true if the contact was added in person or false if the contact was
* introduced or added remotely
* @param active True if the rotation mode transport keys can be used for
* outgoing streams
*/
ContactId addContact(Author remote, AuthorId local, SecretKey master,
ContactId addContact(Author remote, AuthorId local, SecretKey rootKey,
long timestamp, boolean alice, boolean verified, boolean active)
throws DbException;
/**
* Returns the handshake link that needs to be sent to a contact we want
* to add.
*/
String getHandshakeLink() throws DbException;
/**
* Creates a {@link PendingContact} from the given handshake link and
* alias, adds it to the database and returns it.
*
* @param link The handshake link received from the pending contact
* @param alias The alias the user has given this pending contact
* @throws UnsupportedVersionException If the link uses a format version
* that is not supported
* @throws FormatException If the link is invalid
* @throws GeneralSecurityException If the pending contact's handshake
* public key is invalid
* @throws ContactExistsException If a contact with the same handshake
* public key already exists
* @throws PendingContactExistsException If a pending contact with the same
* handshake public key already exists
*/
PendingContact addPendingContact(String link, String alias)
throws DbException, FormatException, GeneralSecurityException,
ContactExistsException, PendingContactExistsException;
/**
* Returns the pending contact with the given ID.
*/
PendingContact getPendingContact(Transaction txn, PendingContactId p)
throws DbException;
/**
* Returns a list of {@link PendingContact PendingContacts} and their
* {@link PendingContactState states}.
*/
Collection<Pair<PendingContact, PendingContactState>> getPendingContacts()
throws DbException;
/**
* Removes a {@link PendingContact}.
*/
void removePendingContact(PendingContactId p) 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
* Returns the contact with the given ID.
*/
Contact getContact(Transaction txn, ContactId c) throws DbException;
/**
* Returns the contact with the given {@code remoteAuthorId}
* that belongs to the local pseudonym with the given {@code localAuthorId}.
*
* @throws org.briarproject.bramble.api.db.NoSuchContactException
* @throws NoSuchContactException If the contact is not in the database
*/
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
* Returns the contact with the given {@code remoteAuthorId}
* that belongs to the local pseudonym with the given {@code localAuthorId}.
*
* @throws org.briarproject.bramble.api.db.NoSuchContactException
* @throws NoSuchContactException If the contact is not in the database
*/
Contact getContact(Transaction txn, AuthorId remoteAuthorId,
AuthorId localAuthorId) throws DbException;
/**
* Returns all active contacts.
* Returns all contacts.
*/
Collection<Contact> getActiveContacts() throws DbException;
Collection<Contact> getContacts() throws DbException;
/**
* Removes a contact and all associated state.
@@ -88,27 +190,57 @@ public interface ContactManager {
void removeContact(Transaction txn, ContactId c) throws DbException;
/**
* Marks a contact as active or inactive.
* Sets an alias for the contact or unsets it if {@code alias} is null.
*/
void setContactActive(Transaction txn, ContactId c, boolean active)
void setContactAlias(Transaction txn, ContactId c, @Nullable String alias)
throws DbException;
/**
* Return true if a contact with this name and public key already exists
* Sets an alias for the contact or unsets it if {@code alias} is null.
*/
void setContactAlias(ContactId c, @Nullable String alias)
throws DbException;
/**
* Returns true if a contact with this {@code remoteAuthorId} belongs to
* the local pseudonym with this {@code localAuthorId}.
*/
boolean contactExists(Transaction txn, AuthorId remoteAuthorId,
AuthorId localAuthorId) throws DbException;
/**
* Return true if a contact with this name and public key already exists
* Returns true if a contact with this {@code remoteAuthorId} belongs to
* the local pseudonym with this {@code localAuthorId}.
*/
boolean contactExists(AuthorId remoteAuthorId, AuthorId localAuthorId)
throws DbException;
/**
* Returns the {@link AuthorInfo} for the given author.
*/
AuthorInfo getAuthorInfo(AuthorId a) throws DbException;
/**
* Returns the {@link AuthorInfo} for the given author.
*/
AuthorInfo getAuthorInfo(Transaction txn, AuthorId a) throws DbException;
interface ContactHook {
/**
* Called when a contact is being added.
*
* @param txn A read-write transaction
* @param c The contact that is being added
*/
void addingContact(Transaction txn, Contact c) throws DbException;
/**
* Called when a contact is being removed
*
* @param txn A read-write transaction
* @param c The contact that is being removed
*/
void removingContact(Transaction txn, Contact c) throws DbException;
}
}
@@ -0,0 +1,34 @@
package org.briarproject.bramble.api.contact;
import java.util.regex.Pattern;
public interface HandshakeLinkConstants {
/**
* The current version of the handshake link format.
*/
int FORMAT_VERSION = 0;
/**
* The length of a base32-encoded handshake link in bytes, excluding the
* 'briar://' prefix.
*/
int BASE32_LINK_BYTES = 53;
/**
* The length of a raw handshake link in bytes, before base32 encoding.
*/
int RAW_LINK_BYTES = 33;
/**
* Regular expression for matching handshake links, including or excluding
* the 'briar://' prefix.
*/
Pattern LINK_REGEX =
Pattern.compile("(briar://)?([a-z2-7]{" + BASE32_LINK_BYTES + "})");
/**
* Label for hashing handshake public keys to calculate their identifiers.
*/
String ID_LABEL = "org.briarproject.bramble/HANDSHAKE_KEY_ID";
}
@@ -0,0 +1,45 @@
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.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.transport.StreamWriter;
import java.io.IOException;
import java.io.InputStream;
@NotNullByDefault
public interface HandshakeManager {
/**
* Handshakes with the given pending contact. Returns an ephemeral master
* key authenticated with both parties' handshake key pairs and a flag
* indicating whether the local peer is Alice or Bob.
*
* @param in An incoming stream for the handshake, which must be secured in
* handshake mode
* @param out An outgoing stream for the handshake, which must be secured
* in handshake mode
*/
HandshakeResult handshake(PendingContactId p, InputStream in,
StreamWriter out) throws DbException, IOException;
class HandshakeResult {
private final SecretKey masterKey;
private final boolean alice;
public HandshakeResult(SecretKey masterKey, boolean alice) {
this.masterKey = masterKey;
this.alice = alice;
}
public SecretKey getMasterKey() {
return masterKey;
}
public boolean isAlice() {
return alice;
}
}
}
@@ -0,0 +1,51 @@
package org.briarproject.bramble.api.contact;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
@Immutable
@NotNullByDefault
public class PendingContact {
private final PendingContactId id;
private final PublicKey publicKey;
private final String alias;
private final long timestamp;
public PendingContact(PendingContactId id, PublicKey publicKey,
String alias, long timestamp) {
this.id = id;
this.publicKey = publicKey;
this.alias = alias;
this.timestamp = timestamp;
}
public PendingContactId getId() {
return id;
}
public PublicKey getPublicKey() {
return publicKey;
}
public String getAlias() {
return alias;
}
public long getTimestamp() {
return timestamp;
}
@Override
public int hashCode() {
return id.hashCode();
}
@Override
public boolean equals(Object o) {
return o instanceof PendingContact &&
id.equals(((PendingContact) o).id);
}
}
@@ -0,0 +1,25 @@
package org.briarproject.bramble.api.contact;
import org.briarproject.bramble.api.UniqueId;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
/**
* Type-safe wrapper for a byte array that uniquely identifies a
* {@link PendingContact}.
*/
@ThreadSafe
@NotNullByDefault
public class PendingContactId extends UniqueId {
public PendingContactId(byte[] id) {
super(id);
}
@Override
public boolean equals(@Nullable Object o) {
return o instanceof PendingContactId && super.equals(o);
}
}
@@ -0,0 +1,10 @@
package org.briarproject.bramble.api.contact;
public enum PendingContactState {
WAITING_FOR_CONNECTION,
OFFLINE,
CONNECTING,
ADDING_CONTACT,
FAILED
}
@@ -14,18 +14,18 @@ import javax.annotation.concurrent.Immutable;
public class ContactAddedEvent extends Event {
private final ContactId contactId;
private final boolean active;
private final boolean verified;
public ContactAddedEvent(ContactId contactId, boolean active) {
public ContactAddedEvent(ContactId contactId, boolean verified) {
this.contactId = contactId;
this.active = active;
this.verified = verified;
}
public ContactId getContactId() {
return contactId;
}
public boolean isActive() {
return active;
public boolean isVerified() {
return verified;
}
}
@@ -1,31 +0,0 @@
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;
}
}
@@ -0,0 +1,25 @@
package org.briarproject.bramble.api.contact.event;
import org.briarproject.bramble.api.contact.PendingContact;
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 pending contact is added.
*/
@Immutable
@NotNullByDefault
public class PendingContactAddedEvent extends Event {
private final PendingContact pendingContact;
public PendingContactAddedEvent(PendingContact pendingContact) {
this.pendingContact = pendingContact;
}
public PendingContact getPendingContact() {
return pendingContact;
}
}
@@ -0,0 +1,26 @@
package org.briarproject.bramble.api.contact.event;
import org.briarproject.bramble.api.contact.PendingContactId;
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 pending contact is removed.
*/
@Immutable
@NotNullByDefault
public class PendingContactRemovedEvent extends Event {
private final PendingContactId id;
public PendingContactRemovedEvent(PendingContactId id) {
this.id = id;
}
public PendingContactId getId() {
return id;
}
}
@@ -0,0 +1,34 @@
package org.briarproject.bramble.api.contact.event;
import org.briarproject.bramble.api.contact.PendingContactId;
import org.briarproject.bramble.api.contact.PendingContactState;
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 pending contact's state is changed.
*/
@Immutable
@NotNullByDefault
public class PendingContactStateChangedEvent extends Event {
private final PendingContactId id;
private final PendingContactState state;
public PendingContactStateChangedEvent(PendingContactId id,
PendingContactState state) {
this.id = id;
this.state = state;
}
public PendingContactId getId() {
return id;
}
public PendingContactState getPendingContactState() {
return state;
}
}
@@ -0,0 +1,30 @@
package org.briarproject.bramble.api.crypto;
import org.briarproject.bramble.api.Bytes;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.crypto.CryptoConstants.KEY_TYPE_AGREEMENT;
/**
* Type-safe wrapper for a private key used for key agreement.
*/
@Immutable
@NotNullByDefault
public class AgreementPrivateKey extends Bytes implements PrivateKey {
public AgreementPrivateKey(byte[] encoded) {
super(encoded);
}
@Override
public String getKeyType() {
return KEY_TYPE_AGREEMENT;
}
@Override
public byte[] getEncoded() {
return getBytes();
}
}
@@ -0,0 +1,35 @@
package org.briarproject.bramble.api.crypto;
import org.briarproject.bramble.api.Bytes;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.crypto.CryptoConstants.KEY_TYPE_AGREEMENT;
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_AGREEMENT_PUBLIC_KEY_BYTES;
/**
* Type-safe wrapper for a public key used for key agreement.
*/
@Immutable
@NotNullByDefault
public class AgreementPublicKey extends Bytes implements PublicKey {
public AgreementPublicKey(byte[] encoded) {
super(encoded);
if (encoded.length == 0 ||
encoded.length > MAX_AGREEMENT_PUBLIC_KEY_BYTES) {
throw new IllegalArgumentException();
}
}
@Override
public String getKeyType() {
return KEY_TYPE_AGREEMENT;
}
@Override
public byte[] getEncoded() {
return getBytes();
}
}
@@ -27,54 +27,78 @@ public interface CryptoComponent {
/**
* Derives another secret key from the given secret key.
*
* @param label a namespaced label indicating the purpose of the derived
* @param label A namespaced label indicating the purpose of the derived
* key, to prevent it from being repurposed or colliding with a key derived
* for another purpose
* @param inputs Additional inputs that will be included in the derivation
* of the key
*/
SecretKey deriveKey(String label, SecretKey k, byte[]... inputs);
/**
* Derives a common shared secret from two public keys and one of the
* corresponding private keys.
* Derives a shared secret from two key pairs.
*
* @param label a namespaced label indicating the purpose of this shared
* @param label A namespaced label indicating the purpose of this shared
* secret, to prevent it from being repurposed or colliding with a shared
* secret derived for another purpose
* @param theirPublicKey the public key of the remote party
* @param ourKeyPair the key pair of the local party
* @return the shared secret
* @param theirPublicKey The public key of the remote party
* @param ourKeyPair The key pair of the local party
* @param inputs Additional inputs that will be included in the derivation
* of the shared secret
* @return The shared secret
*/
SecretKey deriveSharedSecret(String label, PublicKey theirPublicKey,
KeyPair ourKeyPair, byte[]... inputs)
throws GeneralSecurityException;
/**
* Derives a shared secret from two static and two ephemeral key pairs.
*
* @param label A namespaced label indicating the purpose of this shared
* secret, to prevent it from being repurposed or colliding with a shared
* secret derived for another purpose
* @param theirStaticPublicKey The static public key of the remote party
* @param theirEphemeralPublicKey The ephemeral public key of the remote
* party
* @param ourStaticKeyPair The static key pair of the local party
* @param ourEphemeralKeyPair The ephemeral key pair of the local party
* @param alice True if the local party is Alice
* @param inputs Additional inputs that will be included in the
* derivation of the shared secret
* @return The shared secret
*/
SecretKey deriveSharedSecret(String label, PublicKey theirStaticPublicKey,
PublicKey theirEphemeralPublicKey, KeyPair ourStaticKeyPair,
KeyPair ourEphemeralKeyPair, boolean alice, byte[]... inputs)
throws GeneralSecurityException;
/**
* Signs the given byte[] with the given private key.
*
* @param label a namespaced label indicating the purpose of this
* @param label A namespaced label indicating the purpose of this
* signature, to prevent it from being repurposed or colliding with a
* signature created for another purpose
*/
byte[] sign(String label, byte[] toSign, byte[] privateKey)
byte[] sign(String label, byte[] toSign, PrivateKey privateKey)
throws GeneralSecurityException;
/**
* Verifies that the given signature is valid for the signed data
* and the given public key.
*
* @param label a namespaced label indicating the purpose of this
* @param label A namespaced label indicating the purpose of this
* signature, to prevent it from being repurposed or colliding with a
* signature created for another purpose
* @return true if the signature was valid, false otherwise.
* @return True if the signature was valid, false otherwise.
*/
boolean verifySignature(byte[] signature, String label, byte[] signed,
byte[] publicKey) throws GeneralSecurityException;
PublicKey publicKey) throws GeneralSecurityException;
/**
* Returns the hash of the given inputs. The inputs are unambiguously
* combined by prefixing each input with its length.
*
* @param label a namespaced label indicating the purpose of this hash, to
* @param label A namespaced label indicating the purpose of this hash, to
* prevent it from being repurposed or colliding with a hash created for
* another purpose
*/
@@ -85,7 +109,7 @@ public interface CryptoComponent {
* given inputs. The inputs are unambiguously combined by prefixing each
* input with its length.
*
* @param label a namespaced label indicating the purpose of this MAC, to
* @param label A namespaced label indicating the purpose of this MAC, to
* prevent it from being repurposed or colliding with a MAC created for
* another purpose
*/
@@ -95,10 +119,10 @@ public interface CryptoComponent {
* Verifies that the given message authentication code is valid for the
* given secret key and inputs.
*
* @param label a namespaced label indicating the purpose of this MAC, to
* @param label A namespaced label indicating the purpose of this MAC, to
* prevent it from being repurposed or colliding with a MAC created for
* another purpose
* @return true if the MAC was valid, false otherwise.
* @return True if the MAC was valid, false otherwise.
*/
boolean verifyMac(byte[] mac, String label, SecretKey macKey,
byte[]... inputs);
@@ -108,17 +132,32 @@ public interface CryptoComponent {
* storage. The encryption and authentication keys are derived from the
* given password. The ciphertext will be decryptable using the same
* password after the app restarts.
*
* @param keyStrengthener Used to strengthen the password-based key. If
* null, the password-based key will not be strengthened
*/
byte[] encryptWithPassword(byte[] plaintext, String password);
byte[] encryptWithPassword(byte[] plaintext, String password,
@Nullable KeyStrengthener keyStrengthener);
/**
* Decrypts and authenticates the given ciphertext that has been read from
* storage. The encryption and authentication keys are derived from the
* given password. Returns null if the ciphertext cannot be decrypted and
* authenticated (for example, if the password is wrong).
*
* @param keyStrengthener Used to strengthen the password-based key. If
* null, or if strengthening was not used when encrypting the ciphertext,
* the password-based key will not be strengthened
*/
@Nullable
byte[] decryptWithPassword(byte[] ciphertext, String password);
byte[] decryptWithPassword(byte[] ciphertext, String password,
@Nullable KeyStrengthener keyStrengthener);
/**
* Returns true if the given ciphertext was encrypted using a strengthened
* key. The validity of the ciphertext is not checked.
*/
boolean isEncryptedWithStrengthenedKey(byte[] ciphertext);
/**
* Encrypts the given plaintext to the given public key.
@@ -7,11 +7,21 @@ public interface CryptoConstants {
*/
int MAX_AGREEMENT_PUBLIC_KEY_BYTES = 32;
/**
* The key type for agreement key pairs.
*/
String KEY_TYPE_AGREEMENT = "Curve25519";
/**
* The maximum length of a signature public key in bytes.
*/
int MAX_SIGNATURE_PUBLIC_KEY_BYTES = 32;
/**
* The key type for signature key pairs.
*/
String KEY_TYPE_SIGNATURE = "Ed25519";
/**
* The maximum length of a signature in bytes.
*/
@@ -2,7 +2,7 @@ package org.briarproject.bramble.api.crypto;
/**
* Crypto operations for the key agreement protocol - see
* https://code.briarproject.org/akwizgran/briar-spec/blob/master/protocols/BQP.md
* https://code.briarproject.org/briar/briar-spec/blob/master/protocols/BQP.md
*/
public interface KeyAgreementCrypto {
@@ -15,6 +15,8 @@ public class KeyPair {
private final PrivateKey privateKey;
public KeyPair(PublicKey publicKey, PrivateKey privateKey) {
if (!publicKey.getKeyType().equals(privateKey.getKeyType()))
throw new IllegalArgumentException();
this.publicKey = publicKey;
this.privateKey = privateKey;
}
@@ -0,0 +1,23 @@
package org.briarproject.bramble.api.crypto;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
/**
* Interface for strengthening a password-based key, for example by using a
* key stored in a key management service or hardware security module.
*/
@NotNullByDefault
public interface KeyStrengthener {
/**
* Returns true if the strengthener has been initialised.
*/
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
boolean isInitialised();
/**
* Initialises the strengthener if necessary and returns a strong key
* derived from the given key.
*/
SecretKey strengthenKey(SecretKey k);
}
@@ -8,6 +8,11 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface PrivateKey {
/**
* Returns the type of this key pair.
*/
String getKeyType();
/**
* Returns the encoded representation of this key.
*/
@@ -8,6 +8,11 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface PublicKey {
/**
* Returns the type of this key pair.
*/
String getKeyType();
/**
* Returns the encoded representation of this key.
*/
@@ -0,0 +1,30 @@
package org.briarproject.bramble.api.crypto;
import org.briarproject.bramble.api.Bytes;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.crypto.CryptoConstants.KEY_TYPE_SIGNATURE;
/**
* Type-safe wrapper for a public key used for signing.
*/
@Immutable
@NotNullByDefault
public class SignaturePrivateKey extends Bytes implements PrivateKey {
public SignaturePrivateKey(byte[] bytes) {
super(bytes);
}
@Override
public String getKeyType() {
return KEY_TYPE_SIGNATURE;
}
@Override
public byte[] getEncoded() {
return getBytes();
}
}
@@ -0,0 +1,35 @@
package org.briarproject.bramble.api.crypto;
import org.briarproject.bramble.api.Bytes;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.crypto.CryptoConstants.KEY_TYPE_SIGNATURE;
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_SIGNATURE_PUBLIC_KEY_BYTES;
/**
* Type-safe wrapper for a public key used for verifying signatures.
*/
@Immutable
@NotNullByDefault
public class SignaturePublicKey extends Bytes implements PublicKey {
public SignaturePublicKey(byte[] encoded) {
super(encoded);
if (encoded.length == 0 ||
encoded.length > MAX_SIGNATURE_PUBLIC_KEY_BYTES) {
throw new IllegalArgumentException();
}
}
@Override
public String getKeyType() {
return KEY_TYPE_SIGNATURE;
}
@Override
public byte[] getEncoded() {
return getBytes();
}
}
@@ -3,27 +3,61 @@ package org.briarproject.bramble.api.crypto;
import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.transport.TransportKeys;
import java.security.GeneralSecurityException;
/**
* Crypto operations for the transport security protocol - see
* https://code.briarproject.org/akwizgran/briar-spec/blob/master/protocols/BTP.md
* https://code.briarproject.org/briar/briar-spec/blob/master/protocols/BTP.md
*/
public interface TransportCrypto {
/**
* Derives initial transport keys for the given transport in the given
* rotation period from the given master secret.
*
* @param alice whether the keys are for use by Alice or Bob.
* @param active whether the keys are usable for outgoing streams.
* Returns true if the local peer is Alice.
*/
TransportKeys deriveTransportKeys(TransportId t, SecretKey master,
long rotationPeriod, boolean alice, boolean active);
boolean isAlice(PublicKey theirHandshakePublicKey,
KeyPair ourHandshakeKeyPair);
/**
* Rotates the given transport keys to the given rotation period. If the
* keys are for the given period or any later period they are not rotated.
* Derives the static master key shared with a contact or pending contact.
*/
TransportKeys rotateTransportKeys(TransportKeys k, long rotationPeriod);
SecretKey deriveStaticMasterKey(PublicKey theirHandshakePublicKey,
KeyPair ourHandshakeKeyPair) throws GeneralSecurityException;
/**
* Derives the handshake mode root key from the static master key. To
* prevent tag reuse, separate root keys are derived for contacts and
* pending contacts.
*
* @param pendingContact Whether the static master key is shared with a
* pending contact or a contact
*/
SecretKey deriveHandshakeRootKey(SecretKey staticMasterKey,
boolean pendingContact);
/**
* Derives initial rotation mode transport keys for the given transport in
* the given time period from the given root key.
*
* @param alice Whether the keys are for use by Alice or Bob
* @param active Whether the keys are usable for outgoing streams
*/
TransportKeys deriveRotationKeys(TransportId t, SecretKey rootKey,
long timePeriod, boolean alice, boolean active);
/**
* Derives handshake keys for the given transport in the given time period
* from the given root key.
*
* @param alice Whether the keys are for use by Alice or Bob
*/
TransportKeys deriveHandshakeKeys(TransportId t, SecretKey rootKey,
long timePeriod, boolean alice);
/**
* Updates the given transport keys to the given time period. If the keys
* are for the given period or any later period they are not updated.
*/
TransportKeys updateTransportKeys(TransportKeys k, long timePeriod);
/**
* Encodes the pseudo-random tag that is used to recognise a stream.
@@ -0,0 +1,71 @@
package org.briarproject.bramble.api.data;
import org.briarproject.bramble.api.Bytes;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.annotation.Nullable;
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
import static org.briarproject.bramble.util.StringUtils.toHexString;
@NotNullByDefault
public class BdfStringUtils {
public static String toString(@Nullable Object o) throws FormatException {
return toString(o, 0);
}
private static String toString(@Nullable Object o, int indent)
throws FormatException {
if (o == null || o == NULL_VALUE) return "null";
if (o instanceof Boolean) return o.toString();
if (o instanceof Number) return o.toString();
if (o instanceof String) return "\"" + o + "\"";
if (o instanceof Bytes)
return "x" + toHexString(((Bytes) o).getBytes());
if (o instanceof byte[])
return "x" + toHexString((byte[]) o);
if (o instanceof List) {
List<?> list = (List) o;
StringBuilder sb = new StringBuilder();
sb.append("[\n");
int i = 0, size = list.size();
for (Object e : list) {
indent(sb, indent + 1);
sb.append(toString(e, indent + 1));
if (i++ < size - 1) sb.append(',');
sb.append('\n');
}
indent(sb, indent);
sb.append(']');
return sb.toString();
}
if (o instanceof Map) {
Map<?, ?> map = (Map) o;
StringBuilder sb = new StringBuilder();
sb.append("{\n");
int i = 0, size = map.size();
for (Entry e : map.entrySet()) {
indent(sb, indent + 1);
sb.append(toString(e.getKey(), indent + 1));
sb.append(": ");
sb.append(toString(e.getValue(), indent + 1));
if (i++ < size - 1) sb.append(',');
sb.append('\n');
}
indent(sb, indent);
sb.append('}');
return sb.toString();
}
throw new FormatException();
}
private static void indent(StringBuilder sb, int indent) {
for (int i = 0; i < indent; i++) sb.append('\t');
}
}
@@ -0,0 +1,20 @@
package org.briarproject.bramble.api.db;
import org.briarproject.bramble.api.event.EventExecutor;
/**
* An action that's taken when a {@link Transaction} is committed.
*/
public interface CommitAction {
void accept(Visitor visitor);
interface Visitor {
@EventExecutor
void visit(EventAction a);
@EventExecutor
void visit(TaskAction a);
}
}
@@ -1,8 +1,27 @@
package org.briarproject.bramble.api.db;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
/**
* 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 {
private final AuthorId local;
private final Author remote;
public ContactExistsException(AuthorId local, Author remote) {
this.local = local;
this.remote = remote;
}
public AuthorId getLocalAuthorId() {
return local;
}
public Author getRemoteAuthor() {
return remote;
}
}
@@ -2,10 +2,14 @@ package org.briarproject.bramble.api.db;
import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.contact.PendingContact;
import org.briarproject.bramble.api.contact.PendingContactId;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.crypto.SecretKey;
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.identity.Identity;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.settings.Settings;
@@ -19,23 +23,23 @@ 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.transport.KeySet;
import org.briarproject.bramble.api.sync.validation.MessageState;
import org.briarproject.bramble.api.transport.KeySetId;
import org.briarproject.bramble.api.transport.TransportKeySet;
import org.briarproject.bramble.api.transport.TransportKeys;
import java.util.Collection;
import java.util.List;
import java.util.Map;
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 {
public interface DatabaseComponent extends TransactionManager {
/**
* Opens the database and returns true if the database already existed.
@@ -53,35 +57,12 @@ public interface DatabaseComponent {
*/
void close() throws DbException;
/**
* Starts a new transaction and returns an object representing it.
* <p/>
* This method acquires locks, so it must not be called while holding a
* lock.
*
* @param readOnly true if the transaction will only be used for reading.
*/
Transaction startTransaction(boolean readOnly) throws DbException;
/**
* Commits a transaction to the database.
*/
void commitTransaction(Transaction txn) throws DbException;
/**
* Ends a transaction. If the transaction has not been committed,
* it will be aborted. If the transaction has been committed,
* any events attached to the transaction are broadcast.
* The database lock will be released in either case.
*/
void endTransaction(Transaction txn);
/**
* Stores a contact associated with the given local and remote pseudonyms,
* and returns an ID for the contact.
*/
ContactId addContact(Transaction txn, Author remote, AuthorId local,
boolean verified, boolean active) throws DbException;
@Nullable PublicKey handshake, boolean verified) throws DbException;
/**
* Stores a group.
@@ -89,15 +70,21 @@ public interface DatabaseComponent {
void addGroup(Transaction txn, Group g) throws DbException;
/**
* Stores a local pseudonym.
* Stores an identity.
*/
void addLocalAuthor(Transaction txn, LocalAuthor a) throws DbException;
void addIdentity(Transaction txn, Identity i) throws DbException;
/**
* Stores a local message.
*/
void addLocalMessage(Transaction txn, Message m, Metadata meta,
boolean shared) throws DbException;
boolean shared, boolean temporary) throws DbException;
/**
* Stores a pending contact.
*/
void addPendingContact(Transaction txn, PendingContact p, AuthorId local)
throws DbException;
/**
* Stores a transport.
@@ -109,25 +96,46 @@ public interface DatabaseComponent {
* Stores the given transport keys for the given contact and returns a
* key set ID.
*/
KeySetId addTransportKeys(Transaction txn, ContactId c,
KeySetId addTransportKeys(Transaction txn, ContactId c, TransportKeys k)
throws DbException;
/**
* Stores the given transport keys for the given pending contact and
* returns a key set ID.
*/
KeySetId addTransportKeys(Transaction txn, PendingContactId p,
TransportKeys k) throws DbException;
/**
* Returns true if the database contains the given contact for the given
* local pseudonym.
* <p/>
* Read-only.
*/
boolean containsContact(Transaction txn, AuthorId remote, AuthorId local)
throws DbException;
/**
* Returns true if the database contains the given group.
* <p/>
* Read-only.
*/
boolean containsGroup(Transaction txn, GroupId g) throws DbException;
/**
* Returns true if the database contains the given local author.
* Returns true if the database contains an identity for the given
* pseudonym.
* <p/>
* Read-only.
*/
boolean containsLocalAuthor(Transaction txn, AuthorId local)
boolean containsIdentity(Transaction txn, AuthorId a) throws DbException;
/**
* Returns true if the database contains the given pending contact.
* <p/>
* Read-only.
*/
boolean containsPendingContact(Transaction txn, PendingContactId p)
throws DbException;
/**
@@ -215,7 +223,7 @@ public interface DatabaseComponent {
* <p/>
* Read-only.
*/
Collection<ContactId> getContacts(Transaction txn, AuthorId a)
Collection<ContactId> getContacts(Transaction txn, AuthorId local)
throws DbException;
/**
@@ -250,18 +258,18 @@ public interface DatabaseComponent {
throws DbException;
/**
* Returns the local pseudonym with the given ID.
* Returns the identity for the local pseudonym with the given ID.
* <p/>
* Read-only.
*/
LocalAuthor getLocalAuthor(Transaction txn, AuthorId a) throws DbException;
Identity getIdentity(Transaction txn, AuthorId a) throws DbException;
/**
* Returns all local pseudonyms.
* Returns the identities for all local pseudonyms.
* <p/>
* Read-only.
*/
Collection<LocalAuthor> getLocalAuthors(Transaction txn) throws DbException;
Collection<Identity> getIdentities(Transaction txn) throws DbException;
/**
* Returns the message with the given ID.
@@ -353,12 +361,12 @@ public interface DatabaseComponent {
/**
* Returns the IDs and states of all dependencies of the given message.
* For missing dependencies and dependencies in other groups, the state
* {@link State UNKNOWN} is returned.
* {@link MessageState UNKNOWN} is returned.
* <p/>
* Read-only.
*/
Map<MessageId, State> getMessageDependencies(Transaction txn, MessageId m)
throws DbException;
Map<MessageId, MessageState> getMessageDependencies(Transaction txn,
MessageId m) throws DbException;
/**
* Returns the IDs and states of all dependents of the given message.
@@ -367,15 +375,16 @@ public interface DatabaseComponent {
* <p/>
* Read-only.
*/
Map<MessageId, State> getMessageDependents(Transaction txn, MessageId m)
throws DbException;
Map<MessageId, MessageState> getMessageDependents(Transaction txn,
MessageId m) throws DbException;
/**
* Gets the validation and delivery state of the given message.
* <p/>
* Read-only.
*/
State getMessageState(Transaction txn, MessageId m) throws DbException;
MessageState getMessageState(Transaction txn, MessageId m)
throws DbException;
/**
* Returns the status of the given delivered message with respect to the
@@ -396,6 +405,22 @@ public interface DatabaseComponent {
*/
long getNextSendTime(Transaction txn, ContactId c) throws DbException;
/**
* Returns the pending contact with the given ID.
* <p/>
* Read-only.
*/
PendingContact getPendingContact(Transaction txn, PendingContactId p)
throws DbException;
/**
* Returns all pending contacts.
* <p/>
* Read-only.
*/
Collection<PendingContact> getPendingContacts(Transaction txn)
throws DbException;
/**
* Returns all settings in the given namespace.
* <p/>
@@ -403,12 +428,19 @@ public interface DatabaseComponent {
*/
Settings getSettings(Transaction txn, String namespace) throws DbException;
/**
* Returns the versions of the sync protocol supported by the given contact.
* <p/>
* Read-only.
*/
List<Byte> getSyncVersions(Transaction txn, ContactId c) throws DbException;
/**
* Returns all transport keys for the given transport.
* <p/>
* Read-only.
*/
Collection<KeySet> getTransportKeys(Transaction txn, TransportId t)
Collection<TransportKeySet> getTransportKeys(Transaction txn, TransportId t)
throws DbException;
/**
@@ -471,15 +503,27 @@ public interface DatabaseComponent {
void removeGroup(Transaction txn, Group g) throws DbException;
/**
* Removes a local pseudonym (and all associated state) from the database.
* Removes an identity (and all associated state) from the database.
*/
void removeLocalAuthor(Transaction txn, AuthorId a) throws DbException;
void removeIdentity(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 pending contact (and all associated state) from the database.
*/
void removePendingContact(Transaction txn, PendingContactId p)
throws DbException;
/**
* Removes all temporary messages (and all associated state) from the
* database.
*/
void removeTemporaryMessages(Transaction txn) throws DbException;
/**
* Removes a transport (and all associated state) from the database.
*/
@@ -497,9 +541,9 @@ public interface DatabaseComponent {
void setContactVerified(Transaction txn, ContactId c) throws DbException;
/**
* Marks the given contact as active or inactive.
* Sets an alias name for the contact or unsets it if alias is null.
*/
void setContactActive(Transaction txn, ContactId c, boolean active)
void setContactAlias(Transaction txn, ContactId c, @Nullable String alias)
throws DbException;
/**
@@ -508,6 +552,11 @@ public interface DatabaseComponent {
void setGroupVisibility(Transaction txn, ContactId c, GroupId g,
Visibility v) throws DbException;
/**
* Marks the given message as permanent, i.e. not temporary.
*/
void setMessagePermanent(Transaction txn, MessageId m) throws DbException;
/**
* Marks the given message as shared.
*/
@@ -516,7 +565,7 @@ public interface DatabaseComponent {
/**
* Sets the validation and delivery state of the given message.
*/
void setMessageState(Transaction txn, MessageId m, State state)
void setMessageState(Transaction txn, MessageId m, MessageState state)
throws DbException;
/**
@@ -526,11 +575,23 @@ public interface DatabaseComponent {
Collection<MessageId> dependencies) throws DbException;
/**
* Sets the reordering window for the given key set and transport in the
* given rotation period.
* Sets the handshake key pair for the identity with the given ID.
*/
void setHandshakeKeyPair(Transaction txn, AuthorId local,
PublicKey publicKey, PrivateKey privateKey) throws DbException;
/**
* Sets the reordering window for the given transport keys in the given
* time period.
*/
void setReorderingWindow(Transaction txn, KeySetId k, TransportId t,
long rotationPeriod, long base, byte[] bitmap) throws DbException;
long timePeriod, long base, byte[] bitmap) throws DbException;
/**
* Sets the versions of the sync protocol supported by the given contact.
*/
void setSyncVersions(Transaction txn, ContactId c, List<Byte> supported)
throws DbException;
/**
* Marks the given transport keys as usable for outgoing streams.
@@ -541,6 +602,6 @@ public interface DatabaseComponent {
/**
* Stores the given transport keys, deleting any keys they have replaced.
*/
void updateTransportKeys(Transaction txn, Collection<KeySet> keys)
void updateTransportKeys(Transaction txn, Collection<TransportKeySet> keys)
throws DbException;
}
@@ -1,15 +1,29 @@
package org.briarproject.bramble.api.db;
import org.briarproject.bramble.api.crypto.KeyStrengthener;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.io.File;
import javax.annotation.Nullable;
@NotNullByDefault
public interface DatabaseConfig {
/**
* Returns the directory where the database stores its data.
*/
File getDatabaseDirectory();
/**
* Returns the directory where the encrypted database key is stored.
*/
File getDatabaseKeyDirectory();
long getMaxSize();
/**
* Returns a {@link KeyStrengthener} for strengthening the encryption of
* the database key, or null if no strengthener should be used.
*/
@Nullable
KeyStrengthener getKeyStrengthener();
}
@@ -0,0 +1,9 @@
package org.briarproject.bramble.api.db;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface DbCallable<R, E extends Exception> {
R call(Transaction txn) throws DbException, E;
}
@@ -0,0 +1,9 @@
package org.briarproject.bramble.api.db;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface DbRunnable<E extends Exception> {
void run(Transaction txn) throws DbException, E;
}
@@ -0,0 +1,24 @@
package org.briarproject.bramble.api.db;
import org.briarproject.bramble.api.event.Event;
/**
* A {@link CommitAction} that broadcasts an event.
*/
public class EventAction implements CommitAction {
private final Event event;
EventAction(Event event) {
this.event = event;
}
public Event getEvent() {
return event;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
@@ -6,6 +6,10 @@ 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();
void onDatabaseMigration();
/**
* This is called when compaction is started while opening the database.
*/
void onDatabaseCompaction();
}
@@ -1,9 +1,9 @@
package org.briarproject.bramble.api.db;
/**
* Thrown when a database operation is attempted for a pseudonym that is not in
* Thrown when a database operation is attempted for an identity that is not in
* the database. This exception may occur due to concurrent updates and does
* not indicate a database error.
*/
public class NoSuchLocalAuthorException extends DbException {
public class NoSuchIdentityException extends DbException {
}
@@ -0,0 +1,9 @@
package org.briarproject.bramble.api.db;
/**
* Thrown when a database operation is attempted for a pending contact that is
* not in the database. This exception may occur due to concurrent updates and
* does not indicate a database error.
*/
public class NoSuchPendingContactException extends DbException {
}
@@ -0,0 +1,12 @@
package org.briarproject.bramble.api.db;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.Nullable;
@NotNullByDefault
public interface NullableDbCallable<R, E extends Exception> {
@Nullable
R call(Transaction txn) throws DbException, E;
}
@@ -0,0 +1,21 @@
package org.briarproject.bramble.api.db;
import org.briarproject.bramble.api.contact.PendingContact;
/**
* Thrown when a duplicate pending contact is added to the database. This
* exception may occur due to concurrent updates and does not indicate a
* database error.
*/
public class PendingContactExistsException extends DbException {
private final PendingContact pendingContact;
public PendingContactExistsException(PendingContact pendingContact) {
this.pendingContact = pendingContact;
}
public PendingContact getPendingContact() {
return pendingContact;
}
}
@@ -0,0 +1,24 @@
package org.briarproject.bramble.api.db;
import org.briarproject.bramble.api.event.EventExecutor;
/**
* A {@link CommitAction} that submits a task to the {@link EventExecutor}.
*/
public class TaskAction implements CommitAction {
private final Runnable task;
TaskAction(Runnable task) {
this.task = task;
}
public Runnable getTask() {
return task;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
@@ -1,13 +1,15 @@
package org.briarproject.bramble.api.db;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventExecutor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.concurrent.NotThreadSafe;
import static java.util.Collections.emptyList;
/**
* A wrapper around a database transaction. Transactions are not thread-safe.
*/
@@ -17,7 +19,7 @@ public class Transaction {
private final Object txn;
private final boolean readOnly;
private List<Event> events = null;
private List<CommitAction> actions = null;
private boolean committed = false;
public Transaction(Object txn, boolean readOnly) {
@@ -42,19 +44,27 @@ public class Transaction {
/**
* Attaches an event to be broadcast when the transaction has been
* committed.
* committed. The event will be broadcast on the {@link EventExecutor}.
*/
public void attach(Event e) {
if (events == null) events = new ArrayList<>();
events.add(e);
if (actions == null) actions = new ArrayList<>();
actions.add(new EventAction(e));
}
/**
* Returns any events attached to the transaction.
* Attaches a task to be executed when the transaction has been
* committed. The task will be run on the {@link EventExecutor}.
*/
public List<Event> getEvents() {
if (events == null) return Collections.emptyList();
return events;
public void attach(Runnable r) {
if (actions == null) actions = new ArrayList<>();
actions.add(new TaskAction(r));
}
/**
* Returns any actions attached to the transaction.
*/
public List<CommitAction> getActions() {
return actions == null ? emptyList() : actions;
}
/**
@@ -0,0 +1,54 @@
package org.briarproject.bramble.api.db;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.Nullable;
@NotNullByDefault
public interface TransactionManager {
/**
* Starts a new transaction and returns an object representing it.
* <p/>
* This method acquires locks, so it must not be called while holding a
* lock.
*
* @param readOnly true if the transaction will only be used for reading.
*/
Transaction startTransaction(boolean readOnly) throws DbException;
/**
* Commits a transaction to the database.
*/
void commitTransaction(Transaction txn) throws DbException;
/**
* Ends a transaction. If the transaction has not been committed,
* it will be aborted. If the transaction has been committed,
* any events attached to the transaction are broadcast.
* The database lock will be released in either case.
*/
void endTransaction(Transaction txn);
/**
* Runs the given task within a transaction.
*/
<E extends Exception> void transaction(boolean readOnly,
DbRunnable<E> task) throws DbException, E;
/**
* Runs the given task within a transaction and returns the result of the
* task.
*/
<R, E extends Exception> R transactionWithResult(boolean readOnly,
DbCallable<R, E> task) throws DbException, E;
/**
* Runs the given task within a transaction and returns the result of the
* task, which may be null.
*/
@Nullable
<R, E extends Exception> R transactionWithNullableResult(boolean readOnly,
NullableDbCallable<R, E> task) throws DbException, E;
}
@@ -16,7 +16,10 @@ public interface EventBus {
void removeListener(EventListener l);
/**
* Notifies all listeners of an event.
* Asynchronously notifies all listeners of an event. Listeners are
* notified on the {@link EventExecutor}.
* <p>
* This method can safely be called while holding a lock.
*/
void broadcast(Event e);
}
@@ -0,0 +1,26 @@
package org.briarproject.bramble.api.event;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Annotation for injecting the executor for broadcasting events and running
* tasks that need to run in a defined order with respect to events. Also used
* for annotating methods that should run on the event executor.
* <p>
* The contract of this executor is that tasks are run in the order they're
* submitted, tasks are not run concurrently, and submitting a task will never
* block. Tasks must not block. Tasks submitted during shutdown are discarded.
*/
@Qualifier
@Target({FIELD, METHOD, PARAMETER})
@Retention(RUNTIME)
public @interface EventExecutor {
}
@@ -12,5 +12,6 @@ public interface EventListener {
* Called when an event is broadcast. Implementations of this method must
* not block.
*/
@EventExecutor
void eventOccurred(Event e);
}
@@ -1,23 +1,21 @@
package org.briarproject.bramble.api.identity;
import org.briarproject.bramble.api.Nameable;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.util.StringUtils;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.crypto.CryptoConstants.KEY_TYPE_SIGNATURE;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.util.StringUtils.toUtf8;
/**
* A pseudonym for a user.
*/
@Immutable
@NotNullByDefault
public class Author {
public enum Status {
NONE, ANONYMOUS, UNKNOWN, UNVERIFIED, VERIFIED, OURSELVES
}
public class Author implements Nameable {
/**
* The current version of the author structure.
@@ -27,14 +25,14 @@ public class Author {
private final AuthorId id;
private final int formatVersion;
private final String name;
private final byte[] publicKey;
private final PublicKey publicKey;
public Author(AuthorId id, int formatVersion, String name,
byte[] publicKey) {
int nameLength = StringUtils.toUtf8(name).length;
PublicKey publicKey) {
int nameLength = toUtf8(name).length;
if (nameLength == 0 || nameLength > MAX_AUTHOR_NAME_LENGTH)
throw new IllegalArgumentException();
if (publicKey.length == 0 || publicKey.length > MAX_PUBLIC_KEY_LENGTH)
if (!publicKey.getKeyType().equals(KEY_TYPE_SIGNATURE))
throw new IllegalArgumentException();
this.id = id;
this.formatVersion = formatVersion;
@@ -66,7 +64,7 @@ public class Author {
/**
* Returns the public key used to verify the pseudonym's signatures.
*/
public byte[] getPublicKey() {
public PublicKey getPublicKey() {
return publicKey;
}
@@ -1,5 +1,6 @@
package org.briarproject.bramble.api.identity;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
@@ -9,23 +10,16 @@ public interface AuthorFactory {
* Creates an author with the current format version and the given name and
* public key.
*/
Author createAuthor(String name, byte[] publicKey);
Author createAuthor(String name, PublicKey publicKey);
/**
* Creates an author with the given format version, name and public key.
*/
Author createAuthor(int formatVersion, String name, byte[] publicKey);
Author createAuthor(int formatVersion, String name, PublicKey publicKey);
/**
* Creates a local author with the current format version and the given
* name and keys.
* name.
*/
LocalAuthor createLocalAuthor(String name, byte[] publicKey,
byte[] privateKey);
/**
* Creates a local author with the given format version, name and keys.
*/
LocalAuthor createLocalAuthor(int formatVersion, String name,
byte[] publicKey, byte[] privateKey);
LocalAuthor createLocalAuthor(String name);
}
@@ -0,0 +1,56 @@
package org.briarproject.bramble.api.identity;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
@Immutable
@NotNullByDefault
public class AuthorInfo {
public enum Status {
NONE, ANONYMOUS, UNKNOWN, UNVERIFIED, VERIFIED, OURSELVES;
public boolean isContact() {
return this == UNVERIFIED || this == VERIFIED;
}
}
private final Status status;
@Nullable
private final String alias;
public AuthorInfo(Status status, @Nullable String alias) {
this.status = status;
this.alias = alias;
}
public AuthorInfo(Status status) {
this(status, null);
}
public Status getStatus() {
return status;
}
@Nullable
public String getAlias() {
return alias;
}
@Override
public int hashCode() {
int hashCode = status.ordinal();
if (alias != null) hashCode += alias.hashCode();
return hashCode;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof AuthorInfo)) return false;
AuthorInfo info = (AuthorInfo) o;
return status == info.status &&
(alias == null ? info.alias == null : alias.equals(info.alias));
}
}
@@ -0,0 +1,88 @@
package org.briarproject.bramble.api.identity;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.crypto.CryptoConstants.KEY_TYPE_AGREEMENT;
@Immutable
@NotNullByDefault
public class Identity {
private final LocalAuthor localAuthor;
@Nullable
private final PublicKey handshakePublicKey;
@Nullable
private final PrivateKey handshakePrivateKey;
private final long created;
public Identity(LocalAuthor localAuthor,
@Nullable PublicKey handshakePublicKey,
@Nullable PrivateKey handshakePrivateKey, long created) {
if (handshakePublicKey != null) {
if (handshakePrivateKey == null)
throw new IllegalArgumentException();
if (!handshakePublicKey.getKeyType().equals(KEY_TYPE_AGREEMENT))
throw new IllegalArgumentException();
}
if (handshakePrivateKey != null) {
if (handshakePublicKey == null)
throw new IllegalArgumentException();
if (!handshakePrivateKey.getKeyType().equals(KEY_TYPE_AGREEMENT))
throw new IllegalArgumentException();
}
this.localAuthor = localAuthor;
this.handshakePublicKey = handshakePublicKey;
this.handshakePrivateKey = handshakePrivateKey;
this.created = created;
}
/**
* Returns the ID of the user's pseudonym.
*/
public AuthorId getId() {
return localAuthor.getId();
}
/**
* Returns the user's pseudonym.
*/
public LocalAuthor getLocalAuthor() {
return localAuthor;
}
/**
* Returns true if the identity has a handshake key pair.
*/
public boolean hasHandshakeKeyPair() {
return handshakePublicKey != null && handshakePrivateKey != null;
}
/**
* Returns the public key used for handshaking, or null if no key exists.
*/
@Nullable
public PublicKey getHandshakePublicKey() {
return handshakePublicKey;
}
/**
* Returns the private key used for handshaking, or null if no key exists.
*/
@Nullable
public PrivateKey getHandshakePrivateKey() {
return handshakePrivateKey;
}
/**
* Returns the time the identity was created, in milliseconds since the
* Unix epoch.
*/
public long getTimeCreated() {
return created;
}
}
@@ -1,31 +1,30 @@
package org.briarproject.bramble.api.identity;
import org.briarproject.bramble.api.crypto.CryptoExecutor;
import org.briarproject.bramble.api.crypto.KeyPair;
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.Status;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface IdentityManager {
/**
* Creates a local identity with the given name.
* Creates an identity with the given name. The identity includes a
* handshake key pair.
*/
@CryptoExecutor
LocalAuthor createLocalAuthor(String name);
Identity createIdentity(String name);
/**
* Registers the given local identity with the manager. The identity is
* not stored until {@link #storeLocalAuthor()} is called.
* Registers the given identity with the manager. This method should be
* called before {@link LifecycleManager#startServices(SecretKey)}. The
* identity is stored when {@link LifecycleManager#startServices(SecretKey)}
* is called. The identity must include a handshake key pair.
*/
void registerLocalAuthor(LocalAuthor a);
/**
* Stores the local identity registered with
* {@link #registerLocalAuthor(LocalAuthor)}, if any.
*/
void storeLocalAuthor() throws DbException;
void registerIdentity(Identity i);
/**
* Returns the cached local identity or loads it from the database.
@@ -34,17 +33,15 @@ public interface IdentityManager {
/**
* Returns the cached local identity or loads it from the database.
* <p/>
* Read-only.
*/
LocalAuthor getLocalAuthor(Transaction txn) throws DbException;
/**
* Returns the {@link Status} of the given author.
* Returns the cached handshake keys or loads them from the database.
* <p/>
* Read-only.
*/
Status getAuthorStatus(AuthorId a) throws DbException;
/**
* Returns the {@link Status} of the given author.
*/
Status getAuthorStatus(Transaction txn, AuthorId a) throws DbException;
KeyPair getHandshakeKeys(Transaction txn) throws DbException;
}
@@ -1,9 +1,13 @@
package org.briarproject.bramble.api.identity;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.crypto.CryptoConstants.KEY_TYPE_SIGNATURE;
/**
* A pseudonym for the local user.
*/
@@ -11,28 +15,20 @@ import javax.annotation.concurrent.Immutable;
@NotNullByDefault
public class LocalAuthor extends Author {
private final byte[] privateKey;
private final long created;
private final PrivateKey privateKey;
public LocalAuthor(AuthorId id, int formatVersion, String name,
byte[] publicKey, byte[] privateKey, long created) {
PublicKey publicKey, PrivateKey privateKey) {
super(id, formatVersion, name, publicKey);
if (!privateKey.getKeyType().equals(KEY_TYPE_SIGNATURE))
throw new IllegalArgumentException();
this.privateKey = privateKey;
this.created = created;
}
/**
* Returns the private key used to generate the pseudonym's signatures.
*/
public byte[] getPrivateKey() {
public PrivateKey getPrivateKey() {
return privateKey;
}
/**
* Returns the time the pseudonym was created, in milliseconds since the
* Unix epoch.
*/
public long getTimeCreated() {
return created;
}
}
@@ -7,15 +7,15 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
/**
* An event that is broadcast when a local pseudonym is added.
* An event that is broadcast when an identity is added.
*/
@Immutable
@NotNullByDefault
public class LocalAuthorAddedEvent extends Event {
public class IdentityAddedEvent extends Event {
private final AuthorId authorId;
public LocalAuthorAddedEvent(AuthorId authorId) {
public IdentityAddedEvent(AuthorId authorId) {
this.authorId = authorId;
}

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