Compare commits

...

91 Commits

Author SHA1 Message Date
akwizgran
9476782ced Bump version numbers for 1.1.1 release. 2018-09-14 13:16:17 +01:00
akwizgran
74445acb55 Merge branch '1379-startup-failure-error' into 'master'
Correct startup database failure error messages

Closes #1379

See merge request briar/briar!920
2018-09-14 12:01:52 +00:00
akwizgran
e32771f964 Merge branch '1359-conversation-progress' into 'master'
Fix progress feel over messages in Conversation view

Closes #1359

See merge request briar/briar!911
2018-09-14 11:59:42 +00:00
akwizgran
d7bf1ee374 Merge branch '1367-db-header-corrupt' into 'master'
Fix duplicate actions triggered by hardware keyboard

Closes #1367

See merge request briar/briar!921
2018-09-14 09:09:41 +00:00
Torsten Grote
10bee05856 Only sign-in once when pressing enter 2018-09-13 18:45:24 -03:00
Torsten Grote
fc626d0921 Only create one private group when pressing enter 2018-09-13 18:45:24 -03:00
Torsten Grote
30f87e626a Only create one forum when pressing enter 2018-09-13 18:45:24 -03:00
Torsten Grote
a0d91da569 Add TODO for not allowing double account creation 2018-09-13 18:19:15 -03:00
Torsten Grote
c90a72617e Do not create two accounts when pressing enter for account creation
Fixes #1367
2018-09-13 18:18:30 -03:00
Torsten Grote
8813bc36af Correct startup database failure error messages 2018-09-13 12:35:39 -03:00
akwizgran
049cf3ad27 Merge branch 'optional-tests' into 'master'
Specify optional tests with an environment variable

See merge request briar/briar!916
2018-09-13 14:36:59 +00:00
Torsten Grote
de8a6b23e5 Merge branch '1189-setup-activity' into 'master'
Launch SetupActivity in same task to prevent relaunching from recent apps

Closes #1189

See merge request briar/briar!919
2018-09-13 14:21:24 +00:00
akwizgran
30193a240b Start SetupActivity in same task, finish other activities. 2018-09-13 13:43:01 +01:00
akwizgran
a52ad8b4cc Bump version numbers for 1.1.0 release. 2018-09-12 17:10:52 +01:00
Torsten Grote
6a1a8b6872 Merge branch '1245-enable-pin-lock' into 'master'
Enable sign-in reminder, PIN lock and dark theme for release builds

See merge request briar/briar!917
2018-09-12 11:15:12 +00:00
Torsten Grote
50ad42a0a2 Update translations, adds Hungarian, sets inclusion threshold to 80% 2018-09-12 07:45:02 -03:00
akwizgran
08005bdf56 Enable PIN lock for release builds. 2018-09-12 11:44:27 +01:00
akwizgran
e32cc3af6d Enable dark theme for release builds. 2018-09-12 11:41:54 +01:00
akwizgran
28a68ff625 Enable sign-in reminder for release builds. 2018-09-12 11:39:54 +01:00
akwizgran
2bef2ac828 Merge branch '1249-sign-in-screenshots' into 'master'
Screenshots for account sign-in improvements and Tor settings

See merge request briar/briar!909
2018-09-06 13:40:03 +00:00
akwizgran
b2febbc6e9 Specify optional tests with an environment variable. 2018-09-06 10:34:04 +01:00
Torsten Grote
e12601dd08 Merge branch 'attach-updated-settings-to-event' into 'master'
Attach updated settings to SettingsUpdatedEvent

See merge request briar/briar!913
2018-09-05 11:22:05 +00:00
akwizgran
3388682dda Use updated settings from event. 2018-09-05 12:04:56 +01:00
akwizgran
8ad3047f87 Merge branch '1247-pin-lock-fingerprint' into 'master'
Implement fingerprint unlocking with BiometricPromptCompat

See merge request briar/briar!882
2018-09-05 08:39:54 +00:00
akwizgran
0cffaf8646 Merge branch 'move-tor-bridge-tests' into 'master'
Move Tor Bridge tests and rename bramble-j2se to bramble-java

See merge request briar/briar!907
2018-09-05 08:35:33 +00:00
akwizgran
7b116f15df Attach updated settings to SettingsUpdatedEvent. 2018-09-05 09:31:12 +01:00
Torsten Grote
ced0f72fba Fix progress feel over messages in Conversation view
Unlike with many other lists,
we are not clearing the list of private messages when restarting the activity.
We still load the messages from the database and add them to the view.
When there are no new message to add,
the usual insert observers do not trigger
and we do not call list.showData() although we should.
Doing so removes the progress bar as soon as messages have been loaded.
2018-09-04 12:31:16 -03:00
Torsten Grote
24c030f06f Remove button from UnlockActivity 2018-09-04 09:32:24 -03:00
Torsten Grote
a3fa15e90e Blank UnlockActivity when not using fingerprint unlock 2018-09-04 09:04:59 -03:00
Torsten Grote
57841be447 Remove BiometricPromptCompat library and limit feature to API 28 2018-09-04 09:04:58 -03:00
Torsten Grote
c5d374af04 ScreenLock: Implement fingerprint unlocking with BiometricPromptCompat 2018-09-04 09:04:33 -03:00
Torsten Grote
8d592ad2ee Take screenshot of Tor settings 2018-09-03 18:03:57 -03:00
Torsten Grote
055c381cc9 Take a screenshot of the Navigation Drawer with lock action 2018-09-03 16:32:39 -03:00
Torsten Grote
1d259bd51c Screenshots for Sign-in improvements
Screenshots for #1249
2018-09-03 16:32:39 -03:00
Torsten Grote
de63141997 Update translations 2018-09-03 15:02:34 -03:00
Torsten Grote
dee8f68477 Do not run Tor bridge test with every CI run 2018-09-03 13:02:54 -03:00
Torsten Grote
59048f106a Move Tor Bridge tests and rename bramble-j2se to bramble-java 2018-09-03 12:58:20 -03:00
akwizgran
da7cf4af28 Rename bramble-j2se to bramble-java. 2018-09-03 16:28:59 +01:00
akwizgran
0d4cf4db68 Merge branch 'java-tor-plugin' into 'master'
Add a LinuxTorPlugin

See merge request briar/briar!902
2018-09-03 15:23:20 +00:00
Torsten Grote
9efd2d113a Ignore file extension when retrieving resources on Android 2018-09-03 11:58:42 -03:00
Torsten Grote
8e6cd12f07 LinuxTorPlugin: Address review comments 2018-09-03 11:52:10 -03:00
Torsten Grote
3a49ca0d97 Add JavaTorPlugin 2018-09-03 11:52:10 -03:00
akwizgran
c03868e800 Merge branch '1343-vanniktech-emoji' into 'master'
Use vanniktech emoji library

Closes #1343, #1314, #940, #930, #749, and #684

See merge request briar/briar!857
2018-09-03 12:12:01 +00:00
akwizgran
d6c129e919 Hide emoji popup when hiding soft keyboard. 2018-08-28 16:45:04 +01:00
akwizgran
271efdd2bc Hide soft keyboard when reblogging post. 2018-08-28 15:57:55 +01:00
akwizgran
ad4e8d51e9 Hide soft keyboard when sending blog post. 2018-08-28 15:55:16 +01:00
akwizgran
eb19c6e08d Remove unused resources. 2018-08-28 15:55:16 +01:00
akwizgran
83bfeb9075 Initialise EmojiManager for UI tests. 2018-08-28 15:55:16 +01:00
akwizgran
428501cf5f Use vanniktech emoji library. 2018-08-28 15:55:16 +01:00
Torsten Grote
d8b04edcd0 Merge branch '1240-avoid-raw-messages' into 'master'
Avoid raw messages

See merge request briar/briar!906
2018-08-27 14:40:54 +00:00
akwizgran
0bc07cd0c1 Rename message length method. 2018-08-24 16:56:24 +01:00
akwizgran
cb3026959a Remove raw messages from SyncRecordWriter interface. 2018-08-24 16:56:24 +01:00
akwizgran
48933637d8 Remove raw messages from DB interface. 2018-08-24 16:56:24 +01:00
akwizgran
5626f3d761 Remove raw message method from DatabaseComponent interface. 2018-08-24 16:56:23 +01:00
akwizgran
0fce224d88 Add method for getting cooked message from DB. 2018-08-24 16:56:23 +01:00
Torsten Grote
3db35f7061 Merge branch 'network-interfaces-may-be-null' into 'master'
Check whether getNetworkInterfaces() returns null

See merge request briar/briar!903
2018-08-24 15:48:22 +00:00
Torsten Grote
751375035d Merge branch 'message-constructor' into 'master'
Minimise use of message constructor

See merge request briar/briar!905
2018-08-24 14:58:57 +00:00
akwizgran
27a169c6e2 Minimise use of message constructor. 2018-08-24 14:17:25 +01:00
akwizgran
d4a4351786 Merge branch '758-db-exception-for-deleted-messages' into 'master'
Throw an exception if a deleted message is requested from the DB

Closes #758

See merge request briar/briar!904
2018-08-24 09:21:05 +00:00
akwizgran
fbd38dbb94 Throw an exception if a raw message has been deleted. 2018-08-23 14:51:56 +01:00
akwizgran
cd4897e6c9 Check whether getNetworkInterfaces() returns null. 2018-08-23 14:16:18 +01:00
akwizgran
d84e176bb4 Merge branch 'fix_performance_test_db' into 'master'
Fix the database performance tests

See merge request briar/briar!893
2018-08-22 15:46:11 +00:00
Torsten Grote
da8b49bec2 Merge branch 'log-relay-names' into 'master'
Log Tor relay names to detect failing bridges

See merge request briar/briar!901
2018-08-22 14:27:58 +00:00
akwizgran
6c8cc79d87 Log Tor relay names to detect failing bridges. 2018-08-22 14:21:41 +01:00
akwizgran
a5271eee29 Merge branch 'switch-preference-android-4' into 'master'
Use Material style for SwitchPreference on Android 4

See merge request briar/briar!897
2018-08-20 19:40:56 +00:00
akwizgran
4dfc96996d Merge branch '1224-show-explanation-when-contact-exchange-fails' into 'master'
Show an error fragment when contact exchange fails

See merge request briar/briar!890
2018-08-20 19:40:36 +00:00
akwizgran
3139f308a2 Merge branch '1349-empty-state-ui' into 'master'
Implement new empty state icons

Closes #1349

See merge request briar/briar!898
2018-08-20 19:39:56 +00:00
Torsten Grote
cc6daffa61 Merge branch 'update-bridges' into 'master'
Replace two failing bridges

See merge request briar/briar!900
2018-08-20 18:36:07 +00:00
Torsten Grote
f08f441f5f Use Material style for SwitchPreference on Android 4 2018-08-20 15:22:55 -03:00
Torsten Grote
83886c78f1 Empty states: Address review comments 2018-08-20 15:14:53 -03:00
Torsten Grote
5ed0e9efec Implement new empty state icons 2018-08-20 15:14:53 -03:00
akwizgran
169c59349e Merge branch '1269-bridge-setting' into 'master'
Refactor Tor settings and add a setting for forcing the use bridges

Closes #1269

See merge request briar/briar!895
2018-08-20 17:56:56 +00:00
akwizgran
764f60b3fe Replace two failing bridges. 2018-08-20 17:57:36 +01:00
Torsten Grote
e51c437a06 Merge branch 'ci-dev-urandom' into 'master'
Use /dev/urandom for CI

See merge request briar/briar!899
2018-08-20 16:24:49 +00:00
akwizgran
9fbf740ba7 Use /dev/urandom for tests. 2018-08-20 17:08:57 +01:00
akwizgran
db7686ea52 Merge branch '1247-pin-lock-activity-timeout' into 'master'
Screen Lock: Lock after customizable inactivity timeout

See merge request briar/briar!887
2018-08-20 13:52:23 +00:00
akwizgran
7fe21e079f Merge branch '1358-message-bubbles' into 'master'
New Design for Message Bubbles

Closes #1358

See merge request briar/briar!896
2018-08-20 12:11:22 +00:00
Torsten Grote
be72e624a3 ContactExchangeErrorFragment: Address review comments 2018-08-16 13:00:02 -03:00
Torsten Grote
d9e9741112 Replace generic ErrorFragment with specific one
when key agreement protocol doesn't match
2018-08-16 12:34:20 -03:00
Torsten Grote
656ca8d67a Contact failure: Add better icon and remove technical error message 2018-08-16 12:34:20 -03:00
Torsten Grote
d3e44358a4 Move feedback trigger and making link clickable to UiUtils 2018-08-16 12:34:20 -03:00
Torsten Grote
920a1d0431 Show an error fragment when contact exchange fails 2018-08-16 12:34:20 -03:00
Torsten Grote
4b9a9771f8 Tor settings: Address review comments 2018-08-16 12:27:26 -03:00
Torsten Grote
d64252aaf3 Screen Lock Timeout: Address review comments 2018-08-16 12:16:45 -03:00
Torsten Grote
825ed451a3 Screen lock: Add a fallback in case alarm manager didn't run during sleep 2018-08-16 12:14:59 -03:00
Torsten Grote
bffd78d404 Use a dedicated summary for 'never lock Briar' for proper English 2018-08-16 12:14:59 -03:00
Torsten Grote
04ffff0953 Screen Lock: Lock after customizable inactivity timeout 2018-08-16 12:14:59 -03:00
Torsten Grote
21f95ed9af Add a stroke for private message bubbles on Android 4 2018-08-16 12:07:54 -03:00
Torsten Grote
c8b516196c Add new private message bubbles, get rid of 9-patch drawables
This reverts commit f8a8c0d8b8.
2018-08-16 10:22:15 -03:00
goapunk
941a0cccc3 Fix a regression in the performance tests causing the db key to be regenerated everytime. 2018-08-16 12:09:33 +02:00
Torsten Grote
9b17836595 Refactor Tor settings and add a setting for forcing to use bridges 2018-08-15 17:32:43 -03:00
317 changed files with 5777 additions and 5104 deletions

View File

@@ -11,8 +11,8 @@ test:
- .gradle/caches - .gradle/caches
script: script:
- ./gradlew --no-daemon animalSnifferMain animalSnifferTest - ./gradlew --no-daemon -Djava.security.egd=file:/dev/urandom animalSnifferMain animalSnifferTest
- ./gradlew --no-daemon test - ./gradlew --no-daemon -Djava.security.egd=file:/dev/urandom test
after_script: after_script:
# these file change every time but should not be cached # these file change every time but should not be cached

View File

@@ -22,8 +22,8 @@
<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-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-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-android" run_configuration_type="AndroidJUnit" />
<option name="RunConfigurationTask" enabled="true" run_configuration_name="All tests in bramble-j2se" run_configuration_type="AndroidJUnit" /> <option name="RunConfigurationTask" enabled="true" run_configuration_name="All tests in 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-core" run_configuration_type="AndroidJUnit" />
</method> </method>
</configuration> </configuration>
</component> </component>

View File

@@ -1,7 +1,7 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="All tests in bramble-j2se" type="AndroidJUnit" factoryName="Android JUnit"> <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" /> <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="bramble-j2se" /> <module name="bramble-java" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" /> <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" /> <option name="ALTERNATIVE_JRE_PATH" />
<option name="PACKAGE_NAME" value="" /> <option name="PACKAGE_NAME" value="" />
@@ -10,7 +10,7 @@
<option name="TEST_OBJECT" value="package" /> <option name="TEST_OBJECT" value="package" />
<option name="VM_PARAMETERS" value="-ea -Djava.library.path=libs" /> <option name="VM_PARAMETERS" value="-ea -Djava.library.path=libs" />
<option name="PARAMETERS" value="" /> <option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/bramble-j2se" /> <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/bramble-java" />
<option name="ENV_VARIABLES" /> <option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" /> <option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE"> <option name="TEST_SEARCH_SCOPE">

View File

@@ -9,8 +9,8 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 14 minSdkVersion 14
targetSdkVersion 26 targetSdkVersion 26
versionCode 10013 versionCode 10101
versionName "1.0.13" versionName "1.1.1"
consumerProguardFiles 'proguard-rules.txt' consumerProguardFiles 'proguard-rules.txt'
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
@@ -41,12 +41,6 @@ dependencies {
testImplementation "org.jmock:jmock-legacy:2.8.2" testImplementation "org.jmock:jmock-legacy:2.8.2"
testImplementation "org.hamcrest:hamcrest-library:1.3" testImplementation "org.hamcrest:hamcrest-library:1.3"
testImplementation "org.hamcrest:hamcrest-core:1.3" testImplementation "org.hamcrest:hamcrest-core:1.3"
androidTestImplementation project(path: ':bramble-api', configuration: 'testOutput')
androidTestImplementation project(path: ':bramble-core', configuration: 'testOutput')
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestAnnotationProcessor 'com.google.dagger:dagger-compiler:2.0.2'
androidTestCompileOnly 'javax.annotation:jsr250-api:1.0'
} }
project.afterEvaluate { project.afterEvaluate {

View File

@@ -1,20 +0,0 @@
package org.briarproject.bramble.test;
import android.app.Application;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import static android.support.test.InstrumentationRegistry.getTargetContext;
@Module
class ApplicationModule {
@Provides
@Singleton
Application provideApplication() {
return (Application) getTargetContext().getApplicationContext();
}
}

View File

@@ -22,9 +22,11 @@ class AndroidResourceProvider implements ResourceProvider {
} }
@Override @Override
public InputStream getResourceInputStream(String name) { public InputStream getResourceInputStream(String name, String extension) {
Resources res = appContext.getResources(); Resources res = appContext.getResources();
int resId = res.getIdentifier(name, "raw", appContext.getPackageName()); // extension is ignored on Android, resources are retrieved without it
int resId =
res.getIdentifier(name, "raw", appContext.getPackageName());
return res.openRawResource(resId); return res.openRawResource(resId);
} }
} }

View File

@@ -1,9 +1,6 @@
dependencyVerification { dependencyVerification {
verify = [ verify = [
'cglib:cglib:3.2.0:cglib-3.2.0.jar:adb13bab79712ad6bdf1bd59f2a3918018a8016e722e8a357065afb9e6690861', 'cglib:cglib:3.2.0:cglib-3.2.0.jar:adb13bab79712ad6bdf1bd59f2a3918018a8016e722e8a357065afb9e6690861',
'com.android.support.test:monitor:1.0.2:monitor-1.0.2.aar:38ef4fa98a32dc55550ff49bb36a583e178b3a9b830fcb8dcc27bfc4254bc2bc',
'com.android.support.test:runner:1.0.2:runner-1.0.2.aar:f04b9ae342975ba1cb3e4a06e13426e3e6b8a73faa45acba604493d83c9a4f00',
'com.android.support:support-annotations:27.1.1:support-annotations-27.1.1.jar:3365960206c3d2b09e845f555e7f88f8effc8d2f00b369e66c4be384029299cf',
'com.android.tools.analytics-library:protos:26.1.3:protos-26.1.3.jar:818c9f256f141d9dafec03a1aa2b94d240b2c140acfd7ee31a8b3e6c2b9479e3', '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: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.analytics-library:tracker:26.1.3:tracker-26.1.3.jar:4155424bf2ce4872da83332579a1707252bc66cbd77c5144fdc4483d0f2e1418',

View File

@@ -16,8 +16,6 @@ import org.briarproject.bramble.api.sync.MessageId;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.util.Map; import java.util.Map;
import javax.annotation.Nullable;
@NotNullByDefault @NotNullByDefault
public interface ClientHelper { public interface ClientHelper {
@@ -32,16 +30,12 @@ public interface ClientHelper {
Message createMessageForStoringMetadata(GroupId g); Message createMessageForStoringMetadata(GroupId g);
@Nullable
Message getMessage(MessageId m) throws DbException; Message getMessage(MessageId m) throws DbException;
@Nullable
Message getMessage(Transaction txn, MessageId m) throws DbException; Message getMessage(Transaction txn, MessageId m) throws DbException;
@Nullable
BdfList getMessageAsList(MessageId m) throws DbException, FormatException; BdfList getMessageAsList(MessageId m) throws DbException, FormatException;
@Nullable
BdfList getMessageAsList(Transaction txn, MessageId m) throws DbException, BdfList getMessageAsList(Transaction txn, MessageId m) throws DbException,
FormatException; FormatException;

View File

@@ -151,13 +151,13 @@ public interface DatabaseComponent {
throws DbException; throws DbException;
/** /**
* Returns a batch of raw messages for the given contact, with a total * Returns a batch of messages for the given contact, with a total length
* length less than or equal to the given length, for transmission over a * less than or equal to the given length, for transmission over a
* transport with the given maximum latency. Returns null if there are no * transport with the given maximum latency. Returns null if there are no
* sendable messages that fit in the given length. * sendable messages that fit in the given length.
*/ */
@Nullable @Nullable
Collection<byte[]> generateBatch(Transaction txn, ContactId c, Collection<Message> generateBatch(Transaction txn, ContactId c,
int maxLength, int maxLatency) throws DbException; int maxLength, int maxLatency) throws DbException;
/** /**
@@ -178,14 +178,14 @@ public interface DatabaseComponent {
throws DbException; throws DbException;
/** /**
* Returns a batch of raw messages for the given contact, with a total * Returns a batch of messages for the given contact, with a total length
* length less than or equal to the given length, for transmission over a * less than or equal to the given length, for transmission over a
* transport with the given maximum latency. Only messages that have been * transport with the given maximum latency. Only messages that have been
* requested by the contact are returned. Returns null if there are no * requested by the contact are returned. Returns null if there are no
* sendable messages that fit in the given length. * sendable messages that fit in the given length.
*/ */
@Nullable @Nullable
Collection<byte[]> generateRequestedBatch(Transaction txn, ContactId c, Collection<Message> generateRequestedBatch(Transaction txn, ContactId c,
int maxLength, int maxLatency) throws DbException; int maxLength, int maxLatency) throws DbException;
/** /**
@@ -263,6 +263,15 @@ public interface DatabaseComponent {
*/ */
Collection<LocalAuthor> getLocalAuthors(Transaction txn) throws DbException; Collection<LocalAuthor> getLocalAuthors(Transaction txn) throws DbException;
/**
* Returns the message with the given ID.
* <p/>
* Read-only.
*
* @throws MessageDeletedException if the message has been deleted
*/
Message getMessage(Transaction txn, MessageId m) throws DbException;
/** /**
* Returns the IDs of all delivered messages in the given group. * Returns the IDs of all delivered messages in the given group.
* <p/> * <p/>
@@ -297,15 +306,6 @@ public interface DatabaseComponent {
Collection<MessageId> getMessagesToShare(Transaction txn) Collection<MessageId> getMessagesToShare(Transaction txn)
throws DbException; throws DbException;
/**
* Returns the message with the given ID, in serialised form, or null if
* the message has been deleted.
* <p/>
* Read-only.
*/
@Nullable
byte[] getRawMessage(Transaction txn, MessageId m) throws DbException;
/** /**
* Returns the metadata for all delivered messages in the given group. * Returns the metadata for all delivered messages in the given group.
* <p/> * <p/>

View File

@@ -0,0 +1,9 @@
package org.briarproject.bramble.api.db;
/**
* Thrown when a message that has been deleted is requested from the database.
* This exception may occur due to concurrent updates and does not indicate a
* database error.
*/
public class MessageDeletedException extends DbException {
}

View File

@@ -12,12 +12,13 @@ public interface TorConstants {
int CONNECT_TO_PROXY_TIMEOUT = 5000; // Milliseconds int CONNECT_TO_PROXY_TIMEOUT = 5000; // Milliseconds
int EXTRA_SOCKET_TIMEOUT = 30000; // Milliseconds int EXTRA_SOCKET_TIMEOUT = 30000; // Milliseconds
String PREF_TOR_NETWORK = "network"; String PREF_TOR_NETWORK = "network2";
String PREF_TOR_PORT = "port"; String PREF_TOR_PORT = "port";
String PREF_TOR_DISABLE_BLOCKED = "disableWhenBlocked"; String PREF_TOR_MOBILE = "useMobileData";
int PREF_TOR_NETWORK_NEVER = 0; int PREF_TOR_NETWORK_AUTOMATIC = 0;
int PREF_TOR_NETWORK_WIFI = 1; int PREF_TOR_NETWORK_WITHOUT_BRIDGES = 1;
int PREF_TOR_NETWORK_ALWAYS = 2; int PREF_TOR_NETWORK_WITH_BRIDGES = 2;
int PREF_TOR_NETWORK_NEVER = 3;
} }

View File

@@ -1,6 +1,7 @@
package org.briarproject.bramble.api.settings; package org.briarproject.bramble.api.settings;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault @NotNullByDefault
@@ -11,6 +12,11 @@ public interface SettingsManager {
*/ */
Settings getSettings(String namespace) throws DbException; Settings getSettings(String namespace) throws DbException;
/**
* Returns all settings in the given namespace.
*/
Settings getSettings(Transaction txn, String namespace) throws DbException;
/** /**
* Merges the given settings with any existing settings in the given * Merges the given settings with any existing settings in the given
* namespace. * namespace.

View File

@@ -2,6 +2,7 @@ package org.briarproject.bramble.api.settings.event;
import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.settings.Settings;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
@@ -13,12 +14,18 @@ import javax.annotation.concurrent.Immutable;
public class SettingsUpdatedEvent extends Event { public class SettingsUpdatedEvent extends Event {
private final String namespace; private final String namespace;
private final Settings settings;
public SettingsUpdatedEvent(String namespace) { public SettingsUpdatedEvent(String namespace, Settings settings) {
this.namespace = namespace; this.namespace = namespace;
this.settings = settings;
} }
public String getNamespace() { public String getNamespace() {
return namespace; return namespace;
} }
public Settings getSettings() {
return settings;
}
} }

View File

@@ -50,7 +50,7 @@ public class Message {
/** /**
* Returns the length of the raw message in bytes. * Returns the length of the raw message in bytes.
*/ */
public int getLength() { public int getRawLength() {
return raw.length; return raw.length;
} }

View File

@@ -9,7 +9,7 @@ public interface SyncRecordWriter {
void writeAck(Ack a) throws IOException; void writeAck(Ack a) throws IOException;
void writeMessage(byte[] raw) throws IOException; void writeMessage(Message m) throws IOException;
void writeOffer(Offer o) throws IOException; void writeOffer(Offer o) throws IOException;

View File

@@ -7,5 +7,5 @@ import java.io.InputStream;
@NotNullByDefault @NotNullByDefault
public interface ResourceProvider { public interface ResourceProvider {
InputStream getResourceInputStream(String name); InputStream getResourceInputStream(String name, String extension);
} }

View File

@@ -24,6 +24,7 @@ import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import static java.util.Arrays.asList;
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION; import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; 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.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
@@ -40,6 +41,7 @@ public class TestUtils {
private static final AtomicInteger nextTestDir = private static final AtomicInteger nextTestDir =
new AtomicInteger((int) (Math.random() * 1000 * 1000)); new AtomicInteger((int) (Math.random() * 1000 * 1000));
private static final Random random = new Random(); private static final Random random = new Random();
private static final long timestamp = System.currentTimeMillis();
public static File getTestDirectory() { public static File getTestDirectory() {
int name = nextTestDir.getAndIncrement(); int name = nextTestDir.getAndIncrement();
@@ -101,9 +103,8 @@ public class TestUtils {
String name = getRandomString(nameLength); String name = getRandomString(nameLength);
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH); byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
byte[] privateKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH); byte[] privateKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
long created = System.currentTimeMillis();
return new LocalAuthor(id, FORMAT_VERSION, name, publicKey, privateKey, return new LocalAuthor(id, FORMAT_VERSION, name, publicKey, privateKey,
created); timestamp);
} }
public static Author getAuthor() { public static Author getAuthor() {
@@ -137,7 +138,6 @@ public class TestUtils {
public static Message getMessage(GroupId groupId, int rawLength) { public static Message getMessage(GroupId groupId, int rawLength) {
MessageId id = new MessageId(getRandomId()); MessageId id = new MessageId(getRandomId());
byte[] raw = getRandomBytes(rawLength); byte[] raw = getRandomBytes(rawLength);
long timestamp = System.currentTimeMillis();
return new Message(id, groupId, timestamp, raw); return new Message(id, groupId, timestamp, raw);
} }
@@ -174,4 +174,10 @@ public class TestUtils {
Collection<? extends Number> samples) { Collection<? extends Number> samples) {
return Math.sqrt(getVariance(samples)); return Math.sqrt(getVariance(samples));
} }
public static boolean isOptionalTestEnabled(Class testClass) {
String optionalTests = System.getenv("OPTIONAL_TESTS");
return optionalTests != null &&
asList(optionalTests.split(",")).contains(testClass.getName());
}
} }

View File

@@ -33,7 +33,7 @@ dependencies {
signature 'org.codehaus.mojo.signature:java16:1.1@signature' signature 'org.codehaus.mojo.signature:java16:1.1@signature'
} }
// needed to make test output available to bramble-j2se // needed to make test output available to bramble-java
configurations { configurations {
testOutput.extendsFrom(testCompile) testOutput.extendsFrom(testCompile)
} }

View File

@@ -159,6 +159,7 @@ class AccountManagerImpl implements AccountManager {
@Override @Override
public boolean createAccount(String name, String password) { public boolean createAccount(String name, String password) {
synchronized (stateChangeLock) { synchronized (stateChangeLock) {
// TODO don't allow creating another account if one already exists
LocalAuthor localAuthor = identityManager.createLocalAuthor(name); LocalAuthor localAuthor = identityManager.createLocalAuthor(name);
identityManager.registerLocalAuthor(localAuthor); identityManager.registerLocalAuthor(localAuthor);
SecretKey key = crypto.generateSecretKey(); SecretKey key = crypto.generateSecretKey();

View File

@@ -127,9 +127,7 @@ class ClientHelperImpl implements ClientHelper {
@Override @Override
public Message getMessage(Transaction txn, MessageId m) throws DbException { public Message getMessage(Transaction txn, MessageId m) throws DbException {
byte[] raw = db.getRawMessage(txn, m); return db.getMessage(txn, m);
if (raw == null) return null;
return messageFactory.createMessage(m, raw);
} }
@Override @Override
@@ -149,8 +147,7 @@ class ClientHelperImpl implements ClientHelper {
@Override @Override
public BdfList getMessageAsList(Transaction txn, MessageId m) public BdfList getMessageAsList(Transaction txn, MessageId m)
throws DbException, FormatException { throws DbException, FormatException {
byte[] raw = db.getRawMessage(txn, m); byte[] raw = db.getMessage(txn, m).getRaw();
if (raw == null) return null;
return toList(raw, MESSAGE_HEADER_LENGTH, return toList(raw, MESSAGE_HEADER_LENGTH,
raw.length - MESSAGE_HEADER_LENGTH); raw.length - MESSAGE_HEADER_LENGTH);
} }

View File

@@ -6,6 +6,7 @@ import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.DataTooNewException; import org.briarproject.bramble.api.db.DataTooNewException;
import org.briarproject.bramble.api.db.DataTooOldException; import org.briarproject.bramble.api.db.DataTooOldException;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.MessageDeletedException;
import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.db.MigrationListener; import org.briarproject.bramble.api.db.MigrationListener;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
@@ -297,6 +298,15 @@ interface Database<T> {
*/ */
Collection<LocalAuthor> getLocalAuthors(T txn) throws DbException; Collection<LocalAuthor> getLocalAuthors(T txn) throws DbException;
/**
* Returns the message with the given ID.
* <p/>
* Read-only.
*
* @throws MessageDeletedException if the message has been deleted
*/
Message getMessage(T txn, MessageId m) throws DbException;
/** /**
* Returns the IDs and states of all dependencies of the given message. * Returns the IDs and states of all dependencies of the given message.
* For missing dependencies and dependencies in other groups, the state * For missing dependencies and dependencies in other groups, the state
@@ -464,15 +474,6 @@ interface Database<T> {
*/ */
long getNextSendTime(T txn, ContactId c) throws DbException; long getNextSendTime(T txn, ContactId c) throws DbException;
/**
* Returns the message with the given ID, in serialised form, or null if
* the message has been deleted.
* <p/>
* Read-only.
*/
@Nullable
byte[] getRawMessage(T txn, MessageId m) throws DbException;
/** /**
* Returns the IDs of some messages that are eligible to be sent to the * Returns the IDs of some messages that are eligible to be sent to the
* given contact and have been requested by the contact, up to the given * given contact and have been requested by the contact, up to the given

View File

@@ -307,16 +307,16 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
@Nullable @Nullable
@Override @Override
public Collection<byte[]> generateBatch(Transaction transaction, public Collection<Message> generateBatch(Transaction transaction,
ContactId c, int maxLength, int maxLatency) throws DbException { ContactId c, int maxLength, int maxLatency) throws DbException {
if (transaction.isReadOnly()) throw new IllegalArgumentException(); if (transaction.isReadOnly()) throw new IllegalArgumentException();
T txn = unbox(transaction); T txn = unbox(transaction);
if (!db.containsContact(txn, c)) if (!db.containsContact(txn, c))
throw new NoSuchContactException(); throw new NoSuchContactException();
Collection<MessageId> ids = db.getMessagesToSend(txn, c, maxLength); Collection<MessageId> ids = db.getMessagesToSend(txn, c, maxLength);
List<byte[]> messages = new ArrayList<>(ids.size()); List<Message> messages = new ArrayList<>(ids.size());
for (MessageId m : ids) { for (MessageId m : ids) {
messages.add(db.getRawMessage(txn, m)); messages.add(db.getMessage(txn, m));
db.updateExpiryTime(txn, c, m, maxLatency); db.updateExpiryTime(txn, c, m, maxLatency);
} }
if (ids.isEmpty()) return null; if (ids.isEmpty()) return null;
@@ -356,7 +356,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
@Nullable @Nullable
@Override @Override
public Collection<byte[]> generateRequestedBatch(Transaction transaction, public Collection<Message> generateRequestedBatch(Transaction transaction,
ContactId c, int maxLength, int maxLatency) throws DbException { ContactId c, int maxLength, int maxLatency) throws DbException {
if (transaction.isReadOnly()) throw new IllegalArgumentException(); if (transaction.isReadOnly()) throw new IllegalArgumentException();
T txn = unbox(transaction); T txn = unbox(transaction);
@@ -364,9 +364,9 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
throw new NoSuchContactException(); throw new NoSuchContactException();
Collection<MessageId> ids = db.getRequestedMessagesToSend(txn, c, Collection<MessageId> ids = db.getRequestedMessagesToSend(txn, c,
maxLength); maxLength);
List<byte[]> messages = new ArrayList<>(ids.size()); List<Message> messages = new ArrayList<>(ids.size());
for (MessageId m : ids) { for (MessageId m : ids) {
messages.add(db.getRawMessage(txn, m)); messages.add(db.getMessage(txn, m));
db.updateExpiryTime(txn, c, m, maxLatency); db.updateExpiryTime(txn, c, m, maxLatency);
} }
if (ids.isEmpty()) return null; if (ids.isEmpty()) return null;
@@ -457,6 +457,15 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
return db.getLocalAuthors(txn); return db.getLocalAuthors(txn);
} }
@Override
public Message getMessage(Transaction transaction, MessageId m)
throws DbException {
T txn = unbox(transaction);
if (!db.containsMessage(txn, m))
throw new NoSuchMessageException();
return db.getMessage(txn, m);
}
@Override @Override
public Collection<MessageId> getMessageIds(Transaction transaction, public Collection<MessageId> getMessageIds(Transaction transaction,
GroupId g) throws DbException { GroupId g) throws DbException {
@@ -487,16 +496,6 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
return db.getMessagesToShare(txn); return db.getMessagesToShare(txn);
} }
@Nullable
@Override
public byte[] getRawMessage(Transaction transaction, MessageId m)
throws DbException {
T txn = unbox(transaction);
if (!db.containsMessage(txn, m))
throw new NoSuchMessageException();
return db.getRawMessage(txn, m);
}
@Override @Override
public Map<MessageId, Metadata> getMessageMetadata(Transaction transaction, public Map<MessageId, Metadata> getMessageMetadata(Transaction transaction,
GroupId g) throws DbException { GroupId g) throws DbException {
@@ -656,7 +655,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
merged.putAll(s); merged.putAll(s);
if (!merged.equals(old)) { if (!merged.equals(old)) {
db.mergeSettings(txn, s, namespace); db.mergeSettings(txn, s, namespace);
transaction.attach(new SettingsUpdatedEvent(namespace)); transaction.attach(new SettingsUpdatedEvent(namespace, merged));
} }
} }

View File

@@ -7,6 +7,7 @@ import org.briarproject.bramble.api.db.DataTooNewException;
import org.briarproject.bramble.api.db.DataTooOldException; import org.briarproject.bramble.api.db.DataTooOldException;
import org.briarproject.bramble.api.db.DbClosedException; import org.briarproject.bramble.api.db.DbClosedException;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.MessageDeletedException;
import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.db.MigrationListener; import org.briarproject.bramble.api.db.MigrationListener;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
@@ -740,7 +741,7 @@ abstract class JdbcDatabase implements Database<Connection> {
boolean offered = removeOfferedMessage(txn, c, m.getId()); boolean offered = removeOfferedMessage(txn, c, m.getId());
boolean seen = offered || (sender != null && c.equals(sender)); boolean seen = offered || (sender != null && c.equals(sender));
addStatus(txn, m.getId(), c, m.getGroupId(), m.getTimestamp(), addStatus(txn, m.getId(), c, m.getGroupId(), m.getTimestamp(),
m.getLength(), state, e.getValue(), messageShared, m.getRawLength(), state, e.getValue(), messageShared,
false, seen); false, seen);
} }
// Update denormalised column in messageDependencies if dependency // Update denormalised column in messageDependencies if dependency
@@ -1482,6 +1483,32 @@ abstract class JdbcDatabase implements Database<Connection> {
} }
} }
@Override
public Message getMessage(Connection txn, MessageId m) throws DbException {
PreparedStatement ps = null;
ResultSet rs = null;
try {
String sql = "SELECT groupId, timestamp, raw FROM messages"
+ " WHERE messageId = ?";
ps = txn.prepareStatement(sql);
ps.setBytes(1, m.getBytes());
rs = ps.executeQuery();
if (!rs.next()) throw new DbStateException();
GroupId g = new GroupId(rs.getBytes(1));
long timestamp = rs.getLong(2);
byte[] raw = rs.getBytes(3);
if (rs.next()) throw new DbStateException();
rs.close();
ps.close();
if (raw == null) throw new MessageDeletedException();
return new Message(m, g, timestamp, raw);
} catch (SQLException e) {
tryToClose(rs);
tryToClose(ps);
throw new DbException(e);
}
}
@Override @Override
public Collection<MessageId> getMessageIds(Connection txn, GroupId g) public Collection<MessageId> getMessageIds(Connection txn, GroupId g)
throws DbException { throws DbException {
@@ -2018,30 +2045,6 @@ abstract class JdbcDatabase implements Database<Connection> {
} }
} }
@Override
@Nullable
public byte[] getRawMessage(Connection txn, MessageId m)
throws DbException {
PreparedStatement ps = null;
ResultSet rs = null;
try {
String sql = "SELECT raw FROM messages WHERE messageId = ?";
ps = txn.prepareStatement(sql);
ps.setBytes(1, m.getBytes());
rs = ps.executeQuery();
if (!rs.next()) throw new DbStateException();
byte[] raw = rs.getBytes(1);
if (rs.next()) throw new DbStateException();
rs.close();
ps.close();
return raw;
} catch (SQLException e) {
tryToClose(rs);
tryToClose(ps);
throw new DbException(e);
}
}
@Override @Override
public Collection<MessageId> getRequestedMessagesToSend(Connection txn, public Collection<MessageId> getRequestedMessagesToSend(Connection txn,
ContactId c, int maxLength) throws DbException { ContactId c, int maxLength) throws DbException {

View File

@@ -102,6 +102,7 @@ class KeyAgreementTaskImpl extends Thread implements KeyAgreementTask,
KeyAgreementTransport transport = KeyAgreementTransport transport =
connector.connect(remotePayload, alice); connector.connect(remotePayload, alice);
if (transport == null) { if (transport == null) {
LOG.warning("Key agreement failed. Transport was null.");
// Notify caller that the connection failed // Notify caller that the connection failed
eventBus.broadcast(new KeyAgreementFailedEvent()); eventBus.broadcast(new KeyAgreementFailedEvent());
return; return;

View File

@@ -21,6 +21,7 @@ import org.briarproject.bramble.api.plugin.event.BluetoothEnabledEvent;
import org.briarproject.bramble.api.plugin.event.DisableBluetoothEvent; import org.briarproject.bramble.api.plugin.event.DisableBluetoothEvent;
import org.briarproject.bramble.api.plugin.event.EnableBluetoothEvent; import org.briarproject.bramble.api.plugin.event.EnableBluetoothEvent;
import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.properties.TransportProperties;
import org.briarproject.bramble.api.settings.Settings;
import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent; import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent;
import org.briarproject.bramble.util.StringUtils; import org.briarproject.bramble.util.StringUtils;
@@ -146,16 +147,15 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
} }
updateProperties(); updateProperties();
running = true; running = true;
loadSettings(); loadSettings(callback.getSettings());
if (shouldAllowContactConnections()) { if (shouldAllowContactConnections()) {
if (isAdapterEnabled()) bind(); if (isAdapterEnabled()) bind();
else enableAdapter(); else enableAdapter();
} }
} }
private void loadSettings() { private void loadSettings(Settings settings) {
contactConnections = contactConnections = settings.getBoolean(PREF_BT_ENABLE, false);
callback.getSettings().getBoolean(PREF_BT_ENABLE, false);
} }
private boolean shouldAllowContactConnections() { private boolean shouldAllowContactConnections() {
@@ -387,7 +387,7 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
} else if (e instanceof SettingsUpdatedEvent) { } else if (e instanceof SettingsUpdatedEvent) {
SettingsUpdatedEvent s = (SettingsUpdatedEvent) e; SettingsUpdatedEvent s = (SettingsUpdatedEvent) e;
if (s.getNamespace().equals(ID.getString())) if (s.getNamespace().equals(ID.getString()))
ioExecutor.execute(this::onSettingsUpdated); ioExecutor.execute(() -> onSettingsUpdated(s.getSettings()));
} else if (e instanceof KeyAgreementListeningEvent) { } else if (e instanceof KeyAgreementListeningEvent) {
ioExecutor.execute(connectionLimiter::keyAgreementStarted); ioExecutor.execute(connectionLimiter::keyAgreementStarted);
} else if (e instanceof KeyAgreementStoppedListeningEvent) { } else if (e instanceof KeyAgreementStoppedListeningEvent) {
@@ -395,9 +395,9 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
} }
} }
private void onSettingsUpdated() { private void onSettingsUpdated(Settings settings) {
boolean wasAllowed = shouldAllowContactConnections(); boolean wasAllowed = shouldAllowContactConnections();
loadSettings(); loadSettings(settings);
boolean isAllowed = shouldAllowContactConnections(); boolean isAllowed = shouldAllowContactConnections();
if (wasAllowed && !isAllowed) { if (wasAllowed && !isAllowed) {
LOG.info("Contact connections disabled"); LOG.info("Contact connections disabled");

View File

@@ -24,7 +24,7 @@ import java.net.SocketException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Enumeration;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
@@ -35,6 +35,9 @@ import java.util.regex.Pattern;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static java.net.NetworkInterface.getNetworkInterfaces;
import static java.util.Collections.emptyList;
import static java.util.Collections.list;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.logException;
@@ -303,16 +306,16 @@ abstract class TcpPlugin implements DuplexPlugin {
} }
Collection<InetAddress> getLocalIpAddresses() { Collection<InetAddress> getLocalIpAddresses() {
List<NetworkInterface> ifaces;
try { try {
ifaces = Collections.list(NetworkInterface.getNetworkInterfaces()); Enumeration<NetworkInterface> ifaces = getNetworkInterfaces();
if (ifaces == null) return emptyList();
List<InetAddress> addrs = new ArrayList<>();
for (NetworkInterface iface : list(ifaces))
addrs.addAll(list(iface.getInetAddresses()));
return addrs;
} catch (SocketException e) { } catch (SocketException e) {
logException(LOG, WARNING, e); logException(LOG, WARNING, e);
return Collections.emptyList(); return emptyList();
} }
List<InetAddress> addrs = new ArrayList<>();
for (NetworkInterface iface : ifaces)
addrs.addAll(Collections.list(iface.getInetAddresses()));
return addrs;
} }
} }

View File

@@ -1,7 +1,6 @@
package org.briarproject.bramble.plugin.tor; package org.briarproject.bramble.plugin.tor;
import org.briarproject.bramble.api.lifecycle.IoExecutor; import org.briarproject.bramble.api.lifecycle.IoExecutor;
import org.briarproject.bramble.api.system.ResourceProvider;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
@@ -24,14 +23,11 @@ class CircumventionProviderImpl implements CircumventionProvider {
private static final Set<String> BRIDGES_WORK_IN_COUNTRIES = private static final Set<String> BRIDGES_WORK_IN_COUNTRIES =
new HashSet<>(asList(BRIDGES)); new HashSet<>(asList(BRIDGES));
private final ResourceProvider resourceProvider;
@Nullable @Nullable
private volatile List<String> bridges = null; private volatile List<String> bridges = null;
@Inject @Inject
CircumventionProviderImpl(ResourceProvider resourceProvider) { CircumventionProviderImpl() {
this.resourceProvider = resourceProvider;
} }
@Override @Override
@@ -50,8 +46,8 @@ class CircumventionProviderImpl implements CircumventionProvider {
List<String> bridges = this.bridges; List<String> bridges = this.bridges;
if (bridges != null) return new ArrayList<>(bridges); if (bridges != null) return new ArrayList<>(bridges);
InputStream is = InputStream is = getClass().getClassLoader()
resourceProvider.getResourceInputStream(BRIDGE_FILE_NAME); .getResourceAsStream(BRIDGE_FILE_NAME);
Scanner scanner = new Scanner(is); Scanner scanner = new Scanner(is);
bridges = new ArrayList<>(); bridges = new ArrayList<>();

View File

@@ -64,11 +64,11 @@ import static net.freehaven.tor.control.TorControlCommands.HS_ADDRESS;
import static net.freehaven.tor.control.TorControlCommands.HS_PRIVKEY; import static net.freehaven.tor.control.TorControlCommands.HS_PRIVKEY;
import static org.briarproject.bramble.api.plugin.TorConstants.CONTROL_PORT; import static org.briarproject.bramble.api.plugin.TorConstants.CONTROL_PORT;
import static org.briarproject.bramble.api.plugin.TorConstants.ID; import static org.briarproject.bramble.api.plugin.TorConstants.ID;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_DISABLE_BLOCKED; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_MOBILE;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_ALWAYS; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_AUTOMATIC;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_NEVER; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_NEVER;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_WIFI; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_WITH_BRIDGES;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_PORT; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_PORT;
import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION; import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION;
import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.logException;
@@ -108,6 +108,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private volatile ServerSocket socket = null; private volatile ServerSocket socket = null;
private volatile Socket controlSocket = null; private volatile Socket controlSocket = null;
private volatile TorControlConnection controlConnection = null; private volatile TorControlConnection controlConnection = null;
private volatile Settings settings = null;
protected volatile boolean running = false; protected volatile boolean running = false;
@@ -166,10 +167,20 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
@Override @Override
public void start() throws PluginException { public void start() throws PluginException {
if (used.getAndSet(true)) throw new IllegalStateException(); if (used.getAndSet(true)) throw new IllegalStateException();
if (!torDirectory.exists()) {
if (!torDirectory.mkdirs()) {
LOG.warning("Could not create Tor directory.");
throw new PluginException();
}
}
// Load the settings
settings = callback.getSettings();
// Install or update the assets if necessary // Install or update the assets if necessary
if (!assetsAreUpToDate()) installAssets(); if (!assetsAreUpToDate()) installAssets();
if (cookieFile.exists() && !cookieFile.delete()) if (cookieFile.exists() && !cookieFile.delete())
LOG.warning("Old auth cookie not deleted"); LOG.warning("Old auth cookie not deleted");
// Migrate old settings before having a chance to stop
migrateSettings();
// Start a new Tor process // Start a new Tor process
LOG.info("Starting Tor"); LOG.info("Starting Tor");
String torPath = torFile.getAbsolutePath(); String torPath = torFile.getAbsolutePath();
@@ -286,22 +297,23 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private InputStream getTorInputStream() throws IOException { private InputStream getTorInputStream() throws IOException {
if (LOG.isLoggable(INFO)) if (LOG.isLoggable(INFO))
LOG.info("Installing Tor binary for " + architecture); LOG.info("Installing Tor binary for " + architecture);
InputStream in = InputStream in = resourceProvider
resourceProvider.getResourceInputStream("tor_" + architecture); .getResourceInputStream("tor_" + architecture, ".zip");
ZipInputStream zin = new ZipInputStream(in); ZipInputStream zin = new ZipInputStream(in);
if (zin.getNextEntry() == null) throw new IOException(); if (zin.getNextEntry() == null) throw new IOException();
return zin; return zin;
} }
private InputStream getGeoIpInputStream() throws IOException { private InputStream getGeoIpInputStream() throws IOException {
InputStream in = resourceProvider.getResourceInputStream("geoip"); InputStream in = resourceProvider.getResourceInputStream("geoip",
".zip");
ZipInputStream zin = new ZipInputStream(in); ZipInputStream zin = new ZipInputStream(in);
if (zin.getNextEntry() == null) throw new IOException(); if (zin.getNextEntry() == null) throw new IOException();
return zin; return zin;
} }
private InputStream getConfigInputStream() { private InputStream getConfigInputStream() {
return resourceProvider.getResourceInputStream("torrc"); return getClass().getClassLoader().getResourceAsStream("torrc");
} }
private void tryToClose(@Nullable Closeable c) { private void tryToClose(@Nullable Closeable c) {
@@ -348,7 +360,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private void bind() { private void bind() {
ioExecutor.execute(() -> { ioExecutor.execute(() -> {
// If there's already a port number stored in config, reuse it // If there's already a port number stored in config, reuse it
String portString = callback.getSettings().get(PREF_TOR_PORT); String portString = settings.get(PREF_TOR_PORT);
int port; int port;
if (StringUtils.isNullOrEmpty(portString)) port = 0; if (StringUtils.isNullOrEmpty(portString)) port = 0;
else port = Integer.parseInt(portString); else port = Integer.parseInt(portString);
@@ -393,7 +405,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private void publishHiddenService(String port) { private void publishHiddenService(String port) {
if (!running) return; if (!running) return;
LOG.info("Creating hidden service"); LOG.info("Creating hidden service");
String privKey = callback.getSettings().get(HS_PRIVKEY); String privKey = settings.get(HS_PRIVKEY);
Map<Integer, String> portLines = Map<Integer, String> portLines =
Collections.singletonMap(80, "127.0.0.1:" + port); Collections.singletonMap(80, "127.0.0.1:" + port);
Map<String, String> response; Map<String, String> response;
@@ -576,7 +588,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
@Override @Override
public void orConnStatus(String status, String orName) { public void orConnStatus(String status, String orName) {
if (LOG.isLoggable(INFO)) LOG.info("OR connection " + status); if (LOG.isLoggable(INFO))
LOG.info("OR connection " + status + " " + orName);
if (status.equals("CLOSED") || status.equals("FAILED")) { if (status.equals("CLOSED") || status.equals("FAILED")) {
// Check whether we've lost connectivity // Check whether we've lost connectivity
updateConnectionStatus(networkManager.getNetworkStatus()); updateConnectionStatus(networkManager.getNetworkStatus());
@@ -613,6 +626,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
SettingsUpdatedEvent s = (SettingsUpdatedEvent) e; SettingsUpdatedEvent s = (SettingsUpdatedEvent) e;
if (s.getNamespace().equals(ID.getString())) { if (s.getNamespace().equals(ID.getString())) {
LOG.info("Tor settings updated"); LOG.info("Tor settings updated");
settings = s.getSettings();
updateConnectionStatus(networkManager.getNetworkStatus()); updateConnectionStatus(networkManager.getNetworkStatus());
} }
} else if (e instanceof NetworkStatusEvent) { } else if (e instanceof NetworkStatusEvent) {
@@ -628,10 +642,11 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
String country = locationUtils.getCurrentCountry(); String country = locationUtils.getCurrentCountry();
boolean blocked = boolean blocked =
circumventionProvider.isTorProbablyBlocked(country); circumventionProvider.isTorProbablyBlocked(country);
Settings s = callback.getSettings(); int network = settings.getInt(PREF_TOR_NETWORK,
int network = s.getInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_ALWAYS); PREF_TOR_NETWORK_AUTOMATIC);
boolean disableWhenBlocked = boolean useMobile = settings.getBoolean(PREF_TOR_MOBILE, true);
s.getBoolean(PREF_TOR_DISABLE_BLOCKED, true); boolean bridgesWork = circumventionProvider.doBridgesWork(country);
boolean automatic = network == PREF_TOR_NETWORK_AUTOMATIC;
if (LOG.isLoggable(INFO)) { if (LOG.isLoggable(INFO)) {
LOG.info("Online: " + online + ", wifi: " + wifi); LOG.info("Online: " + online + ", wifi: " + wifi);
@@ -643,25 +658,20 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
if (!online) { if (!online) {
LOG.info("Disabling network, device is offline"); LOG.info("Disabling network, device is offline");
enableNetwork(false); enableNetwork(false);
} else if (network == PREF_TOR_NETWORK_NEVER } else if (network == PREF_TOR_NETWORK_NEVER ||
|| (network == PREF_TOR_NETWORK_WIFI && !wifi)) { (!useMobile && !wifi)) {
LOG.info("Disabling network due to data setting"); LOG.info("Disabling network due to setting");
enableNetwork(false); enableNetwork(false);
} else if (blocked) { } else if (automatic && blocked && !bridgesWork) {
if (circumventionProvider.doBridgesWork(country)) { LOG.info("Disabling network, country is blocked");
LOG.info("Enabling network, using bridges"); enableNetwork(false);
enableBridges(true); } else if (network == PREF_TOR_NETWORK_WITH_BRIDGES ||
enableNetwork(true); (automatic && bridgesWork)) {
} else if (disableWhenBlocked) { LOG.info("Enabling network, using bridges");
LOG.info("Disabling network, country is blocked"); enableBridges(true);
enableNetwork(false); enableNetwork(true);
} else {
LOG.info("Enabling network but country is blocked");
enableBridges(false);
enableNetwork(true);
}
} else { } else {
LOG.info("Enabling network"); LOG.info("Enabling network, not using bridges");
enableBridges(false); enableBridges(false);
enableNetwork(true); enableNetwork(true);
} }
@@ -671,6 +681,21 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
}); });
} }
// TODO remove when sufficient time has passed. Added 2018-08-15
private void migrateSettings() {
Settings sOld = callback.getSettings();
int oldNetwork = sOld.getInt("network", -1);
if (oldNetwork == -1) return;
Settings s = new Settings();
if (oldNetwork == 0) {
s.putInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_NEVER);
} else if (oldNetwork == 1) {
s.putBoolean(PREF_TOR_MOBILE, false);
}
s.putInt("network", -1);
callback.mergeSettings(s);
}
private static class ConnectionStatus { private static class ConnectionStatus {
// All of the following are locking: this // All of the following are locking: this

View File

@@ -164,7 +164,6 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
for (Entry<TransportId, LatestUpdate> e : latest.entrySet()) { for (Entry<TransportId, LatestUpdate> e : latest.entrySet()) {
BdfList message = clientHelper.getMessageAsList(txn, BdfList message = clientHelper.getMessageAsList(txn,
e.getValue().messageId); e.getValue().messageId);
if (message == null) throw new DbException();
local.put(e.getKey(), parseProperties(message)); local.put(e.getKey(), parseProperties(message));
} }
return local; return local;
@@ -187,7 +186,6 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
// Retrieve and parse the latest local properties // Retrieve and parse the latest local properties
BdfList message = clientHelper.getMessageAsList(txn, BdfList message = clientHelper.getMessageAsList(txn,
latest.messageId); latest.messageId);
if (message == null) throw new DbException();
p = parseProperties(message); p = parseProperties(message);
} }
db.commitTransaction(txn); db.commitTransaction(txn);
@@ -227,7 +225,6 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
// Retrieve and parse the latest remote properties // Retrieve and parse the latest remote properties
BdfList message = BdfList message =
clientHelper.getMessageAsList(txn, latest.messageId); clientHelper.getMessageAsList(txn, latest.messageId);
if (message == null) throw new DbException();
return parseProperties(message); return parseProperties(message);
} catch (FormatException e) { } catch (FormatException e) {
throw new DbException(e); throw new DbException(e);
@@ -265,7 +262,6 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
} else { } else {
BdfList message = clientHelper.getMessageAsList(txn, BdfList message = clientHelper.getMessageAsList(txn,
latest.messageId); latest.messageId);
if (message == null) throw new DbException();
TransportProperties old = parseProperties(message); TransportProperties old = parseProperties(message);
merged = new TransportProperties(old); merged = new TransportProperties(old);
merged.putAll(p); merged.putAll(p);

View File

@@ -34,6 +34,12 @@ class SettingsManagerImpl implements SettingsManager {
return s; return s;
} }
@Override
public Settings getSettings(Transaction txn, String namespace)
throws DbException {
return db.getSettings(txn, namespace);
}
@Override @Override
public void mergeSettings(Settings s, String namespace) throws DbException { public void mergeSettings(Settings s, String namespace) throws DbException {
Transaction txn = db.startTransaction(false); Transaction txn = db.startTransaction(false);

View File

@@ -13,6 +13,7 @@ import org.briarproject.bramble.api.lifecycle.IoExecutor;
import org.briarproject.bramble.api.lifecycle.event.LifecycleEvent; import org.briarproject.bramble.api.lifecycle.event.LifecycleEvent;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.Ack; import org.briarproject.bramble.api.sync.Ack;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.Offer; import org.briarproject.bramble.api.sync.Offer;
import org.briarproject.bramble.api.sync.Request; import org.briarproject.bramble.api.sync.Request;
import org.briarproject.bramble.api.sync.SyncRecordWriter; import org.briarproject.bramble.api.sync.SyncRecordWriter;
@@ -274,7 +275,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
if (!generateBatchQueued.getAndSet(false)) if (!generateBatchQueued.getAndSet(false))
throw new AssertionError(); throw new AssertionError();
try { try {
Collection<byte[]> b; Collection<Message> b;
Transaction txn = db.startTransaction(false); Transaction txn = db.startTransaction(false);
try { try {
b = db.generateRequestedBatch(txn, contactId, b = db.generateRequestedBatch(txn, contactId,
@@ -296,9 +297,9 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
private class WriteBatch implements ThrowingRunnable<IOException> { private class WriteBatch implements ThrowingRunnable<IOException> {
private final Collection<byte[]> batch; private final Collection<Message> batch;
private WriteBatch(Collection<byte[]> batch) { private WriteBatch(Collection<Message> batch) {
this.batch = batch; this.batch = batch;
} }
@@ -306,7 +307,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
@Override @Override
public void run() throws IOException { public void run() throws IOException {
if (interrupted) return; if (interrupted) return;
for (byte[] raw : batch) recordWriter.writeMessage(raw); for (Message m : batch) recordWriter.writeMessage(m);
LOG.info("Sent batch"); LOG.info("Sent batch");
generateBatch(); generateBatch();
} }

View File

@@ -13,6 +13,7 @@ import org.briarproject.bramble.api.lifecycle.IoExecutor;
import org.briarproject.bramble.api.lifecycle.event.LifecycleEvent; import org.briarproject.bramble.api.lifecycle.event.LifecycleEvent;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.Ack; import org.briarproject.bramble.api.sync.Ack;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.SyncRecordWriter; import org.briarproject.bramble.api.sync.SyncRecordWriter;
import org.briarproject.bramble.api.sync.SyncSession; import org.briarproject.bramble.api.sync.SyncSession;
import org.briarproject.bramble.api.transport.StreamWriter; import org.briarproject.bramble.api.transport.StreamWriter;
@@ -171,7 +172,7 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
public void run() { public void run() {
if (interrupted) return; if (interrupted) return;
try { try {
Collection<byte[]> b; Collection<Message> b;
Transaction txn = db.startTransaction(false); Transaction txn = db.startTransaction(false);
try { try {
b = db.generateBatch(txn, contactId, b = db.generateBatch(txn, contactId,
@@ -193,9 +194,9 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
private class WriteBatch implements ThrowingRunnable<IOException> { private class WriteBatch implements ThrowingRunnable<IOException> {
private final Collection<byte[]> batch; private final Collection<Message> batch;
private WriteBatch(Collection<byte[]> batch) { private WriteBatch(Collection<Message> batch) {
this.batch = batch; this.batch = batch;
} }
@@ -203,7 +204,7 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
@Override @Override
public void run() throws IOException { public void run() throws IOException {
if (interrupted) return; if (interrupted) return;
for (byte[] raw : batch) recordWriter.writeMessage(raw); for (Message m : batch) recordWriter.writeMessage(m);
LOG.info("Sent batch"); LOG.info("Sent batch");
dbExecutor.execute(new GenerateBatch()); dbExecutor.execute(new GenerateBatch());
} }

View File

@@ -4,6 +4,7 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.record.Record; import org.briarproject.bramble.api.record.Record;
import org.briarproject.bramble.api.record.RecordWriter; import org.briarproject.bramble.api.record.RecordWriter;
import org.briarproject.bramble.api.sync.Ack; import org.briarproject.bramble.api.sync.Ack;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.sync.Offer; import org.briarproject.bramble.api.sync.Offer;
import org.briarproject.bramble.api.sync.Request; import org.briarproject.bramble.api.sync.Request;
@@ -44,8 +45,8 @@ class SyncRecordWriterImpl implements SyncRecordWriter {
} }
@Override @Override
public void writeMessage(byte[] raw) throws IOException { public void writeMessage(Message m) throws IOException {
writer.writeRecord(new Record(PROTOCOL_VERSION, MESSAGE, raw)); writer.writeRecord(new Record(PROTOCOL_VERSION, MESSAGE, m.getRaw()));
} }
@Override @Override

View File

@@ -16,7 +16,6 @@ import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.InvalidMessageException; import org.briarproject.bramble.api.sync.InvalidMessageException;
import org.briarproject.bramble.api.sync.Message; import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageContext; import org.briarproject.bramble.api.sync.MessageContext;
import org.briarproject.bramble.api.sync.MessageFactory;
import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.sync.ValidationManager; import org.briarproject.bramble.api.sync.ValidationManager;
import org.briarproject.bramble.api.sync.event.MessageAddedEvent; import org.briarproject.bramble.api.sync.event.MessageAddedEvent;
@@ -52,7 +51,6 @@ class ValidationManagerImpl implements ValidationManager, Service,
private final DatabaseComponent db; private final DatabaseComponent db;
private final Executor dbExecutor, validationExecutor; private final Executor dbExecutor, validationExecutor;
private final MessageFactory messageFactory;
private final Map<ClientMajorVersion, MessageValidator> validators; private final Map<ClientMajorVersion, MessageValidator> validators;
private final Map<ClientMajorVersion, IncomingMessageHook> hooks; private final Map<ClientMajorVersion, IncomingMessageHook> hooks;
private final AtomicBoolean used = new AtomicBoolean(false); private final AtomicBoolean used = new AtomicBoolean(false);
@@ -60,12 +58,10 @@ class ValidationManagerImpl implements ValidationManager, Service,
@Inject @Inject
ValidationManagerImpl(DatabaseComponent db, ValidationManagerImpl(DatabaseComponent db,
@DatabaseExecutor Executor dbExecutor, @DatabaseExecutor Executor dbExecutor,
@ValidationExecutor Executor validationExecutor, @ValidationExecutor Executor validationExecutor) {
MessageFactory messageFactory) {
this.db = db; this.db = db;
this.dbExecutor = dbExecutor; this.dbExecutor = dbExecutor;
this.validationExecutor = validationExecutor; this.validationExecutor = validationExecutor;
this.messageFactory = messageFactory;
validators = new ConcurrentHashMap<>(); validators = new ConcurrentHashMap<>();
hooks = new ConcurrentHashMap<>(); hooks = new ConcurrentHashMap<>();
} }
@@ -128,9 +124,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
Transaction txn = db.startTransaction(true); Transaction txn = db.startTransaction(true);
try { try {
MessageId id = unvalidated.poll(); MessageId id = unvalidated.poll();
byte[] raw = db.getRawMessage(txn, id); m = db.getMessage(txn, id);
if (raw == null) throw new DbException();
m = messageFactory.createMessage(id, raw);
g = db.getGroup(txn, m.getGroupId()); g = db.getGroup(txn, m.getGroupId());
db.commitTransaction(txn); db.commitTransaction(txn);
} finally { } finally {
@@ -197,9 +191,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
invalidateMessage(txn, id); invalidateMessage(txn, id);
invalidate = getDependentsToInvalidate(txn, id); invalidate = getDependentsToInvalidate(txn, id);
} else if (allDelivered) { } else if (allDelivered) {
byte[] raw = db.getRawMessage(txn, id); Message m = db.getMessage(txn, id);
if (raw == null) throw new DbException();
Message m = messageFactory.createMessage(id, raw);
Group g = db.getGroup(txn, m.getGroupId()); Group g = db.getGroup(txn, m.getGroupId());
ClientId c = g.getClientId(); ClientId c = g.getClientId();
int majorVersion = g.getMajorVersion(); int majorVersion = g.getMajorVersion();

View File

@@ -7,13 +7,15 @@ import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.NetworkInterface; import java.net.NetworkInterface;
import java.util.Collections; import java.util.Enumeration;
import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Properties; import java.util.Properties;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import static java.net.NetworkInterface.getNetworkInterfaces;
import static java.util.Collections.list;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
abstract class AbstractSecureRandomProvider implements SecureRandomProvider { abstract class AbstractSecureRandomProvider implements SecureRandomProvider {
@@ -23,13 +25,14 @@ abstract class AbstractSecureRandomProvider implements SecureRandomProvider {
out.writeLong(System.currentTimeMillis()); out.writeLong(System.currentTimeMillis());
out.writeLong(System.nanoTime()); out.writeLong(System.nanoTime());
out.writeLong(Runtime.getRuntime().freeMemory()); out.writeLong(Runtime.getRuntime().freeMemory());
List<NetworkInterface> ifaces = Enumeration<NetworkInterface> ifaces = getNetworkInterfaces();
Collections.list(NetworkInterface.getNetworkInterfaces()); if (ifaces != null) {
for (NetworkInterface i : ifaces) { for (NetworkInterface i : list(ifaces)) {
List<InetAddress> addrs = Collections.list(i.getInetAddresses()); for (InetAddress a : list(i.getInetAddresses()))
for (InetAddress a : addrs) out.write(a.getAddress()); out.write(a.getAddress());
byte[] hardware = i.getHardwareAddress(); byte[] hardware = i.getHardwareAddress();
if (hardware != null) out.write(hardware); if (hardware != null) out.write(hardware);
}
} }
for (Entry<String, String> e : System.getenv().entrySet()) { for (Entry<String, String> e : System.getenv().entrySet()) {
out.writeUTF(e.getKey()); out.writeUTF(e.getKey());

View File

@@ -139,7 +139,7 @@ class ClientVersioningManagerImpl implements ClientVersioningManager, Client,
} }
@Override @Override
public void stopService() throws ServiceException { public void stopService() {
} }
@Override @Override
@@ -274,9 +274,7 @@ class ClientVersioningManagerImpl implements ClientVersioningManager, Client,
private List<ClientVersion> loadClientVersions(Transaction txn, private List<ClientVersion> loadClientVersions(Transaction txn,
MessageId m) throws DbException { MessageId m) throws DbException {
try { try {
BdfList body = clientHelper.getMessageAsList(txn, m); return parseClientVersions(clientHelper.getMessageAsList(txn, m));
if (body == null) throw new DbException();
return parseClientVersions(body);
} catch (FormatException e) { } catch (FormatException e) {
throw new DbException(e); throw new DbException(e);
} }
@@ -359,9 +357,7 @@ class ClientVersioningManagerImpl implements ClientVersioningManager, Client,
private Update loadUpdate(Transaction txn, MessageId m) throws DbException { private Update loadUpdate(Transaction txn, MessageId m) throws DbException {
try { try {
BdfList body = clientHelper.getMessageAsList(txn, m); return parseUpdate(clientHelper.getMessageAsList(txn, m));
if (body == null) throw new DbException();
return parseUpdate(body);
} catch (FormatException e) { } catch (FormatException e) {
throw new DbException(e); throw new DbException(e);
} }

View File

@@ -3,6 +3,6 @@ Bridge 67.205.189.122:8443 12D64D5D44E20169585E7378580C0D33A872AD98
Bridge 45.32.148.146:8443 0CE016FB2462D8BF179AE71F7D702D09DEAC3F1D Bridge 45.32.148.146:8443 0CE016FB2462D8BF179AE71F7D702D09DEAC3F1D
Bridge 148.251.90.59:7510 019F727CA6DCA6CA5C90B55E477B7D87981E75BC Bridge 148.251.90.59:7510 019F727CA6DCA6CA5C90B55E477B7D87981E75BC
Bridge 195.91.239.8:9001 BA83F62551545655BBEBBFF353A45438D73FD45A Bridge 195.91.239.8:9001 BA83F62551545655BBEBBFF353A45438D73FD45A
Bridge 185.165.184.217:6429 64CC94BEC51254E4409AD059192833854CCB95F0
Bridge 45.55.1.74:8443 6F18FEFBB0CAECD5ABA755312FCCB34FC11A7AB8 Bridge 45.55.1.74:8443 6F18FEFBB0CAECD5ABA755312FCCB34FC11A7AB8
Bridge 95.85.40.163:9001 40057BE9CF76B6C5BDBE713753468BE0A990DE9C Bridge 97.107.131.168:65341 DCDA8A5F1E2C50A6756A58462E5CF4B6B2DFDE26
Bridge 85.229.131.78:444 50E433CCC5FEC11CC34CB4D92033561E065EA106

View File

@@ -18,6 +18,8 @@ import org.junit.Test;
import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH; import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE; import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
import static org.briarproject.bramble.test.TestUtils.getMessage;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame; import static org.junit.Assert.assertSame;
@@ -28,8 +30,7 @@ public class BdfMessageValidatorTest extends ValidatorTestCase {
new BdfMessageValidator(clientHelper, metadataEncoder, clock) { new BdfMessageValidator(clientHelper, metadataEncoder, clock) {
@Override @Override
protected BdfMessageContext validateMessage(Message m, Group g, protected BdfMessageContext validateMessage(Message m, Group g,
BdfList body) BdfList body) {
throws InvalidMessageException, FormatException {
throw new AssertionError(); throw new AssertionError();
} }
}; };
@@ -69,7 +70,7 @@ public class BdfMessageValidatorTest extends ValidatorTestCase {
metadataEncoder, clock) { metadataEncoder, clock) {
@Override @Override
protected BdfMessageContext validateMessage(Message m, Group g, protected BdfMessageContext validateMessage(Message m, Group g,
BdfList b) throws InvalidMessageException, FormatException { BdfList b) {
assertSame(message, m); assertSame(message, m);
assertSame(group, g); assertSame(group, g);
assertSame(body, b); assertSame(body, b);
@@ -83,11 +84,12 @@ public class BdfMessageValidatorTest extends ValidatorTestCase {
@Test(expected = InvalidMessageException.class) @Test(expected = InvalidMessageException.class)
public void testRejectsTooShortMessage() throws Exception { public void testRejectsTooShortMessage() throws Exception {
byte[] invalidRaw = new byte[MESSAGE_HEADER_LENGTH]; byte[] invalidRaw = getRandomBytes(MESSAGE_HEADER_LENGTH);
// Use a mock message so the length of the raw message can be invalid // Use a mock message so the length of the raw message can be invalid
Message invalidMessage = context.mock(Message.class); Message invalidMessage = context.mock(Message.class);
context.checking(new Expectations() {{ context.checking(new Expectations() {{
//noinspection ResultOfMethodCallIgnored
oneOf(invalidMessage).getTimestamp(); oneOf(invalidMessage).getTimestamp();
will(returnValue(timestamp)); will(returnValue(timestamp));
oneOf(clock).currentTimeMillis(); oneOf(clock).currentTimeMillis();
@@ -101,15 +103,13 @@ public class BdfMessageValidatorTest extends ValidatorTestCase {
@Test @Test
public void testAcceptsMinLengthMessage() throws Exception { public void testAcceptsMinLengthMessage() throws Exception {
byte[] shortRaw = new byte[MESSAGE_HEADER_LENGTH + 1]; Message shortMessage = getMessage(groupId, MESSAGE_HEADER_LENGTH + 1);
Message shortMessage =
new Message(messageId, groupId, timestamp, shortRaw);
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(clock).currentTimeMillis(); oneOf(clock).currentTimeMillis();
will(returnValue(timestamp)); will(returnValue(timestamp));
oneOf(clientHelper).toList(shortRaw, MESSAGE_HEADER_LENGTH, oneOf(clientHelper).toList(shortMessage.getRaw(),
shortRaw.length - MESSAGE_HEADER_LENGTH); MESSAGE_HEADER_LENGTH, 1);
will(returnValue(body)); will(returnValue(body));
oneOf(metadataEncoder).encode(dictionary); oneOf(metadataEncoder).encode(dictionary);
will(returnValue(meta)); will(returnValue(meta));
@@ -120,7 +120,7 @@ public class BdfMessageValidatorTest extends ValidatorTestCase {
metadataEncoder, clock) { metadataEncoder, clock) {
@Override @Override
protected BdfMessageContext validateMessage(Message m, Group g, protected BdfMessageContext validateMessage(Message m, Group g,
BdfList b) throws InvalidMessageException, FormatException { BdfList b) {
assertSame(shortMessage, m); assertSame(shortMessage, m);
assertSame(group, g); assertSame(group, g);
assertSame(body, b); assertSame(body, b);
@@ -160,7 +160,7 @@ public class BdfMessageValidatorTest extends ValidatorTestCase {
metadataEncoder, clock) { metadataEncoder, clock) {
@Override @Override
protected BdfMessageContext validateMessage(Message m, Group g, protected BdfMessageContext validateMessage(Message m, Group g,
BdfList b) throws InvalidMessageException, FormatException { BdfList b) throws FormatException {
throw new FormatException(); throw new FormatException();
} }
}; };

View File

@@ -39,6 +39,7 @@ import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_N
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
import static org.briarproject.bramble.test.TestUtils.getAuthor; import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getMessage;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.util.StringUtils.getRandomString; import static org.briarproject.bramble.util.StringUtils.getRandomString;
@@ -67,11 +68,9 @@ public class ClientHelperImplTest extends BrambleTestCase {
private final GroupId groupId = new GroupId(getRandomId()); private final GroupId groupId = new GroupId(getRandomId());
private final BdfDictionary dictionary = new BdfDictionary(); private final BdfDictionary dictionary = new BdfDictionary();
private final long timestamp = 42L; private final Message message = getMessage(groupId);
private final byte[] rawMessage = getRandomBytes(42); private final MessageId messageId = message.getId();
private final MessageId messageId = new MessageId(getRandomId()); private final long timestamp = message.getTimestamp();
private final Message message =
new Message(messageId, groupId, timestamp, rawMessage);
private final Metadata metadata = new Metadata(); private final Metadata metadata = new Metadata();
private final BdfList list = BdfList.of("Sign this!", getRandomBytes(42)); private final BdfList list = BdfList.of("Sign this!", getRandomBytes(42));
private final String label = StringUtils.getRandomString(5); private final String label = StringUtils.getRandomString(5);
@@ -120,8 +119,8 @@ public class ClientHelperImplTest extends BrambleTestCase {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn)); will(returnValue(txn));
oneOf(db).getRawMessage(txn, messageId); oneOf(db).getMessage(txn, messageId);
will(returnValue(rawMessage)); will(returnValue(message));
oneOf(db).commitTransaction(txn); oneOf(db).commitTransaction(txn);
oneOf(db).endTransaction(txn); oneOf(db).endTransaction(txn);
}}); }});
@@ -267,7 +266,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
public void testToList() throws Exception { public void testToList() throws Exception {
expectToList(true); expectToList(true);
assertEquals(list, clientHelper.toList(rawMessage)); assertEquals(list, clientHelper.toList(getRandomBytes(123)));
context.assertIsSatisfied(); context.assertIsSatisfied();
} }
@@ -276,7 +275,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
expectToList(false); // no EOF after list expectToList(false); // no EOF after list
try { try {
clientHelper.toList(rawMessage); clientHelper.toList(getRandomBytes(123));
fail(); fail();
} catch (FormatException e) { } catch (FormatException e) {
// expected // expected

View File

@@ -64,6 +64,7 @@ import static java.util.Collections.singletonList;
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE; import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED; import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE; import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_LENGTH;
import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED; import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED;
import static org.briarproject.bramble.api.sync.ValidationManager.State.UNKNOWN; import static org.briarproject.bramble.api.sync.ValidationManager.State.UNKNOWN;
import static org.briarproject.bramble.api.transport.TransportConstants.REORDERING_WINDOW_SIZE; import static org.briarproject.bramble.api.transport.TransportConstants.REORDERING_WINDOW_SIZE;
@@ -72,6 +73,7 @@ import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getClientId; import static org.briarproject.bramble.test.TestUtils.getClientId;
import static org.briarproject.bramble.test.TestUtils.getGroup; import static org.briarproject.bramble.test.TestUtils.getGroup;
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor; import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
import static org.briarproject.bramble.test.TestUtils.getMessage;
import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.test.TestUtils.getSecretKey; import static org.briarproject.bramble.test.TestUtils.getSecretKey;
import static org.briarproject.bramble.test.TestUtils.getTransportId; import static org.briarproject.bramble.test.TestUtils.getTransportId;
@@ -97,10 +99,8 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
private final Group group; private final Group group;
private final Author author; private final Author author;
private final LocalAuthor localAuthor; private final LocalAuthor localAuthor;
private final Message message, message1;
private final MessageId messageId, messageId1; private final MessageId messageId, messageId1;
private final int size;
private final byte[] raw;
private final Message message;
private final Metadata metadata; private final Metadata metadata;
private final TransportId transportId; private final TransportId transportId;
private final int maxLatency; private final int maxLatency;
@@ -115,12 +115,10 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
groupId = group.getId(); groupId = group.getId();
author = getAuthor(); author = getAuthor();
localAuthor = getLocalAuthor(); localAuthor = getLocalAuthor();
messageId = new MessageId(getRandomId()); message = getMessage(groupId);
messageId1 = new MessageId(getRandomId()); message1 = getMessage(groupId);
long timestamp = System.currentTimeMillis(); messageId = message.getId();
size = 1234; messageId1 = message1.getId();
raw = new byte[size];
message = new Message(messageId, groupId, timestamp, raw);
metadata = new Metadata(); metadata = new Metadata();
metadata.put("foo", new byte[] {'b', 'a', 'r'}); metadata.put("foo", new byte[] {'b', 'a', 'r'});
transportId = getTransportId(); transportId = getTransportId();
@@ -646,7 +644,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
transaction = db.startTransaction(false); transaction = db.startTransaction(false);
try { try {
db.getRawMessage(transaction, messageId); db.getMessage(transaction, messageId);
fail(); fail();
} catch (NoSuchMessageException expected) { } catch (NoSuchMessageException expected) {
// Expected // Expected
@@ -865,22 +863,22 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
@Test @Test
public void testGenerateBatch() throws Exception { public void testGenerateBatch() throws Exception {
byte[] raw1 = new byte[size];
Collection<MessageId> ids = Arrays.asList(messageId, messageId1); Collection<MessageId> ids = Arrays.asList(messageId, messageId1);
Collection<byte[]> messages = Arrays.asList(raw, raw1); Collection<Message> messages = Arrays.asList(message, message1);
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(database).startTransaction(); oneOf(database).startTransaction();
will(returnValue(txn)); will(returnValue(txn));
oneOf(database).containsContact(txn, contactId); oneOf(database).containsContact(txn, contactId);
will(returnValue(true)); will(returnValue(true));
oneOf(database).getMessagesToSend(txn, contactId, size * 2); oneOf(database).getMessagesToSend(txn, contactId,
MAX_MESSAGE_LENGTH * 2);
will(returnValue(ids)); will(returnValue(ids));
oneOf(database).getRawMessage(txn, messageId); oneOf(database).getMessage(txn, messageId);
will(returnValue(raw)); will(returnValue(message));
oneOf(database).updateExpiryTime(txn, contactId, messageId, oneOf(database).updateExpiryTime(txn, contactId, messageId,
maxLatency); maxLatency);
oneOf(database).getRawMessage(txn, messageId1); oneOf(database).getMessage(txn, messageId1);
will(returnValue(raw1)); will(returnValue(message1));
oneOf(database).updateExpiryTime(txn, contactId, messageId1, oneOf(database).updateExpiryTime(txn, contactId, messageId1,
maxLatency); maxLatency);
oneOf(database).lowerRequestedFlag(txn, contactId, ids); oneOf(database).lowerRequestedFlag(txn, contactId, ids);
@@ -893,7 +891,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
Transaction transaction = db.startTransaction(false); Transaction transaction = db.startTransaction(false);
try { try {
assertEquals(messages, db.generateBatch(transaction, contactId, assertEquals(messages, db.generateBatch(transaction, contactId,
size * 2, maxLatency)); MAX_MESSAGE_LENGTH * 2, maxLatency));
db.commitTransaction(transaction); db.commitTransaction(transaction);
} finally { } finally {
db.endTransaction(transaction); db.endTransaction(transaction);
@@ -961,23 +959,22 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
@Test @Test
public void testGenerateRequestedBatch() throws Exception { public void testGenerateRequestedBatch() throws Exception {
byte[] raw1 = new byte[size];
Collection<MessageId> ids = Arrays.asList(messageId, messageId1); Collection<MessageId> ids = Arrays.asList(messageId, messageId1);
Collection<byte[]> messages = Arrays.asList(raw, raw1); Collection<Message> messages = Arrays.asList(message, message1);
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(database).startTransaction(); oneOf(database).startTransaction();
will(returnValue(txn)); will(returnValue(txn));
oneOf(database).containsContact(txn, contactId); oneOf(database).containsContact(txn, contactId);
will(returnValue(true)); will(returnValue(true));
oneOf(database).getRequestedMessagesToSend(txn, contactId, oneOf(database).getRequestedMessagesToSend(txn, contactId,
size * 2); MAX_MESSAGE_LENGTH * 2);
will(returnValue(ids)); will(returnValue(ids));
oneOf(database).getRawMessage(txn, messageId); oneOf(database).getMessage(txn, messageId);
will(returnValue(raw)); will(returnValue(message));
oneOf(database).updateExpiryTime(txn, contactId, messageId, oneOf(database).updateExpiryTime(txn, contactId, messageId,
maxLatency); maxLatency);
oneOf(database).getRawMessage(txn, messageId1); oneOf(database).getMessage(txn, messageId1);
will(returnValue(raw1)); will(returnValue(message1));
oneOf(database).updateExpiryTime(txn, contactId, messageId1, oneOf(database).updateExpiryTime(txn, contactId, messageId1,
maxLatency); maxLatency);
oneOf(database).lowerRequestedFlag(txn, contactId, ids); oneOf(database).lowerRequestedFlag(txn, contactId, ids);
@@ -990,7 +987,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
Transaction transaction = db.startTransaction(false); Transaction transaction = db.startTransaction(false);
try { try {
assertEquals(messages, db.generateRequestedBatch(transaction, assertEquals(messages, db.generateRequestedBatch(transaction,
contactId, size * 2, maxLatency)); contactId, MAX_MESSAGE_LENGTH * 2, maxLatency));
db.commitTransaction(transaction); db.commitTransaction(transaction);
} finally { } finally {
db.endTransaction(transaction); db.endTransaction(transaction);

View File

@@ -1,5 +1,6 @@
package org.briarproject.bramble.db; package org.briarproject.bramble.db;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.DatabaseConfig; import org.briarproject.bramble.api.db.DatabaseConfig;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
@@ -26,6 +27,7 @@ public abstract class DatabasePerformanceComparisonTest
* How many blocks of each condition to compare. * How many blocks of each condition to compare.
*/ */
private static final int COMPARISON_BLOCKS = 10; private static final int COMPARISON_BLOCKS = 10;
private SecretKey databaseKey = getSecretKey();
abstract Database<Connection> createDatabase(boolean conditionA, abstract Database<Connection> createDatabase(boolean conditionA,
DatabaseConfig databaseConfig, Clock clock); DatabaseConfig databaseConfig, Clock clock);
@@ -72,7 +74,7 @@ public abstract class DatabasePerformanceComparisonTest
throws DbException { throws DbException {
Database<Connection> db = createDatabase(conditionA, Database<Connection> db = createDatabase(conditionA,
new TestDatabaseConfig(testDir, MAX_SIZE), new SystemClock()); new TestDatabaseConfig(testDir, MAX_SIZE), new SystemClock());
db.open(getSecretKey(), null); db.open(databaseKey, null);
return db; return db;
} }

View File

@@ -506,11 +506,11 @@ public abstract class DatabasePerformanceTest extends BrambleTestCase {
} }
@Test @Test
public void testGetRawMessage() throws Exception { public void testGetMessage() throws Exception {
String name = "getRawMessage(T, MessageId)"; String name = "getMessage(T, MessageId)";
benchmark(name, db -> { benchmark(name, db -> {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
db.getRawMessage(txn, pickRandom(messages).getId()); db.getMessage(txn, pickRandom(messages).getId());
db.commitTransaction(txn); db.commitTransaction(txn);
}); });
} }

View File

@@ -1,5 +1,6 @@
package org.briarproject.bramble.db; package org.briarproject.bramble.db;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.DatabaseConfig; import org.briarproject.bramble.api.db.DatabaseConfig;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
@@ -20,6 +21,8 @@ import static org.briarproject.bramble.test.TestUtils.getSecretKey;
public abstract class DatabaseTraceTest extends DatabasePerformanceTest { public abstract class DatabaseTraceTest extends DatabasePerformanceTest {
private SecretKey databaseKey = getSecretKey();
abstract Database<Connection> createDatabase(DatabaseConfig databaseConfig, abstract Database<Connection> createDatabase(DatabaseConfig databaseConfig,
Clock clock); Clock clock);
@@ -44,7 +47,7 @@ public abstract class DatabaseTraceTest extends DatabasePerformanceTest {
private Database<Connection> openDatabase() throws DbException { private Database<Connection> openDatabase() throws DbException {
Database<Connection> db = createDatabase( Database<Connection> db = createDatabase(
new TestDatabaseConfig(testDir, MAX_SIZE), new SystemClock()); new TestDatabaseConfig(testDir, MAX_SIZE), new SystemClock());
db.open(getSecretKey(), null); db.open(databaseKey, null);
return db; return db;
} }

View File

@@ -5,6 +5,7 @@ import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.DatabaseConfig; import org.briarproject.bramble.api.db.DatabaseConfig;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.MessageDeletedException;
import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.identity.LocalAuthor;
@@ -52,7 +53,7 @@ import static org.briarproject.bramble.api.db.Metadata.REMOVE;
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE; import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED; import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE; import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_LENGTH; import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED; import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED;
import static org.briarproject.bramble.api.sync.ValidationManager.State.INVALID; import static org.briarproject.bramble.api.sync.ValidationManager.State.INVALID;
import static org.briarproject.bramble.api.sync.ValidationManager.State.PENDING; import static org.briarproject.bramble.api.sync.ValidationManager.State.PENDING;
@@ -61,7 +62,7 @@ import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getClientId; import static org.briarproject.bramble.test.TestUtils.getClientId;
import static org.briarproject.bramble.test.TestUtils.getGroup; import static org.briarproject.bramble.test.TestUtils.getGroup;
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor; import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getMessage;
import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.test.TestUtils.getSecretKey; import static org.briarproject.bramble.test.TestUtils.getSecretKey;
import static org.briarproject.bramble.test.TestUtils.getTestDirectory; import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
@@ -88,11 +89,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
private final Group group; private final Group group;
private final Author author; private final Author author;
private final LocalAuthor localAuthor; private final LocalAuthor localAuthor;
private final MessageId messageId;
private final long timestamp;
private final int size;
private final byte[] raw;
private final Message message; private final Message message;
private final MessageId messageId;
private final TransportId transportId; private final TransportId transportId;
private final ContactId contactId; private final ContactId contactId;
private final KeySetId keySetId, keySetId1; private final KeySetId keySetId, keySetId1;
@@ -105,11 +103,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
groupId = group.getId(); groupId = group.getId();
author = getAuthor(); author = getAuthor();
localAuthor = getLocalAuthor(); localAuthor = getLocalAuthor();
messageId = new MessageId(getRandomId()); message = getMessage(groupId);
timestamp = System.currentTimeMillis(); messageId = message.getId();
size = 1234;
raw = getRandomBytes(size);
message = new Message(messageId, groupId, timestamp, raw);
transportId = getTransportId(); transportId = getTransportId();
contactId = new ContactId(1); contactId = new ContactId(1);
keySetId = new KeySetId(1); keySetId = new KeySetId(1);
@@ -149,8 +144,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
assertTrue(db.containsContact(txn, contactId)); assertTrue(db.containsContact(txn, contactId));
assertTrue(db.containsGroup(txn, groupId)); assertTrue(db.containsGroup(txn, groupId));
assertTrue(db.containsMessage(txn, messageId)); assertTrue(db.containsMessage(txn, messageId));
byte[] raw1 = db.getRawMessage(txn, messageId); assertArrayEquals(message.getRaw(),
assertArrayEquals(raw, raw1); db.getMessage(txn, messageId).getRaw());
// Delete the records // Delete the records
db.removeMessage(txn, messageId); db.removeMessage(txn, messageId);
@@ -360,11 +355,11 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// The message is sendable, but too large to send // The message is sendable, but too large to send
Collection<MessageId> ids = db.getMessagesToSend(txn, contactId, Collection<MessageId> ids = db.getMessagesToSend(txn, contactId,
size - 1); message.getRawLength() - 1);
assertTrue(ids.isEmpty()); assertTrue(ids.isEmpty());
// The message is just the right size to send // The message is just the right size to send
ids = db.getMessagesToSend(txn, contactId, size); ids = db.getMessagesToSend(txn, contactId, message.getRawLength());
assertEquals(singletonList(messageId), ids); assertEquals(singletonList(messageId), ids);
db.commitTransaction(txn); db.commitTransaction(txn);
@@ -384,8 +379,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
db.addGroupVisibility(txn, contactId, groupId, false); db.addGroupVisibility(txn, contactId, groupId, false);
// Add some messages to ack // Add some messages to ack
MessageId messageId1 = new MessageId(getRandomId()); Message message1 = getMessage(groupId);
Message message1 = new Message(messageId1, groupId, timestamp, raw); MessageId messageId1 = message1.getId();
db.addMessage(txn, message, DELIVERED, true, contactId); db.addMessage(txn, message, DELIVERED, true, contactId);
db.addMessage(txn, message1, DELIVERED, true, contactId); db.addMessage(txn, message1, DELIVERED, true, contactId);
@@ -448,9 +443,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
@Test @Test
public void testGetFreeSpace() throws Exception { public void testGetFreeSpace() throws Exception {
byte[] largeBody = new byte[MAX_MESSAGE_LENGTH]; Message message = getMessage(groupId, MAX_MESSAGE_BODY_LENGTH);
for (int i = 0; i < largeBody.length; i++) largeBody[i] = (byte) i;
Message message = new Message(messageId, groupId, timestamp, largeBody);
Database<Connection> db = open(false); Database<Connection> db = open(false);
// Sanity check: there should be enough space on disk for this test // Sanity check: there should be enough space on disk for this test
@@ -1104,8 +1097,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
@Test @Test
public void testMetadataQueries() throws Exception { public void testMetadataQueries() throws Exception {
MessageId messageId1 = new MessageId(getRandomId()); Message message1 = getMessage(groupId);
Message message1 = new Message(messageId1, groupId, timestamp, raw); MessageId messageId1 = message1.getId();
Database<Connection> db = open(false); Database<Connection> db = open(false);
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
@@ -1208,8 +1201,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
@Test @Test
public void testMetadataQueriesOnlyForDeliveredMessages() throws Exception { public void testMetadataQueriesOnlyForDeliveredMessages() throws Exception {
MessageId messageId1 = new MessageId(getRandomId()); Message message1 = getMessage(groupId);
Message message1 = new Message(messageId1, groupId, timestamp, raw); MessageId messageId1 = message1.getId();
Database<Connection> db = open(false); Database<Connection> db = open(false);
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
@@ -1279,14 +1272,14 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
@Test @Test
public void testMessageDependencies() throws Exception { public void testMessageDependencies() throws Exception {
MessageId messageId1 = new MessageId(getRandomId()); Message message1 = getMessage(groupId);
MessageId messageId2 = new MessageId(getRandomId()); Message message2 = getMessage(groupId);
MessageId messageId3 = new MessageId(getRandomId()); Message message3 = getMessage(groupId);
MessageId messageId4 = new MessageId(getRandomId()); Message message4 = getMessage(groupId);
Message message1 = new Message(messageId1, groupId, timestamp, raw); MessageId messageId1 = message1.getId();
Message message2 = new Message(messageId2, groupId, timestamp, raw); MessageId messageId2 = message2.getId();
Message message3 = new Message(messageId3, groupId, timestamp, raw); MessageId messageId3 = message3.getId();
Message message4 = new Message(messageId4, groupId, timestamp, raw); MessageId messageId4 = message4.getId();
Database<Connection> db = open(false); Database<Connection> db = open(false);
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
@@ -1384,16 +1377,16 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
db.addGroup(txn, group1); db.addGroup(txn, group1);
// Add a message to the second group // Add a message to the second group
MessageId messageId1 = new MessageId(getRandomId()); Message message1 = getMessage(groupId1);
Message message1 = new Message(messageId1, groupId1, timestamp, raw); MessageId messageId1 = message1.getId();
db.addMessage(txn, message1, DELIVERED, true, contactId); db.addMessage(txn, message1, DELIVERED, true, contactId);
// Create an ID for a missing message // Create an ID for a missing message
MessageId messageId2 = new MessageId(getRandomId()); MessageId messageId2 = new MessageId(getRandomId());
// Add another message to the first group // Add another message to the first group
MessageId messageId3 = new MessageId(getRandomId()); Message message3 = getMessage(groupId);
Message message3 = new Message(messageId3, groupId, timestamp, raw); MessageId messageId3 = message3.getId();
db.addMessage(txn, message3, DELIVERED, true, contactId); db.addMessage(txn, message3, DELIVERED, true, contactId);
// Add dependencies between the messages // Add dependencies between the messages
@@ -1427,36 +1420,32 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
@Test @Test
public void testGetPendingMessagesForDelivery() throws Exception { public void testGetPendingMessagesForDelivery() throws Exception {
MessageId mId1 = new MessageId(getRandomId()); Message message1 = getMessage(groupId);
MessageId mId2 = new MessageId(getRandomId()); Message message2 = getMessage(groupId);
MessageId mId3 = new MessageId(getRandomId()); Message message3 = getMessage(groupId);
MessageId mId4 = new MessageId(getRandomId()); Message message4 = getMessage(groupId);
Message m1 = new Message(mId1, groupId, timestamp, raw);
Message m2 = new Message(mId2, groupId, timestamp, raw);
Message m3 = new Message(mId3, groupId, timestamp, raw);
Message m4 = new Message(mId4, groupId, timestamp, raw);
Database<Connection> db = open(false); Database<Connection> db = open(false);
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add a group and some messages with different states // Add a group and some messages with different states
db.addGroup(txn, group); db.addGroup(txn, group);
db.addMessage(txn, m1, UNKNOWN, true, contactId); db.addMessage(txn, message1, UNKNOWN, true, contactId);
db.addMessage(txn, m2, INVALID, true, contactId); db.addMessage(txn, message2, INVALID, true, contactId);
db.addMessage(txn, m3, PENDING, true, contactId); db.addMessage(txn, message3, PENDING, true, contactId);
db.addMessage(txn, m4, DELIVERED, true, contactId); db.addMessage(txn, message4, DELIVERED, true, contactId);
Collection<MessageId> result; Collection<MessageId> result;
// Retrieve messages to be validated // Retrieve messages to be validated
result = db.getMessagesToValidate(txn); result = db.getMessagesToValidate(txn);
assertEquals(1, result.size()); assertEquals(1, result.size());
assertTrue(result.contains(mId1)); assertTrue(result.contains(message1.getId()));
// Retrieve pending messages // Retrieve pending messages
result = db.getPendingMessages(txn); result = db.getPendingMessages(txn);
assertEquals(1, result.size()); assertEquals(1, result.size());
assertTrue(result.contains(mId3)); assertTrue(result.contains(message3.getId()));
db.commitTransaction(txn); db.commitTransaction(txn);
db.close(); db.close();
@@ -1464,35 +1453,31 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
@Test @Test
public void testGetMessagesToShare() throws Exception { public void testGetMessagesToShare() throws Exception {
MessageId mId1 = new MessageId(getRandomId()); Message message1 = getMessage(groupId);
MessageId mId2 = new MessageId(getRandomId()); Message message2 = getMessage(groupId);
MessageId mId3 = new MessageId(getRandomId()); Message message3 = getMessage(groupId);
MessageId mId4 = new MessageId(getRandomId()); Message message4 = getMessage(groupId);
Message m1 = new Message(mId1, groupId, timestamp, raw);
Message m2 = new Message(mId2, groupId, timestamp, raw);
Message m3 = new Message(mId3, groupId, timestamp, raw);
Message m4 = new Message(mId4, groupId, timestamp, raw);
Database<Connection> db = open(false); Database<Connection> db = open(false);
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add a group and some messages // Add a group and some messages
db.addGroup(txn, group); db.addGroup(txn, group);
db.addMessage(txn, m1, DELIVERED, true, contactId); db.addMessage(txn, message1, DELIVERED, true, contactId);
db.addMessage(txn, m2, DELIVERED, false, contactId); db.addMessage(txn, message2, DELIVERED, false, contactId);
db.addMessage(txn, m3, DELIVERED, false, contactId); db.addMessage(txn, message3, DELIVERED, false, contactId);
db.addMessage(txn, m4, DELIVERED, true, contactId); db.addMessage(txn, message4, DELIVERED, true, contactId);
// Introduce dependencies between the messages // Introduce dependencies between the messages
db.addMessageDependency(txn, m1, mId2, DELIVERED); db.addMessageDependency(txn, message1, message2.getId(), DELIVERED);
db.addMessageDependency(txn, m3, mId1, DELIVERED); db.addMessageDependency(txn, message3, message1.getId(), DELIVERED);
db.addMessageDependency(txn, m4, mId3, DELIVERED); db.addMessageDependency(txn, message4, message3.getId(), DELIVERED);
// Retrieve messages to be shared // Retrieve messages to be shared
Collection<MessageId> result = db.getMessagesToShare(txn); Collection<MessageId> result = db.getMessagesToShare(txn);
assertEquals(2, result.size()); assertEquals(2, result.size());
assertTrue(result.contains(mId2)); assertTrue(result.contains(message2.getId()));
assertTrue(result.contains(mId3)); assertTrue(result.contains(message3.getId()));
db.commitTransaction(txn); db.commitTransaction(txn);
db.close(); db.close();
@@ -1654,8 +1639,12 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
ids = db.getMessagesToOffer(txn, contactId, 100); ids = db.getMessagesToOffer(txn, contactId, 100);
assertEquals(singletonList(messageId), ids); assertEquals(singletonList(messageId), ids);
// The raw message should not be null // The message should be available
assertNotNull(db.getRawMessage(txn, messageId)); Message m = db.getMessage(txn, messageId);
assertEquals(messageId, m.getId());
assertEquals(groupId, m.getGroupId());
assertEquals(message.getTimestamp(), m.getTimestamp());
assertArrayEquals(message.getRaw(), m.getRaw());
// Delete the message // Delete the message
db.deleteMessage(txn, messageId); db.deleteMessage(txn, messageId);
@@ -1669,8 +1658,13 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
ids = db.getMessagesToOffer(txn, contactId, 100); ids = db.getMessagesToOffer(txn, contactId, 100);
assertTrue(ids.isEmpty()); assertTrue(ids.isEmpty());
// The raw message should be null // Requesting the message should throw an exception
assertNull(db.getRawMessage(txn, messageId)); try {
db.getMessage(txn, messageId);
fail();
} catch (MessageDeletedException expected) {
// Expected
}
db.commitTransaction(txn); db.commitTransaction(txn);
db.close(); db.close();
@@ -1802,7 +1796,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
try { try {
// Ask for a nonexistent message - an exception should be thrown // Ask for a nonexistent message - an exception should be thrown
db.getRawMessage(txn, messageId); db.getMessage(txn, messageId);
fail(); fail();
} catch (DbException expected) { } catch (DbException expected) {
// It should be possible to abort the transaction without error // It should be possible to abort the transaction without error

View File

@@ -1,5 +1,6 @@
package org.briarproject.bramble.db; package org.briarproject.bramble.db;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.DatabaseConfig; import org.briarproject.bramble.api.db.DatabaseConfig;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
@@ -22,6 +23,8 @@ public abstract class SingleDatabasePerformanceTest
abstract Database<Connection> createDatabase(DatabaseConfig databaseConfig, abstract Database<Connection> createDatabase(DatabaseConfig databaseConfig,
Clock clock); Clock clock);
private SecretKey databaseKey = getSecretKey();
@Override @Override
protected void benchmark(String name, protected void benchmark(String name,
BenchmarkTask<Database<Connection>> task) throws Exception { BenchmarkTask<Database<Connection>> task) throws Exception {
@@ -41,7 +44,7 @@ public abstract class SingleDatabasePerformanceTest
private Database<Connection> openDatabase() throws DbException { private Database<Connection> openDatabase() throws DbException {
Database<Connection> db = createDatabase( Database<Connection> db = createDatabase(
new TestDatabaseConfig(testDir, MAX_SIZE), new SystemClock()); new TestDatabaseConfig(testDir, MAX_SIZE), new SystemClock());
db.open(getSecretKey(), null); db.open(databaseKey, null);
return db; return db;
} }

View File

@@ -34,11 +34,10 @@ import static java.util.Collections.singletonList;
import static org.briarproject.bramble.api.properties.TransportPropertyManager.CLIENT_ID; import static org.briarproject.bramble.api.properties.TransportPropertyManager.CLIENT_ID;
import static org.briarproject.bramble.api.properties.TransportPropertyManager.MAJOR_VERSION; import static org.briarproject.bramble.api.properties.TransportPropertyManager.MAJOR_VERSION;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED; import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
import static org.briarproject.bramble.test.TestUtils.getAuthor; import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getGroup; import static org.briarproject.bramble.test.TestUtils.getGroup;
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor; import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getMessage;
import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
@@ -187,8 +186,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
throws Exception { throws Exception {
Transaction txn = new Transaction(null, false); Transaction txn = new Transaction(null, false);
GroupId contactGroupId = new GroupId(getRandomId()); GroupId contactGroupId = new GroupId(getRandomId());
long timestamp = 123456789; Message message = getMessage(contactGroupId);
Message message = getMessage(contactGroupId, timestamp);
Metadata meta = new Metadata(); Metadata meta = new Metadata();
BdfDictionary metaDictionary = BdfDictionary.of( BdfDictionary metaDictionary = BdfDictionary.of(
new BdfEntry("transportId", "foo"), new BdfEntry("transportId", "foo"),
@@ -229,8 +227,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
throws Exception { throws Exception {
Transaction txn = new Transaction(null, false); Transaction txn = new Transaction(null, false);
GroupId contactGroupId = new GroupId(getRandomId()); GroupId contactGroupId = new GroupId(getRandomId());
long timestamp = 123456789; Message message = getMessage(contactGroupId);
Message message = getMessage(contactGroupId, timestamp);
Metadata meta = new Metadata(); Metadata meta = new Metadata();
// Version 4 is being delivered // Version 4 is being delivered
BdfDictionary metaDictionary = BdfDictionary.of( BdfDictionary metaDictionary = BdfDictionary.of(
@@ -267,8 +264,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
public void testDeletesObsoleteUpdateWhenDelivered() throws Exception { public void testDeletesObsoleteUpdateWhenDelivered() throws Exception {
Transaction txn = new Transaction(null, false); Transaction txn = new Transaction(null, false);
GroupId contactGroupId = new GroupId(getRandomId()); GroupId contactGroupId = new GroupId(getRandomId());
long timestamp = 123456789; Message message = getMessage(contactGroupId);
Message message = getMessage(contactGroupId, timestamp);
Metadata meta = new Metadata(); Metadata meta = new Metadata();
// Version 3 is being delivered // Version 3 is being delivered
BdfDictionary metaDictionary = BdfDictionary.of( BdfDictionary metaDictionary = BdfDictionary.of(
@@ -619,12 +615,6 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
true, active); true, active);
} }
private Message getMessage(GroupId g, long timestamp) {
MessageId messageId = new MessageId(getRandomId());
byte[] raw = getRandomBytes(MAX_MESSAGE_BODY_LENGTH);
return new Message(messageId, g, timestamp, raw);
}
private void expectGetLocalProperties(Transaction txn) throws Exception { private void expectGetLocalProperties(Transaction txn) throws Exception {
Map<MessageId, BdfDictionary> messageMetadata = new LinkedHashMap<>(); Map<MessageId, BdfDictionary> messageMetadata = new LinkedHashMap<>();
// The latest update for transport "foo" should be returned // The latest update for transport "foo" should be returned
@@ -664,9 +654,9 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
private void expectStoreMessage(Transaction txn, GroupId g, private void expectStoreMessage(Transaction txn, GroupId g,
String transportId, BdfDictionary properties, long version, String transportId, BdfDictionary properties, long version,
boolean local, boolean shared) throws Exception { boolean local, boolean shared) throws Exception {
long timestamp = 123456789;
BdfList body = BdfList.of(transportId, version, properties); BdfList body = BdfList.of(transportId, version, properties);
Message message = getMessage(g, timestamp); Message message = getMessage(g);
long timestamp = message.getTimestamp();
BdfDictionary meta = BdfDictionary.of( BdfDictionary meta = BdfDictionary.of(
new BdfEntry("transportId", transportId), new BdfEntry("transportId", transportId),
new BdfEntry("version", version), new BdfEntry("version", version),

View File

@@ -5,6 +5,8 @@ import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.sync.Ack; import org.briarproject.bramble.api.sync.Ack;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.sync.SyncRecordWriter; import org.briarproject.bramble.api.sync.SyncRecordWriter;
import org.briarproject.bramble.api.transport.StreamWriter; import org.briarproject.bramble.api.transport.StreamWriter;
@@ -13,11 +15,11 @@ import org.briarproject.bramble.test.ImmediateExecutor;
import org.jmock.Expectations; import org.jmock.Expectations;
import org.junit.Test; import org.junit.Test;
import java.util.Arrays;
import java.util.Collections;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import static java.util.Collections.singletonList;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS; import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS;
import static org.briarproject.bramble.test.TestUtils.getMessage;
import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getRandomId;
public class SimplexOutgoingSessionTest extends BrambleMockTestCase { public class SimplexOutgoingSessionTest extends BrambleMockTestCase {
@@ -32,7 +34,8 @@ public class SimplexOutgoingSessionTest extends BrambleMockTestCase {
private final Executor dbExecutor = new ImmediateExecutor(); private final Executor dbExecutor = new ImmediateExecutor();
private final ContactId contactId = new ContactId(234); private final ContactId contactId = new ContactId(234);
private final MessageId messageId = new MessageId(getRandomId()); private final Message message = getMessage(new GroupId(getRandomId()));
private final MessageId messageId = message.getId();
@Test @Test
public void testNothingToSend() throws Exception { public void testNothingToSend() throws Exception {
@@ -71,8 +74,7 @@ public class SimplexOutgoingSessionTest extends BrambleMockTestCase {
@Test @Test
public void testSomethingToSend() throws Exception { public void testSomethingToSend() throws Exception {
Ack ack = new Ack(Collections.singletonList(messageId)); Ack ack = new Ack(singletonList(messageId));
byte[] raw = new byte[1234];
SimplexOutgoingSession session = new SimplexOutgoingSession(db, SimplexOutgoingSession session = new SimplexOutgoingSession(db,
dbExecutor, eventBus, contactId, MAX_LATENCY, streamWriter, dbExecutor, eventBus, contactId, MAX_LATENCY, streamWriter,
recordWriter); recordWriter);
@@ -97,10 +99,10 @@ public class SimplexOutgoingSessionTest extends BrambleMockTestCase {
will(returnValue(msgTxn)); will(returnValue(msgTxn));
oneOf(db).generateBatch(with(msgTxn), with(contactId), oneOf(db).generateBatch(with(msgTxn), with(contactId),
with(any(int.class)), with(MAX_LATENCY)); with(any(int.class)), with(MAX_LATENCY));
will(returnValue(Arrays.asList(raw))); will(returnValue(singletonList(message)));
oneOf(db).commitTransaction(msgTxn); oneOf(db).commitTransaction(msgTxn);
oneOf(db).endTransaction(msgTxn); oneOf(db).endTransaction(msgTxn);
oneOf(recordWriter).writeMessage(raw); oneOf(recordWriter).writeMessage(message);
// No more acks // No more acks
oneOf(db).startTransaction(false); oneOf(db).startTransaction(false);
will(returnValue(noAckTxn)); will(returnValue(noAckTxn));

View File

@@ -108,8 +108,8 @@ public class SyncIntegrationTest extends BrambleTestCase {
streamWriter.getOutputStream()); streamWriter.getOutputStream());
recordWriter.writeAck(new Ack(messageIds)); recordWriter.writeAck(new Ack(messageIds));
recordWriter.writeMessage(message.getRaw()); recordWriter.writeMessage(message);
recordWriter.writeMessage(message1.getRaw()); recordWriter.writeMessage(message1);
recordWriter.writeOffer(new Offer(messageIds)); recordWriter.writeOffer(new Offer(messageIds));
recordWriter.writeRequest(new Request(messageIds)); recordWriter.writeRequest(new Request(messageIds));
@@ -169,7 +169,7 @@ public class SyncIntegrationTest extends BrambleTestCase {
assertArrayEquals(m1.getGroupId().getBytes(), assertArrayEquals(m1.getGroupId().getBytes(),
m2.getGroupId().getBytes()); m2.getGroupId().getBytes());
assertEquals(m1.getTimestamp(), m2.getTimestamp()); assertEquals(m1.getTimestamp(), m2.getTimestamp());
assertEquals(m1.getLength(), m2.getLength()); assertEquals(m1.getRawLength(), m2.getRawLength());
assertArrayEquals(m1.getRaw(), m2.getRaw()); assertArrayEquals(m1.getRaw(), m2.getRaw());
} }
} }

View File

@@ -1,6 +1,5 @@
package org.briarproject.bramble.sync; package org.briarproject.bramble.sync;
import org.briarproject.bramble.api.UniqueId;
import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.Metadata;
@@ -13,7 +12,6 @@ import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.InvalidMessageException; import org.briarproject.bramble.api.sync.InvalidMessageException;
import org.briarproject.bramble.api.sync.Message; import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageContext; import org.briarproject.bramble.api.sync.MessageContext;
import org.briarproject.bramble.api.sync.MessageFactory;
import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.sync.ValidationManager.IncomingMessageHook; import org.briarproject.bramble.api.sync.ValidationManager.IncomingMessageHook;
import org.briarproject.bramble.api.sync.ValidationManager.MessageValidator; import org.briarproject.bramble.api.sync.ValidationManager.MessageValidator;
@@ -21,30 +19,31 @@ import org.briarproject.bramble.api.sync.ValidationManager.State;
import org.briarproject.bramble.api.sync.event.MessageAddedEvent; import org.briarproject.bramble.api.sync.event.MessageAddedEvent;
import org.briarproject.bramble.test.BrambleMockTestCase; import org.briarproject.bramble.test.BrambleMockTestCase;
import org.briarproject.bramble.test.ImmediateExecutor; import org.briarproject.bramble.test.ImmediateExecutor;
import org.briarproject.bramble.util.ByteUtils;
import org.jmock.Expectations; import org.jmock.Expectations;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED; import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED;
import static org.briarproject.bramble.api.sync.ValidationManager.State.INVALID; import static org.briarproject.bramble.api.sync.ValidationManager.State.INVALID;
import static org.briarproject.bramble.api.sync.ValidationManager.State.PENDING; import static org.briarproject.bramble.api.sync.ValidationManager.State.PENDING;
import static org.briarproject.bramble.api.sync.ValidationManager.State.UNKNOWN; import static org.briarproject.bramble.api.sync.ValidationManager.State.UNKNOWN;
import static org.briarproject.bramble.test.TestUtils.getClientId; import static org.briarproject.bramble.test.TestUtils.getClientId;
import static org.briarproject.bramble.test.TestUtils.getGroup; import static org.briarproject.bramble.test.TestUtils.getGroup;
import static org.briarproject.bramble.test.TestUtils.getMessage;
import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getRandomId;
public class ValidationManagerImplTest extends BrambleMockTestCase { public class ValidationManagerImplTest extends BrambleMockTestCase {
private final DatabaseComponent db = context.mock(DatabaseComponent.class); private final DatabaseComponent db = context.mock(DatabaseComponent.class);
private final MessageFactory messageFactory =
context.mock(MessageFactory.class);
private final MessageValidator validator = private final MessageValidator validator =
context.mock(MessageValidator.class); context.mock(MessageValidator.class);
private final IncomingMessageHook hook = private final IncomingMessageHook hook =
@@ -54,38 +53,26 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
private final Executor validationExecutor = new ImmediateExecutor(); private final Executor validationExecutor = new ImmediateExecutor();
private final ClientId clientId = getClientId(); private final ClientId clientId = getClientId();
private final int majorVersion = 123; private final int majorVersion = 123;
private final MessageId messageId = new MessageId(getRandomId());
private final MessageId messageId1 = new MessageId(getRandomId());
private final MessageId messageId2 = new MessageId(getRandomId());
private final Group group = getGroup(clientId, majorVersion); private final Group group = getGroup(clientId, majorVersion);
private final GroupId groupId = group.getId(); private final GroupId groupId = group.getId();
private final long timestamp = System.currentTimeMillis(); private final Message message = getMessage(groupId);
private final byte[] raw = new byte[123]; private final Message message1 = getMessage(groupId);
private final Message message = new Message(messageId, groupId, timestamp, private final Message message2 = getMessage(groupId);
raw); private final MessageId messageId = message.getId();
private final Message message1 = new Message(messageId1, groupId, timestamp, private final MessageId messageId1 = message1.getId();
raw); private final MessageId messageId2 = message2.getId();
private final Message message2 = new Message(messageId2, groupId, timestamp,
raw);
private final Metadata metadata = new Metadata(); private final Metadata metadata = new Metadata();
private final MessageContext validResult = new MessageContext(metadata); private final MessageContext validResult = new MessageContext(metadata);
private final ContactId contactId = new ContactId(234); private final ContactId contactId = new ContactId(234);
private final MessageContext validResultWithDependencies = private final MessageContext validResultWithDependencies =
new MessageContext(metadata, Collections.singletonList(messageId1)); new MessageContext(metadata, singletonList(messageId1));
private ValidationManagerImpl vm; private ValidationManagerImpl vm;
public ValidationManagerImplTest() {
// Encode the messages
System.arraycopy(groupId.getBytes(), 0, raw, 0, UniqueId.LENGTH);
ByteUtils.writeUint64(timestamp, raw, UniqueId.LENGTH);
}
@Before @Before
public void setUp() { public void setUp() {
vm = new ValidationManagerImpl(db, dbExecutor, validationExecutor, vm = new ValidationManagerImpl(db, dbExecutor, validationExecutor);
messageFactory);
vm.registerMessageValidator(clientId, majorVersion, validator); vm.registerMessageValidator(clientId, majorVersion, validator);
vm.registerIncomingMessageHook(clientId, majorVersion, hook); vm.registerIncomingMessageHook(clientId, majorVersion, hook);
} }
@@ -101,21 +88,21 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn)); will(returnValue(txn));
oneOf(db).getMessagesToValidate(txn); oneOf(db).getMessagesToValidate(txn);
will(returnValue(Collections.emptyList())); will(returnValue(emptyList()));
oneOf(db).commitTransaction(txn); oneOf(db).commitTransaction(txn);
oneOf(db).endTransaction(txn); oneOf(db).endTransaction(txn);
// deliverOutstandingMessages() // deliverOutstandingMessages()
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn1)); will(returnValue(txn1));
oneOf(db).getPendingMessages(txn1); oneOf(db).getPendingMessages(txn1);
will(returnValue(Collections.emptyList())); will(returnValue(emptyList()));
oneOf(db).commitTransaction(txn1); oneOf(db).commitTransaction(txn1);
oneOf(db).endTransaction(txn1); oneOf(db).endTransaction(txn1);
// shareOutstandingMessages() // shareOutstandingMessages()
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn2)); will(returnValue(txn2));
oneOf(db).getMessagesToShare(txn2); oneOf(db).getMessagesToShare(txn2);
will(returnValue(Collections.emptyList())); will(returnValue(emptyList()));
oneOf(db).commitTransaction(txn2); oneOf(db).commitTransaction(txn2);
oneOf(db).endTransaction(txn2); oneOf(db).endTransaction(txn2);
}}); }});
@@ -145,9 +132,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
// Load the first raw message and group // Load the first raw message and group
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn1)); will(returnValue(txn1));
oneOf(db).getRawMessage(txn1, messageId); oneOf(db).getMessage(txn1, messageId);
will(returnValue(raw));
oneOf(messageFactory).createMessage(messageId, raw);
will(returnValue(message)); will(returnValue(message));
oneOf(db).getGroup(txn1, groupId); oneOf(db).getGroup(txn1, groupId);
will(returnValue(group)); will(returnValue(group));
@@ -166,15 +151,13 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).setMessageState(txn2, messageId, DELIVERED); oneOf(db).setMessageState(txn2, messageId, DELIVERED);
// Get any pending dependents // Get any pending dependents
oneOf(db).getMessageDependents(txn2, messageId); oneOf(db).getMessageDependents(txn2, messageId);
will(returnValue(Collections.emptyMap())); will(returnValue(emptyMap()));
oneOf(db).commitTransaction(txn2); oneOf(db).commitTransaction(txn2);
oneOf(db).endTransaction(txn2); oneOf(db).endTransaction(txn2);
// Load the second raw message and group // Load the second raw message and group
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn3)); will(returnValue(txn3));
oneOf(db).getRawMessage(txn3, messageId1); oneOf(db).getMessage(txn3, messageId1);
will(returnValue(raw));
oneOf(messageFactory).createMessage(messageId1, raw);
will(returnValue(message1)); will(returnValue(message1));
oneOf(db).getGroup(txn3, groupId); oneOf(db).getGroup(txn3, groupId);
will(returnValue(group)); will(returnValue(group));
@@ -193,21 +176,21 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).deleteMessageMetadata(txn4, messageId1); oneOf(db).deleteMessageMetadata(txn4, messageId1);
// Recursively invalidate any dependents // Recursively invalidate any dependents
oneOf(db).getMessageDependents(txn4, messageId1); oneOf(db).getMessageDependents(txn4, messageId1);
will(returnValue(Collections.emptyMap())); will(returnValue(emptyMap()));
oneOf(db).commitTransaction(txn4); oneOf(db).commitTransaction(txn4);
oneOf(db).endTransaction(txn4); oneOf(db).endTransaction(txn4);
// Get pending messages to deliver // Get pending messages to deliver
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn5)); will(returnValue(txn5));
oneOf(db).getPendingMessages(txn5); oneOf(db).getPendingMessages(txn5);
will(returnValue(Collections.emptyList())); will(returnValue(emptyList()));
oneOf(db).commitTransaction(txn5); oneOf(db).commitTransaction(txn5);
oneOf(db).endTransaction(txn5); oneOf(db).endTransaction(txn5);
// Get messages to share // Get messages to share
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn6)); will(returnValue(txn6));
oneOf(db).getMessagesToShare(txn6); oneOf(db).getMessagesToShare(txn6);
will(returnValue(Collections.emptyList())); will(returnValue(emptyList()));
oneOf(db).commitTransaction(txn6); oneOf(db).commitTransaction(txn6);
oneOf(db).endTransaction(txn6); oneOf(db).endTransaction(txn6);
}}); }});
@@ -228,14 +211,14 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn)); will(returnValue(txn));
oneOf(db).getMessagesToValidate(txn); oneOf(db).getMessagesToValidate(txn);
will(returnValue(Collections.emptyList())); will(returnValue(emptyList()));
oneOf(db).commitTransaction(txn); oneOf(db).commitTransaction(txn);
oneOf(db).endTransaction(txn); oneOf(db).endTransaction(txn);
// Get pending messages to deliver // Get pending messages to deliver
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn1)); will(returnValue(txn1));
oneOf(db).getPendingMessages(txn1); oneOf(db).getPendingMessages(txn1);
will(returnValue(Collections.singletonList(messageId))); will(returnValue(singletonList(messageId)));
oneOf(db).commitTransaction(txn1); oneOf(db).commitTransaction(txn1);
oneOf(db).endTransaction(txn1); oneOf(db).endTransaction(txn1);
// Check whether the message is ready to deliver // Check whether the message is ready to deliver
@@ -244,11 +227,9 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).getMessageState(txn2, messageId); oneOf(db).getMessageState(txn2, messageId);
will(returnValue(PENDING)); will(returnValue(PENDING));
oneOf(db).getMessageDependencies(txn2, messageId); oneOf(db).getMessageDependencies(txn2, messageId);
will(returnValue(Collections.singletonMap(messageId1, DELIVERED))); will(returnValue(singletonMap(messageId1, DELIVERED)));
// Get the message and its metadata to deliver // Get the message and its metadata to deliver
oneOf(db).getRawMessage(txn2, messageId); oneOf(db).getMessage(txn2, messageId);
will(returnValue(raw));
oneOf(messageFactory).createMessage(messageId, raw);
will(returnValue(message)); will(returnValue(message));
oneOf(db).getGroup(txn2, groupId); oneOf(db).getGroup(txn2, groupId);
will(returnValue(group)); will(returnValue(group));
@@ -260,7 +241,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).setMessageState(txn2, messageId, DELIVERED); oneOf(db).setMessageState(txn2, messageId, DELIVERED);
// Get any pending dependents // Get any pending dependents
oneOf(db).getMessageDependents(txn2, messageId); oneOf(db).getMessageDependents(txn2, messageId);
will(returnValue(Collections.singletonMap(messageId2, PENDING))); will(returnValue(singletonMap(messageId2, PENDING)));
oneOf(db).commitTransaction(txn2); oneOf(db).commitTransaction(txn2);
oneOf(db).endTransaction(txn2); oneOf(db).endTransaction(txn2);
// Check whether the dependent is ready to deliver // Check whether the dependent is ready to deliver
@@ -269,11 +250,9 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).getMessageState(txn3, messageId2); oneOf(db).getMessageState(txn3, messageId2);
will(returnValue(PENDING)); will(returnValue(PENDING));
oneOf(db).getMessageDependencies(txn3, messageId2); oneOf(db).getMessageDependencies(txn3, messageId2);
will(returnValue(Collections.singletonMap(messageId1, DELIVERED))); will(returnValue(singletonMap(messageId1, DELIVERED)));
// Get the dependent and its metadata to deliver // Get the dependent and its metadata to deliver
oneOf(db).getRawMessage(txn3, messageId2); oneOf(db).getMessage(txn3, messageId2);
will(returnValue(raw));
oneOf(messageFactory).createMessage(messageId2, raw);
will(returnValue(message2)); will(returnValue(message2));
oneOf(db).getGroup(txn3, groupId); oneOf(db).getGroup(txn3, groupId);
will(returnValue(group)); will(returnValue(group));
@@ -285,7 +264,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).setMessageState(txn3, messageId2, DELIVERED); oneOf(db).setMessageState(txn3, messageId2, DELIVERED);
// Get any pending dependents // Get any pending dependents
oneOf(db).getMessageDependents(txn3, messageId2); oneOf(db).getMessageDependents(txn3, messageId2);
will(returnValue(Collections.emptyMap())); will(returnValue(emptyMap()));
oneOf(db).commitTransaction(txn3); oneOf(db).commitTransaction(txn3);
oneOf(db).endTransaction(txn3); oneOf(db).endTransaction(txn3);
@@ -293,7 +272,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn4)); will(returnValue(txn4));
oneOf(db).getMessagesToShare(txn4); oneOf(db).getMessagesToShare(txn4);
will(returnValue(Collections.emptyList())); will(returnValue(emptyList()));
oneOf(db).commitTransaction(txn4); oneOf(db).commitTransaction(txn4);
oneOf(db).endTransaction(txn4); oneOf(db).endTransaction(txn4);
}}); }});
@@ -314,14 +293,14 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn)); will(returnValue(txn));
oneOf(db).getMessagesToValidate(txn); oneOf(db).getMessagesToValidate(txn);
will(returnValue(Collections.emptyList())); will(returnValue(emptyList()));
oneOf(db).commitTransaction(txn); oneOf(db).commitTransaction(txn);
oneOf(db).endTransaction(txn); oneOf(db).endTransaction(txn);
// No pending messages to deliver // No pending messages to deliver
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn1)); will(returnValue(txn1));
oneOf(db).getPendingMessages(txn1); oneOf(db).getPendingMessages(txn1);
will(returnValue(Collections.emptyList())); will(returnValue(emptyList()));
oneOf(db).commitTransaction(txn1); oneOf(db).commitTransaction(txn1);
oneOf(db).endTransaction(txn1); oneOf(db).endTransaction(txn1);
@@ -329,7 +308,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn2)); will(returnValue(txn2));
oneOf(db).getMessagesToShare(txn2); oneOf(db).getMessagesToShare(txn2);
will(returnValue(Collections.singletonList(messageId))); will(returnValue(singletonList(messageId)));
oneOf(db).commitTransaction(txn2); oneOf(db).commitTransaction(txn2);
oneOf(db).endTransaction(txn2); oneOf(db).endTransaction(txn2);
// Share message and get dependencies // Share message and get dependencies
@@ -337,7 +316,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
will(returnValue(txn3)); will(returnValue(txn3));
oneOf(db).setMessageShared(txn3, messageId); oneOf(db).setMessageShared(txn3, messageId);
oneOf(db).getMessageDependencies(txn3, messageId); oneOf(db).getMessageDependencies(txn3, messageId);
will(returnValue(Collections.singletonMap(messageId2, DELIVERED))); will(returnValue(singletonMap(messageId2, DELIVERED)));
oneOf(db).commitTransaction(txn3); oneOf(db).commitTransaction(txn3);
oneOf(db).endTransaction(txn3); oneOf(db).endTransaction(txn3);
// Share dependency // Share dependency
@@ -345,7 +324,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
will(returnValue(txn4)); will(returnValue(txn4));
oneOf(db).setMessageShared(txn4, messageId2); oneOf(db).setMessageShared(txn4, messageId2);
oneOf(db).getMessageDependencies(txn4, messageId2); oneOf(db).getMessageDependencies(txn4, messageId2);
will(returnValue(Collections.emptyMap())); will(returnValue(emptyMap()));
oneOf(db).commitTransaction(txn4); oneOf(db).commitTransaction(txn4);
oneOf(db).endTransaction(txn4); oneOf(db).endTransaction(txn4);
}}); }});
@@ -376,7 +355,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).addMessageDependencies(txn1, message, oneOf(db).addMessageDependencies(txn1, message,
validResultWithDependencies.getDependencies()); validResultWithDependencies.getDependencies());
oneOf(db).getMessageDependencies(txn1, messageId); oneOf(db).getMessageDependencies(txn1, messageId);
will(returnValue(Collections.singletonMap(messageId1, DELIVERED))); will(returnValue(singletonMap(messageId1, DELIVERED)));
oneOf(db).mergeMessageMetadata(txn1, messageId, metadata); oneOf(db).mergeMessageMetadata(txn1, messageId, metadata);
// Deliver the message // Deliver the message
oneOf(hook).incomingMessage(txn1, message, metadata); oneOf(hook).incomingMessage(txn1, message, metadata);
@@ -384,7 +363,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).setMessageState(txn1, messageId, DELIVERED); oneOf(db).setMessageState(txn1, messageId, DELIVERED);
// Get any pending dependents // Get any pending dependents
oneOf(db).getMessageDependents(txn1, messageId); oneOf(db).getMessageDependents(txn1, messageId);
will(returnValue(Collections.emptyMap())); will(returnValue(emptyMap()));
// Share message // Share message
oneOf(db).setMessageShared(txn1, messageId); oneOf(db).setMessageShared(txn1, messageId);
oneOf(db).commitTransaction(txn1); oneOf(db).commitTransaction(txn1);
@@ -394,7 +373,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
will(returnValue(txn2)); will(returnValue(txn2));
oneOf(db).setMessageShared(txn2, messageId1); oneOf(db).setMessageShared(txn2, messageId1);
oneOf(db).getMessageDependencies(txn2, messageId1); oneOf(db).getMessageDependencies(txn2, messageId1);
will(returnValue(Collections.emptyMap())); will(returnValue(emptyMap()));
oneOf(db).commitTransaction(txn2); oneOf(db).commitTransaction(txn2);
oneOf(db).endTransaction(txn2); oneOf(db).endTransaction(txn2);
}}); }});
@@ -423,16 +402,14 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
// Load the first raw message - *gasp* it's gone! // Load the first raw message - *gasp* it's gone!
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn1)); will(returnValue(txn1));
oneOf(db).getRawMessage(txn1, messageId); oneOf(db).getMessage(txn1, messageId);
will(throwException(new NoSuchMessageException())); will(throwException(new NoSuchMessageException()));
never(db).commitTransaction(txn1); never(db).commitTransaction(txn1);
oneOf(db).endTransaction(txn1); oneOf(db).endTransaction(txn1);
// Load the second raw message and group // Load the second raw message and group
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn2)); will(returnValue(txn2));
oneOf(db).getRawMessage(txn2, messageId1); oneOf(db).getMessage(txn2, messageId1);
will(returnValue(raw));
oneOf(messageFactory).createMessage(messageId1, raw);
will(returnValue(message1)); will(returnValue(message1));
oneOf(db).getGroup(txn2, groupId); oneOf(db).getGroup(txn2, groupId);
will(returnValue(group)); will(returnValue(group));
@@ -451,21 +428,21 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).deleteMessageMetadata(txn3, messageId1); oneOf(db).deleteMessageMetadata(txn3, messageId1);
// Recursively invalidate dependents // Recursively invalidate dependents
oneOf(db).getMessageDependents(txn3, messageId1); oneOf(db).getMessageDependents(txn3, messageId1);
will(returnValue(Collections.emptyMap())); will(returnValue(emptyMap()));
oneOf(db).commitTransaction(txn3); oneOf(db).commitTransaction(txn3);
oneOf(db).endTransaction(txn3); oneOf(db).endTransaction(txn3);
// Get pending messages to deliver // Get pending messages to deliver
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn4)); will(returnValue(txn4));
oneOf(db).getPendingMessages(txn4); oneOf(db).getPendingMessages(txn4);
will(returnValue(Collections.emptyList())); will(returnValue(emptyList()));
oneOf(db).commitTransaction(txn4); oneOf(db).commitTransaction(txn4);
oneOf(db).endTransaction(txn4); oneOf(db).endTransaction(txn4);
// Get messages to share // Get messages to share
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn5)); will(returnValue(txn5));
oneOf(db).getMessagesToShare(txn5); oneOf(db).getMessagesToShare(txn5);
will(returnValue(Collections.emptyList())); will(returnValue(emptyList()));
oneOf(db).commitTransaction(txn5); oneOf(db).commitTransaction(txn5);
oneOf(db).endTransaction(txn5); oneOf(db).endTransaction(txn5);
}}); }});
@@ -494,9 +471,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
// Load the first raw message // Load the first raw message
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn1)); will(returnValue(txn1));
oneOf(db).getRawMessage(txn1, messageId); oneOf(db).getMessage(txn1, messageId);
will(returnValue(raw));
oneOf(messageFactory).createMessage(messageId, raw);
will(returnValue(message)); will(returnValue(message));
// Load the group - *gasp* it's gone! // Load the group - *gasp* it's gone!
oneOf(db).getGroup(txn1, groupId); oneOf(db).getGroup(txn1, groupId);
@@ -506,9 +481,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
// Load the second raw message and group // Load the second raw message and group
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn2)); will(returnValue(txn2));
oneOf(db).getRawMessage(txn2, messageId1); oneOf(db).getMessage(txn2, messageId1);
will(returnValue(raw));
oneOf(messageFactory).createMessage(messageId1, raw);
will(returnValue(message1)); will(returnValue(message1));
oneOf(db).getGroup(txn2, groupId); oneOf(db).getGroup(txn2, groupId);
will(returnValue(group)); will(returnValue(group));
@@ -527,21 +500,21 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).deleteMessageMetadata(txn3, messageId1); oneOf(db).deleteMessageMetadata(txn3, messageId1);
// Recursively invalidate dependents // Recursively invalidate dependents
oneOf(db).getMessageDependents(txn3, messageId1); oneOf(db).getMessageDependents(txn3, messageId1);
will(returnValue(Collections.emptyMap())); will(returnValue(emptyMap()));
oneOf(db).commitTransaction(txn3); oneOf(db).commitTransaction(txn3);
oneOf(db).endTransaction(txn3); oneOf(db).endTransaction(txn3);
// Get pending messages to deliver // Get pending messages to deliver
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn4)); will(returnValue(txn4));
oneOf(db).getPendingMessages(txn4); oneOf(db).getPendingMessages(txn4);
will(returnValue(Collections.emptyList())); will(returnValue(emptyList()));
oneOf(db).commitTransaction(txn4); oneOf(db).commitTransaction(txn4);
oneOf(db).endTransaction(txn4); oneOf(db).endTransaction(txn4);
// Get messages to share // Get messages to share
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn5)); will(returnValue(txn5));
oneOf(db).getMessagesToShare(txn5); oneOf(db).getMessagesToShare(txn5);
will(returnValue(Collections.emptyList())); will(returnValue(emptyList()));
oneOf(db).commitTransaction(txn5); oneOf(db).commitTransaction(txn5);
oneOf(db).endTransaction(txn5); oneOf(db).endTransaction(txn5);
}}); }});
@@ -575,7 +548,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).setMessageState(txn1, messageId, DELIVERED); oneOf(db).setMessageState(txn1, messageId, DELIVERED);
// Get any pending dependents // Get any pending dependents
oneOf(db).getMessageDependents(txn1, messageId); oneOf(db).getMessageDependents(txn1, messageId);
will(returnValue(Collections.emptyMap())); will(returnValue(emptyMap()));
oneOf(db).commitTransaction(txn1); oneOf(db).commitTransaction(txn1);
oneOf(db).endTransaction(txn1); oneOf(db).endTransaction(txn1);
}}); }});
@@ -584,7 +557,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
} }
@Test @Test
public void testLocalMessagesAreNotValidatedWhenAdded() throws Exception { public void testLocalMessagesAreNotValidatedWhenAdded() {
vm.eventOccurred(new MessageAddedEvent(message, null)); vm.eventOccurred(new MessageAddedEvent(message, null));
} }
@@ -611,7 +584,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).addMessageDependencies(txn1, message, oneOf(db).addMessageDependencies(txn1, message,
validResultWithDependencies.getDependencies()); validResultWithDependencies.getDependencies());
oneOf(db).getMessageDependencies(txn1, messageId); oneOf(db).getMessageDependencies(txn1, messageId);
will(returnValue(Collections.singletonMap(messageId1, UNKNOWN))); will(returnValue(singletonMap(messageId1, UNKNOWN)));
oneOf(db).mergeMessageMetadata(txn1, messageId, metadata); oneOf(db).mergeMessageMetadata(txn1, messageId, metadata);
oneOf(db).setMessageState(txn1, messageId, PENDING); oneOf(db).setMessageState(txn1, messageId, PENDING);
oneOf(db).commitTransaction(txn1); oneOf(db).commitTransaction(txn1);
@@ -644,7 +617,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).addMessageDependencies(txn1, message, oneOf(db).addMessageDependencies(txn1, message,
validResultWithDependencies.getDependencies()); validResultWithDependencies.getDependencies());
oneOf(db).getMessageDependencies(txn1, messageId); oneOf(db).getMessageDependencies(txn1, messageId);
will(returnValue(Collections.singletonMap(messageId1, DELIVERED))); will(returnValue(singletonMap(messageId1, DELIVERED)));
oneOf(db).mergeMessageMetadata(txn1, messageId, metadata); oneOf(db).mergeMessageMetadata(txn1, messageId, metadata);
// Deliver the message // Deliver the message
oneOf(hook).incomingMessage(txn1, message, metadata); oneOf(hook).incomingMessage(txn1, message, metadata);
@@ -652,7 +625,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).setMessageState(txn1, messageId, DELIVERED); oneOf(db).setMessageState(txn1, messageId, DELIVERED);
// Get any pending dependents // Get any pending dependents
oneOf(db).getMessageDependents(txn1, messageId); oneOf(db).getMessageDependents(txn1, messageId);
will(returnValue(Collections.emptyMap())); will(returnValue(emptyMap()));
oneOf(db).commitTransaction(txn1); oneOf(db).commitTransaction(txn1);
oneOf(db).endTransaction(txn1); oneOf(db).endTransaction(txn1);
}}); }});
@@ -685,7 +658,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
validResultWithDependencies.getDependencies()); validResultWithDependencies.getDependencies());
// Check for invalid dependencies // Check for invalid dependencies
oneOf(db).getMessageDependencies(txn1, messageId); oneOf(db).getMessageDependencies(txn1, messageId);
will(returnValue(Collections.singletonMap(messageId1, INVALID))); will(returnValue(singletonMap(messageId1, INVALID)));
// Invalidate message // Invalidate message
oneOf(db).getMessageState(txn1, messageId); oneOf(db).getMessageState(txn1, messageId);
will(returnValue(UNKNOWN)); will(returnValue(UNKNOWN));
@@ -694,7 +667,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).deleteMessageMetadata(txn1, messageId); oneOf(db).deleteMessageMetadata(txn1, messageId);
// Recursively invalidate dependents // Recursively invalidate dependents
oneOf(db).getMessageDependents(txn1, messageId); oneOf(db).getMessageDependents(txn1, messageId);
will(returnValue(Collections.singletonMap(messageId2, UNKNOWN))); will(returnValue(singletonMap(messageId2, UNKNOWN)));
oneOf(db).commitTransaction(txn1); oneOf(db).commitTransaction(txn1);
oneOf(db).endTransaction(txn1); oneOf(db).endTransaction(txn1);
// Invalidate dependent in a new transaction // Invalidate dependent in a new transaction
@@ -706,7 +679,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).deleteMessage(txn2, messageId2); oneOf(db).deleteMessage(txn2, messageId2);
oneOf(db).deleteMessageMetadata(txn2, messageId2); oneOf(db).deleteMessageMetadata(txn2, messageId2);
oneOf(db).getMessageDependents(txn2, messageId2); oneOf(db).getMessageDependents(txn2, messageId2);
will(returnValue(Collections.emptyMap())); will(returnValue(emptyMap()));
oneOf(db).commitTransaction(txn2); oneOf(db).commitTransaction(txn2);
oneOf(db).endTransaction(txn2); oneOf(db).endTransaction(txn2);
}}); }});
@@ -763,7 +736,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).deleteMessageMetadata(txn2, messageId1); oneOf(db).deleteMessageMetadata(txn2, messageId1);
// Message 1 has one dependent: 3 // Message 1 has one dependent: 3
oneOf(db).getMessageDependents(txn2, messageId1); oneOf(db).getMessageDependents(txn2, messageId1);
will(returnValue(Collections.singletonMap(messageId3, PENDING))); will(returnValue(singletonMap(messageId3, PENDING)));
oneOf(db).commitTransaction(txn2); oneOf(db).commitTransaction(txn2);
oneOf(db).endTransaction(txn2); oneOf(db).endTransaction(txn2);
// Invalidate message 2 // Invalidate message 2
@@ -776,7 +749,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).deleteMessageMetadata(txn3, messageId2); oneOf(db).deleteMessageMetadata(txn3, messageId2);
// Message 2 has one dependent: 3 (same dependent as 1) // Message 2 has one dependent: 3 (same dependent as 1)
oneOf(db).getMessageDependents(txn3, messageId2); oneOf(db).getMessageDependents(txn3, messageId2);
will(returnValue(Collections.singletonMap(messageId3, PENDING))); will(returnValue(singletonMap(messageId3, PENDING)));
oneOf(db).commitTransaction(txn3); oneOf(db).commitTransaction(txn3);
oneOf(db).endTransaction(txn3); oneOf(db).endTransaction(txn3);
// Invalidate message 3 (via 1) // Invalidate message 3 (via 1)
@@ -789,7 +762,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).deleteMessageMetadata(txn4, messageId3); oneOf(db).deleteMessageMetadata(txn4, messageId3);
// Message 3 has one dependent: 4 // Message 3 has one dependent: 4
oneOf(db).getMessageDependents(txn4, messageId3); oneOf(db).getMessageDependents(txn4, messageId3);
will(returnValue(Collections.singletonMap(messageId4, PENDING))); will(returnValue(singletonMap(messageId4, PENDING)));
oneOf(db).commitTransaction(txn4); oneOf(db).commitTransaction(txn4);
oneOf(db).endTransaction(txn4); oneOf(db).endTransaction(txn4);
// Invalidate message 3 (again, via 2) // Invalidate message 3 (again, via 2)
@@ -809,7 +782,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).deleteMessageMetadata(txn6, messageId4); oneOf(db).deleteMessageMetadata(txn6, messageId4);
// Message 4 has no dependents // Message 4 has no dependents
oneOf(db).getMessageDependents(txn6, messageId4); oneOf(db).getMessageDependents(txn6, messageId4);
will(returnValue(Collections.emptyMap())); will(returnValue(emptyMap()));
oneOf(db).commitTransaction(txn6); oneOf(db).commitTransaction(txn6);
oneOf(db).endTransaction(txn6); oneOf(db).endTransaction(txn6);
}}); }});
@@ -819,12 +792,10 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
@Test @Test
public void testPendingDependentsGetDelivered() throws Exception { public void testPendingDependentsGetDelivered() throws Exception {
MessageId messageId3 = new MessageId(getRandomId()); Message message3 = getMessage(groupId);
MessageId messageId4 = new MessageId(getRandomId()); Message message4 = getMessage(groupId);
Message message3 = new Message(messageId3, groupId, timestamp, MessageId messageId3 = message3.getId();
raw); MessageId messageId4 = message4.getId();
Message message4 = new Message(messageId4, groupId, timestamp,
raw);
Map<MessageId, State> twoDependents = new LinkedHashMap<>(); Map<MessageId, State> twoDependents = new LinkedHashMap<>();
twoDependents.put(messageId1, PENDING); twoDependents.put(messageId1, PENDING);
twoDependents.put(messageId2, PENDING); twoDependents.put(messageId2, PENDING);
@@ -869,11 +840,9 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).getMessageState(txn2, messageId1); oneOf(db).getMessageState(txn2, messageId1);
will(returnValue(PENDING)); will(returnValue(PENDING));
oneOf(db).getMessageDependencies(txn2, messageId1); oneOf(db).getMessageDependencies(txn2, messageId1);
will(returnValue(Collections.singletonMap(messageId, DELIVERED))); will(returnValue(singletonMap(messageId, DELIVERED)));
// Get message 1 and its metadata // Get message 1 and its metadata
oneOf(db).getRawMessage(txn2, messageId1); oneOf(db).getMessage(txn2, messageId1);
will(returnValue(raw));
oneOf(messageFactory).createMessage(messageId1, raw);
will(returnValue(message1)); will(returnValue(message1));
oneOf(db).getGroup(txn2, groupId); oneOf(db).getGroup(txn2, groupId);
will(returnValue(group)); will(returnValue(group));
@@ -885,7 +854,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).setMessageState(txn2, messageId1, DELIVERED); oneOf(db).setMessageState(txn2, messageId1, DELIVERED);
// Message 1 has one pending dependent: 3 // Message 1 has one pending dependent: 3
oneOf(db).getMessageDependents(txn2, messageId1); oneOf(db).getMessageDependents(txn2, messageId1);
will(returnValue(Collections.singletonMap(messageId3, PENDING))); will(returnValue(singletonMap(messageId3, PENDING)));
oneOf(db).commitTransaction(txn2); oneOf(db).commitTransaction(txn2);
oneOf(db).endTransaction(txn2); oneOf(db).endTransaction(txn2);
// Check whether message 2 is ready to be delivered // Check whether message 2 is ready to be delivered
@@ -894,11 +863,9 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).getMessageState(txn3, messageId2); oneOf(db).getMessageState(txn3, messageId2);
will(returnValue(PENDING)); will(returnValue(PENDING));
oneOf(db).getMessageDependencies(txn3, messageId2); oneOf(db).getMessageDependencies(txn3, messageId2);
will(returnValue(Collections.singletonMap(messageId, DELIVERED))); will(returnValue(singletonMap(messageId, DELIVERED)));
// Get message 2 and its metadata // Get message 2 and its metadata
oneOf(db).getRawMessage(txn3, messageId2); oneOf(db).getMessage(txn3, messageId2);
will(returnValue(raw));
oneOf(messageFactory).createMessage(messageId2, raw);
will(returnValue(message2)); will(returnValue(message2));
oneOf(db).getGroup(txn3, groupId); oneOf(db).getGroup(txn3, groupId);
will(returnValue(group)); will(returnValue(group));
@@ -910,7 +877,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).setMessageState(txn3, messageId2, DELIVERED); oneOf(db).setMessageState(txn3, messageId2, DELIVERED);
// Message 2 has one pending dependent: 3 (same dependent as 1) // Message 2 has one pending dependent: 3 (same dependent as 1)
oneOf(db).getMessageDependents(txn3, messageId2); oneOf(db).getMessageDependents(txn3, messageId2);
will(returnValue(Collections.singletonMap(messageId3, PENDING))); will(returnValue(singletonMap(messageId3, PENDING)));
oneOf(db).commitTransaction(txn3); oneOf(db).commitTransaction(txn3);
oneOf(db).endTransaction(txn3); oneOf(db).endTransaction(txn3);
// Check whether message 3 is ready to be delivered (via 1) // Check whether message 3 is ready to be delivered (via 1)
@@ -921,9 +888,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).getMessageDependencies(txn4, messageId3); oneOf(db).getMessageDependencies(txn4, messageId3);
will(returnValue(twoDependencies)); will(returnValue(twoDependencies));
// Get message 3 and its metadata // Get message 3 and its metadata
oneOf(db).getRawMessage(txn4, messageId3); oneOf(db).getMessage(txn4, messageId3);
will(returnValue(raw));
oneOf(messageFactory).createMessage(messageId3, raw);
will(returnValue(message3)); will(returnValue(message3));
oneOf(db).getGroup(txn4, groupId); oneOf(db).getGroup(txn4, groupId);
will(returnValue(group)); will(returnValue(group));
@@ -934,7 +899,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).setMessageState(txn4, messageId3, DELIVERED); oneOf(db).setMessageState(txn4, messageId3, DELIVERED);
// Message 3 has one pending dependent: 4 // Message 3 has one pending dependent: 4
oneOf(db).getMessageDependents(txn4, messageId3); oneOf(db).getMessageDependents(txn4, messageId3);
will(returnValue(Collections.singletonMap(messageId4, PENDING))); will(returnValue(singletonMap(messageId4, PENDING)));
oneOf(db).commitTransaction(txn4); oneOf(db).commitTransaction(txn4);
oneOf(db).endTransaction(txn4); oneOf(db).endTransaction(txn4);
// Check whether message 3 is ready to be delivered (again, via 2) // Check whether message 3 is ready to be delivered (again, via 2)
@@ -950,11 +915,9 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).getMessageState(txn6, messageId4); oneOf(db).getMessageState(txn6, messageId4);
will(returnValue(PENDING)); will(returnValue(PENDING));
oneOf(db).getMessageDependencies(txn6, messageId4); oneOf(db).getMessageDependencies(txn6, messageId4);
will(returnValue(Collections.singletonMap(messageId3, DELIVERED))); will(returnValue(singletonMap(messageId3, DELIVERED)));
// Get message 4 and its metadata // Get message 4 and its metadata
oneOf(db).getRawMessage(txn6, messageId4); oneOf(db).getMessage(txn6, messageId4);
will(returnValue(raw));
oneOf(messageFactory).createMessage(messageId4, raw);
will(returnValue(message4)); will(returnValue(message4));
oneOf(db).getGroup(txn6, groupId); oneOf(db).getGroup(txn6, groupId);
will(returnValue(group)); will(returnValue(group));
@@ -966,7 +929,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).setMessageState(txn6, messageId4, DELIVERED); oneOf(db).setMessageState(txn6, messageId4, DELIVERED);
// Message 4 has no pending dependents // Message 4 has no pending dependents
oneOf(db).getMessageDependents(txn6, messageId4); oneOf(db).getMessageDependents(txn6, messageId4);
will(returnValue(Collections.emptyMap())); will(returnValue(emptyMap()));
oneOf(db).commitTransaction(txn6); oneOf(db).commitTransaction(txn6);
oneOf(db).endTransaction(txn6); oneOf(db).endTransaction(txn6);
}}); }});
@@ -1004,7 +967,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
oneOf(db).setMessageState(txn1, messageId, DELIVERED); oneOf(db).setMessageState(txn1, messageId, DELIVERED);
// Get any pending dependents // Get any pending dependents
oneOf(db).getMessageDependents(txn1, messageId); oneOf(db).getMessageDependents(txn1, messageId);
will(returnValue(Collections.singletonMap(messageId1, PENDING))); will(returnValue(singletonMap(messageId1, PENDING)));
oneOf(db).commitTransaction(txn1); oneOf(db).commitTransaction(txn1);
oneOf(db).endTransaction(txn1); oneOf(db).endTransaction(txn1);
// Check whether the pending dependent is ready to be delivered // Check whether the pending dependent is ready to be delivered

View File

@@ -1,3 +0,0 @@
bin
build
.settings

4
bramble-java/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
bin
build
.settings
src/main/resources/*.zip

View File

@@ -7,11 +7,16 @@ apply plugin: 'idea'
apply plugin: 'witness' apply plugin: 'witness'
apply from: 'witness.gradle' apply from: 'witness.gradle'
configurations {
tor
}
dependencies { dependencies {
implementation project(path: ':bramble-core', configuration: 'default') implementation project(path: ':bramble-core', configuration: 'default')
implementation fileTree(dir: 'libs', include: '*.jar') implementation fileTree(dir: 'libs', include: '*.jar')
implementation 'net.java.dev.jna:jna:4.4.0' implementation 'net.java.dev.jna:jna:4.4.0'
implementation 'net.java.dev.jna:jna-platform:4.4.0' implementation 'net.java.dev.jna:jna-platform:4.4.0'
tor 'org.briarproject:tor:0.2.9.16@zip'
apt 'com.google.dagger:dagger-compiler:2.0.2' apt 'com.google.dagger:dagger-compiler:2.0.2'
@@ -23,6 +28,15 @@ dependencies {
testImplementation "org.jmock:jmock-legacy:2.8.2" testImplementation "org.jmock:jmock-legacy:2.8.2"
testImplementation "org.hamcrest:hamcrest-library:1.3" testImplementation "org.hamcrest:hamcrest-library:1.3"
testImplementation "org.hamcrest:hamcrest-core:1.3" testImplementation "org.hamcrest:hamcrest-core:1.3"
testApt 'com.google.dagger:dagger-compiler:2.0.2'
}
project.afterEvaluate {
copy {
from configurations.tor.collect { zipTree(it) }
into 'src/main/resources'
}
} }
tasks.withType(Test) { tasks.withType(Test) {

View File

@@ -0,0 +1,16 @@
package org.briarproject.bramble;
import org.briarproject.bramble.network.JavaNetworkModule;
import org.briarproject.bramble.plugin.tor.CircumventionModule;
import org.briarproject.bramble.system.JavaSystemModule;
import dagger.Module;
@Module(includes = {
JavaNetworkModule.class,
JavaSystemModule.class,
CircumventionModule.class
})
public class BrambleJavaModule {
}

View File

@@ -0,0 +1,71 @@
package org.briarproject.bramble.network;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.lifecycle.Service;
import org.briarproject.bramble.api.network.NetworkManager;
import org.briarproject.bramble.api.network.NetworkStatus;
import org.briarproject.bramble.api.network.event.NetworkStatusEvent;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.logging.Logger;
import javax.inject.Inject;
import static java.net.NetworkInterface.getNetworkInterfaces;
import static java.util.Collections.list;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
class JavaNetworkManager implements NetworkManager, Service {
private static final Logger LOG =
Logger.getLogger(JavaNetworkManager.class.getName());
private final EventBus eventBus;
@Inject
JavaNetworkManager(EventBus eventBus) {
this.eventBus = eventBus;
}
@Override
public void startService() {
eventBus.broadcast(new NetworkStatusEvent(getNetworkStatus()));
}
@Override
public void stopService() {
}
@Override
public NetworkStatus getNetworkStatus() {
boolean connected = false;
try {
Enumeration<NetworkInterface> interfaces = getNetworkInterfaces();
if (interfaces != null) {
for (NetworkInterface i : list(interfaces)) {
if (i.isLoopback()) continue;
if (i.isUp() && i.getInetAddresses().hasMoreElements()) {
if (LOG.isLoggable(INFO)) {
LOG.info("Interface " + i.getDisplayName() +
" is up with at least one address.");
}
connected = true;
break;
}
}
}
} catch (SocketException e) {
logException(LOG, WARNING, e);
}
return new NetworkStatus(connected, false);
}
}

View File

@@ -0,0 +1,21 @@
package org.briarproject.bramble.network;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.network.NetworkManager;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
@Module
public class JavaNetworkModule {
@Provides
@Singleton
NetworkManager provideNetworkManager(LifecycleManager lifecycleManager,
JavaNetworkManager networkManager) {
lifecycleManager.registerService(networkManager);
return networkManager;
}
}

View File

@@ -0,0 +1,59 @@
package org.briarproject.bramble.plugin.tor;
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.duplex.DuplexPluginCallback;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.api.system.ResourceProvider;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.CodeSource;
import java.util.concurrent.Executor;
import javax.net.SocketFactory;
@NotNullByDefault
class LinuxTorPlugin extends TorPlugin {
LinuxTorPlugin(Executor ioExecutor, NetworkManager networkManager,
LocationUtils locationUtils, SocketFactory torSocketFactory,
Clock clock, ResourceProvider resourceProvider,
CircumventionProvider circumventionProvider, Backoff backoff,
DuplexPluginCallback callback, String architecture, int maxLatency,
int maxIdleTime, File torDirectory) {
super(ioExecutor, networkManager, locationUtils, torSocketFactory,
clock, resourceProvider, circumventionProvider, backoff,
callback, architecture, maxLatency, maxIdleTime, torDirectory);
}
@Override
protected int getProcessId() {
try {
// Java 9: ProcessHandle.current().pid()
return Integer.parseInt(
new File("/proc/self").getCanonicalFile().getName());
} catch (IOException e) {
throw new AssertionError(e);
}
}
@Override
protected long getLastUpdateTime() {
CodeSource codeSource =
getClass().getProtectionDomain().getCodeSource();
if (codeSource == null) throw new AssertionError("CodeSource null");
try {
URI path = codeSource.getLocation().toURI();
File file = new File(path);
return file.lastModified();
} catch (URISyntaxException e) {
throw new AssertionError(e);
}
}
}

View File

@@ -0,0 +1,103 @@
package org.briarproject.bramble.plugin.tor;
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.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;
import org.briarproject.bramble.api.system.ResourceProvider;
import java.io.File;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
import javax.annotation.concurrent.Immutable;
import javax.net.SocketFactory;
import static org.briarproject.bramble.util.OsUtils.isLinux;
@Immutable
@NotNullByDefault
public class LinuxTorPluginFactory implements DuplexPluginFactory {
private static final Logger LOG =
Logger.getLogger(LinuxTorPluginFactory.class.getName());
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 double BACKOFF_BASE = 1.2;
private final Executor ioExecutor;
private final NetworkManager networkManager;
private final LocationUtils locationUtils;
private final EventBus eventBus;
private final SocketFactory torSocketFactory;
private final BackoffFactory backoffFactory;
private final ResourceProvider resourceProvider;
private final CircumventionProvider circumventionProvider;
private final Clock clock;
private final File torDirectory;
public LinuxTorPluginFactory(Executor ioExecutor,
NetworkManager networkManager, LocationUtils locationUtils,
EventBus eventBus, SocketFactory torSocketFactory,
BackoffFactory backoffFactory, ResourceProvider resourceProvider,
CircumventionProvider circumventionProvider, Clock clock,
File torDirectory) {
this.ioExecutor = ioExecutor;
this.networkManager = networkManager;
this.locationUtils = locationUtils;
this.eventBus = eventBus;
this.torSocketFactory = torSocketFactory;
this.backoffFactory = backoffFactory;
this.resourceProvider = resourceProvider;
this.circumventionProvider = circumventionProvider;
this.clock = clock;
this.torDirectory = torDirectory;
}
@Override
public TransportId getId() {
return TorConstants.ID;
}
@Override
public int getMaxLatency() {
return MAX_LATENCY;
}
@Override
public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
// Check that we have a Tor binary for this architecture
String architecture = null;
if (isLinux()) {
String arch = System.getProperty("os.arch");
if (arch.equals("amd64")) {
architecture = "linux-x86_64";
}
}
if (architecture == null) {
LOG.info("Tor is not supported on this architecture");
return null;
}
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
MAX_POLLING_INTERVAL, BACKOFF_BASE);
LinuxTorPlugin plugin =
new LinuxTorPlugin(ioExecutor, networkManager, locationUtils,
torSocketFactory, clock, resourceProvider,
circumventionProvider, backoff, callback, architecture,
MAX_LATENCY, MAX_IDLE_TIME, torDirectory);
eventBus.addListener(plugin);
return plugin;
}
}

View File

@@ -0,0 +1,27 @@
package org.briarproject.bramble.system;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.system.LocationUtils;
import java.util.Locale;
import java.util.logging.Logger;
import javax.inject.Inject;
@NotNullByDefault
class JavaLocationUtils implements LocationUtils {
private static final Logger LOG =
Logger.getLogger(JavaLocationUtils.class.getName());
@Inject
JavaLocationUtils() {
}
@Override
public String getCurrentCountry() {
LOG.info("Using user-defined locale");
return Locale.getDefault().getCountry();
}
}

View File

@@ -0,0 +1,22 @@
package org.briarproject.bramble.system;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.system.ResourceProvider;
import java.io.InputStream;
import javax.inject.Inject;
@NotNullByDefault
class JavaResourceProvider implements ResourceProvider {
@Inject
JavaResourceProvider() {
}
@Override
public InputStream getResourceInputStream(String name, String extension) {
return getClass().getClassLoader()
.getResourceAsStream(name + extension);
}
}

View File

@@ -0,0 +1,25 @@
package org.briarproject.bramble.system;
import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.api.system.ResourceProvider;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
@Module
public class JavaSystemModule {
@Provides
@Singleton
LocationUtils provideLocationUtils(JavaLocationUtils locationUtils) {
return locationUtils;
}
@Provides
@Singleton
ResourceProvider provideResourceProvider(JavaResourceProvider provider) {
return provider;
}
}

View File

@@ -1,8 +1,5 @@
package org.briarproject.bramble.plugin.tor; package org.briarproject.bramble.plugin.tor;
import android.content.Context;
import android.support.test.runner.AndroidJUnit4;
import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.network.NetworkManager; import org.briarproject.bramble.api.network.NetworkManager;
import org.briarproject.bramble.api.plugin.BackoffFactory; import org.briarproject.bramble.api.plugin.BackoffFactory;
@@ -10,32 +7,32 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.system.LocationUtils; import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.api.system.ResourceProvider; import org.briarproject.bramble.api.system.ResourceProvider;
import org.briarproject.bramble.test.BrambleAndroidIntegrationTestComponent; import org.briarproject.bramble.test.BrambleJavaIntegrationTestComponent;
import org.briarproject.bramble.test.BrambleTestCase; import org.briarproject.bramble.test.BrambleTestCase;
import org.briarproject.bramble.test.DaggerBrambleAndroidIntegrationTestComponent; import org.briarproject.bramble.test.DaggerBrambleJavaIntegrationTestComponent;
import org.junit.AfterClass;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.File;
import java.util.List; import java.util.List;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.inject.Inject; import javax.inject.Inject;
import javax.net.SocketFactory; import javax.net.SocketFactory;
import static android.support.test.InstrumentationRegistry.getTargetContext;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
import static java.util.concurrent.TimeUnit.SECONDS; import static java.util.concurrent.TimeUnit.SECONDS;
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
import static org.briarproject.bramble.test.TestUtils.isOptionalTestEnabled;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
@RunWith(AndroidJUnit4.class)
public class BridgeTest extends BrambleTestCase { public class BridgeTest extends BrambleTestCase {
private final static long TIMEOUT = SECONDS.toMillis(23); private final static long TIMEOUT = SECONDS.toMillis(23);
@@ -56,22 +53,22 @@ public class BridgeTest extends BrambleTestCase {
@Inject @Inject
Clock clock; Clock clock;
private final Context appContext =
getTargetContext().getApplicationContext();
private List<String> bridges; private List<String> bridges;
private AndroidTorPluginFactory factory; private LinuxTorPluginFactory factory;
private final static File torDir = getTestDirectory();
private volatile String currentBridge = null; private volatile String currentBridge = null;
@Before @Before
public void setUp() { public void setUp() {
BrambleAndroidIntegrationTestComponent component = // Skip this test unless it's explicitly enabled in the environment
DaggerBrambleAndroidIntegrationTestComponent.builder().build(); assumeTrue(isOptionalTestEnabled(BridgeTest.class));
BrambleJavaIntegrationTestComponent component =
DaggerBrambleJavaIntegrationTestComponent.builder().build();
component.inject(this); component.inject(this);
Executor ioExecutor = Executors.newCachedThreadPool(); Executor ioExecutor = Executors.newCachedThreadPool();
ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1);
LocationUtils locationUtils = () -> "US"; LocationUtils locationUtils = () -> "US";
SocketFactory torSocketFactory = SocketFactory.getDefault(); SocketFactory torSocketFactory = SocketFactory.getDefault();
@@ -92,9 +89,14 @@ public class BridgeTest extends BrambleTestCase {
return singletonList(currentBridge); return singletonList(currentBridge);
} }
}; };
factory = new AndroidTorPluginFactory(ioExecutor, scheduler, appContext, factory = new LinuxTorPluginFactory(ioExecutor, networkManager,
networkManager, locationUtils, eventBus, torSocketFactory, locationUtils, eventBus, torSocketFactory, backoffFactory,
backoffFactory, resourceProvider, bridgeProvider, clock); resourceProvider, bridgeProvider, clock, torDir);
}
@AfterClass
public static void tearDown() {
deleteTestDirectory(torDir);
} }
@Test @Test
@@ -108,7 +110,7 @@ public class BridgeTest extends BrambleTestCase {
DuplexPlugin duplexPlugin = DuplexPlugin duplexPlugin =
factory.createPlugin(new TorPluginCallBack()); factory.createPlugin(new TorPluginCallBack());
assertNotNull(duplexPlugin); assertNotNull(duplexPlugin);
AndroidTorPlugin plugin = (AndroidTorPlugin) duplexPlugin; LinuxTorPlugin plugin = (LinuxTorPlugin) duplexPlugin;
currentBridge = bridge; currentBridge = bridge;
LOG.warning("Testing " + bridge); LOG.warning("Testing " + bridge);

View File

@@ -1,6 +1,6 @@
package org.briarproject.bramble.test; package org.briarproject.bramble.test;
import org.briarproject.bramble.BrambleAndroidModule; import org.briarproject.bramble.BrambleJavaModule;
import org.briarproject.bramble.event.EventModule; import org.briarproject.bramble.event.EventModule;
import org.briarproject.bramble.plugin.PluginModule; import org.briarproject.bramble.plugin.PluginModule;
import org.briarproject.bramble.plugin.tor.BridgeTest; import org.briarproject.bramble.plugin.tor.BridgeTest;
@@ -12,14 +12,13 @@ import dagger.Component;
@Singleton @Singleton
@Component(modules = { @Component(modules = {
BrambleAndroidModule.class, BrambleJavaModule.class,
TestLifecycleModule.class, TestLifecycleModule.class,
ApplicationModule.class,
PluginModule.class, // needed for BackoffFactory PluginModule.class, // needed for BackoffFactory
EventModule.class, EventModule.class,
SystemModule.class, SystemModule.class,
}) })
public interface BrambleAndroidIntegrationTestComponent { public interface BrambleJavaIntegrationTestComponent {
void inject(BridgeTest init); void inject(BridgeTest init);

View File

@@ -12,6 +12,7 @@ dependencyVerification {
'org.apache.ant:ant-launcher:1.9.4:ant-launcher-1.9.4.jar:7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d', '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.ant:ant:1.9.4:ant-1.9.4.jar:649ae0730251de07b8913f49286d46bba7b92d47c5f332610aa426c4f02161d8',
'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8', 'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8',
'org.briarproject:tor:0.2.9.16:tor-0.2.9.16.zip:f33091ba414d6a952263981d9059b3d0a9093fd277ae887b3cdd02e8f1936558',
'org.hamcrest:hamcrest-core:1.3:hamcrest-core-1.3.jar:66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9', '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.hamcrest:hamcrest-library:1.3:hamcrest-library-1.3.jar:711d64522f9ec410983bd310934296da134be4254a125080a0416ec178dfad1c',
'org.jmock:jmock-junit4:2.8.2:jmock-junit4-2.8.2.jar:f7ee4df4f7bd7b7f1cafad3b99eb74d579f109d5992ff625347352edb55e674c', 'org.jmock:jmock-junit4:2.8.2:jmock-junit4-2.8.2.jar:f7ee4df4f7bd7b7f1cafad3b99eb74d579f109d5992ff625347352edb55e674c',

View File

@@ -7,5 +7,5 @@ file_filter = src/main/res/values-<lang>/strings.xml
source_file = src/main/res/values/strings.xml source_file = src/main/res/values/strings.xml
source_lang = en source_lang = en
type = ANDROID type = ANDROID
minimum_perc = 25 minimum_perc = 80

View File

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="162"
height="156"
viewBox="0 0 162 156"
fill="none"
version="1.1"
id="svg16"
sodipodi:docname="No-Posts.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)">
<metadata
id="metadata22">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs20" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="754"
inkscape:window-height="480"
id="namedview18"
showgrid="false"
inkscape:zoom="1.5128205"
inkscape:cx="81"
inkscape:cy="78"
inkscape:window-x="0"
inkscape:window-y="20"
inkscape:window-maximized="0"
inkscape:current-layer="svg16" />
<rect
width="80.9997"
height="78"
fill="black"
fill-opacity="0"
transform="scale(2)"
id="rect2" />
<rect
width="80.9997"
height="78"
fill="black"
fill-opacity="0"
transform="scale(2)"
id="rect4" />
<path
d="M140.87 53.647H91.5654V64.2352H140.87V53.647Z"
fill="white"
fill-opacity="0.6"
id="path6" />
<path
d="M140.869 99.5292V88.9409H115.512L126.077 99.5292H140.869Z"
fill="white"
fill-opacity="0.6"
id="path8" />
<path
d="M140.869 71.2939H97.9038L108.469 81.8822H140.869V71.2939Z"
fill="white"
fill-opacity="0.6"
id="path10" />
<path
d="M147.912 14.8232H41.5557L84.5209 57.8821V28.9409H147.912V120.706H147.208L157.773 131.294C160.59 128.47 161.999 124.941 161.999 120.706V28.9409C161.999 21.1762 155.66 14.8232 147.912 14.8232Z"
fill="white"
fill-opacity="0.6"
id="path12" />
<path
d="M129.6 120.706L84.5217 75.5294L23.9478 14.8235L9.15652 0L0 9.17647L10.5652 19.7647C8.45217 21.8824 7.04348 25.4118 7.04348 28.9412V120.706C7.04348 128.471 13.3826 134.824 21.1304 134.824H125.374L146.504 156L155.661 146.824L143.687 134.824L129.6 120.706ZM84.5217 120.706V93.8824L111.287 120.706H84.5217Z"
fill="white"
fill-opacity="0.6"
id="path14" />
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="164"
height="164"
viewBox="0 0 164 164"
fill="none"
version="1.1"
id="svg12"
sodipodi:docname="empty_state_contact_list.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)">
<metadata
id="metadata18">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs16" />
<sodipodi:namedview
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1020"
id="namedview14"
showgrid="false"
inkscape:zoom="1.4390244"
inkscape:cx="81.305085"
inkscape:cy="109.79661"
inkscape:window-x="1440"
inkscape:window-y="24"
inkscape:window-maximized="0"
inkscape:current-layer="svg12" />
<path
style="clip-rule:evenodd;display:inline;fill:#ffffff;fill-rule:evenodd"
d="M 27.333984 0 L 27.333984 13.666016 L 136.66797 13.666016 L 136.66797 0 L 27.333984 0 z M 27.333984 27.333984 C 19.817284 27.333984 13.666016 33.4834 13.666016 41 L 13.666016 123 C 13.666016 130.517 19.817284 136.66797 27.333984 136.66797 L 136.66797 136.66797 C 144.18397 136.66797 150.33203 130.517 150.33203 123 L 150.33203 41 C 150.33203 33.4834 144.18397 27.333984 136.66797 27.333984 L 27.333984 27.333984 z M 82.150391 44.757812 C 89.592295 44.757812 95.348492 46.476807 99.419922 49.914062 C 103.52467 53.351338 105.57617 58.23949 105.57617 64.580078 C 105.57617 67.349967 105.0272 69.869409 103.92578 72.138672 C 102.82458 74.407935 101.05521 76.728225 98.619141 79.097656 L 92.863281 84.453125 C 91.227921 86.021639 90.093094 87.640125 89.458984 89.308594 C 88.824874 90.943745 88.475053 93.030171 88.408203 95.566406 L 74.091797 95.566406 C 74.091797 90.694273 74.640917 86.855942 75.742188 84.052734 C 76.843435 81.216209 78.63001 78.762286 81.099609 76.693359 C 83.568995 74.624218 85.436853 72.739109 86.705078 71.037109 C 88.006403 69.30179 88.658203 67.400958 88.658203 65.332031 C 88.658203 60.292857 86.488795 57.771484 82.150391 57.771484 C 80.1481 57.771484 78.529614 58.506262 77.294922 59.974609 C 76.060186 61.442955 75.40854 63.42881 75.341797 65.931641 L 58.423828 65.931641 C 58.490468 59.25736 60.592402 54.067509 64.730469 50.363281 C 68.868538 46.625672 74.675257 44.757813 82.150391 44.757812 z M 81.398438 102.32422 C 84.068159 102.32422 86.287795 103.12473 88.056641 104.72656 C 89.858601 106.29508 90.759766 108.31381 90.759766 110.7832 C 90.759766 113.2528 89.858601 115.28879 88.056641 116.89062 C 86.287795 118.45914 84.068159 119.24219 81.398438 119.24219 C 78.728717 119.24219 76.493467 118.45914 74.691406 116.89062 C 72.922705 115.28879 72.039062 113.2528 72.039062 110.7832 C 72.039062 108.31381 72.922705 106.29508 74.691406 104.72656 C 76.493467 103.12473 78.728716 102.32422 81.398438 102.32422 z M 27.333984 150.33203 L 27.333984 164 L 136.66797 164 L 136.66797 150.33203 L 27.333984 150.33203 z "
id="path8" />
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="148"
height="148"
viewBox="0 0 148 148"
fill="none"
version="1.1"
id="svg12"
sodipodi:docname="No-Forums.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)">
<metadata
id="metadata18">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs16" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1366"
inkscape:window-height="720"
id="namedview14"
showgrid="false"
inkscape:zoom="1.5945946"
inkscape:cx="74"
inkscape:cy="74"
inkscape:window-x="0"
inkscape:window-y="20"
inkscape:window-maximized="1"
inkscape:current-layer="svg12" />
<rect
width="74"
height="74"
fill="black"
fill-opacity="0"
transform="scale(2)"
id="rect2" />
<rect
width="74"
height="74"
fill="black"
fill-opacity="0"
transform="scale(2)"
id="rect4" />
<path
d="M107.266 74.6791C111.34 74.6791 114.055 71.9635 114.055 67.8901V6.78901C114.055 2.7156 111.34 0 107.266 0H24.4404L99.1194 74.6791H107.266Z"
fill="white"
fill-opacity="0.6"
id="path6" />
<path
d="M141.211 27.156H127.633V88.2571H112.697L148 123.56V33.945C148 29.8716 144.606 27.156 141.211 27.156Z"
fill="white"
fill-opacity="0.6"
id="path8" />
<path
d="M8.8257 1.35742L0 10.1831L12.2202 22.4033V101.835L39.3762 74.6787H64.4955L78.0735 88.2567H39.3762V101.835C39.3762 105.908 42.0918 108.624 46.1652 108.624H98.4405L137.817 148L146.642 139.174L8.8257 1.35742Z"
fill="white"
fill-opacity="0.6"
id="path10" />
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="172"
height="140"
viewBox="0 0 172 140"
fill="none"
version="1.1"
id="svg14"
sodipodi:docname="No-Groups.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)">
<metadata
id="metadata20">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs18" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="754"
inkscape:window-height="480"
id="namedview16"
showgrid="false"
inkscape:zoom="1.6857143"
inkscape:cx="86"
inkscape:cy="70"
inkscape:window-x="0"
inkscape:window-y="20"
inkscape:window-maximized="0"
inkscape:current-layer="svg14" />
<rect
width="85.9999"
height="70"
fill="black"
fill-opacity="0"
transform="scale(2)"
id="rect2" />
<rect
width="85.9999"
height="70"
fill="black"
fill-opacity="0"
transform="scale(2)"
id="rect4" />
<path
d="M125.091 103.444L71.9274 50.5556L38.3092 17.1111L21.1091 0L10.9455 10.1111L31.2728 30.3333C31.2728 31.8889 31.2728 32.6667 31.2728 34.2222C31.2728 47.4444 41.4365 57.5556 54.7274 57.5556C56.291 57.5556 57.0729 57.5556 58.6365 56.7778L78.182 76.2222C69.582 74.6667 60.982 73.1111 54.7274 73.1111C36.7455 73.1111 0 82.4444 0 100.333V119.778H109.455V107.333L142.291 140L152.455 129.889L142.291 119.778L125.091 103.444Z"
fill="white"
fill-opacity="0.6"
id="path6" />
<path
d="M117.273 57.5549C130.227 57.5549 140.728 47.1082 140.728 34.2215C140.728 21.3349 130.227 10.8882 117.273 10.8882C104.319 10.8882 93.8184 21.3349 93.8184 34.2215C93.8184 47.1082 104.319 57.5549 117.273 57.5549Z"
fill="white"
fill-opacity="0.6"
id="path8" />
<path
d="M78.1819 34.2215C78.1819 20.9993 68.0182 10.8882 54.7273 10.8882C53.9455 10.8882 53.1637 10.8882 52.3818 10.8882L78.1819 36.5548C78.1819 35.7771 78.1819 34.9993 78.1819 34.2215Z"
fill="white"
fill-opacity="0.6"
id="path10" />
<path
d="M117.272 73.1104C116.49 73.1104 115.709 73.1104 114.927 73.1104L161.836 119.777H172V100.333C172 82.4437 135.254 73.1104 117.272 73.1104Z"
fill="white"
fill-opacity="0.6"
id="path12" />
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
height="161.7"
width="409.20001"
version="1.1"
id="svg2"
x="0px"
y="0px"
viewBox="0 0 409.2 161.7"
xml:space="preserve"><metadata
id="metadata853"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs851" />
<style
type="text/css"
id="style826">
.st0{display:none;fill:none;stroke:#FFFFFF;stroke-width:4.3281;}
.st1{fill-rule:evenodd;clip-rule:evenodd;fill:#020202;}
</style>
<path
id="path4201"
d="m 369.6,157.3 -4.3,-4.3 -7.1,-2.4 c -3.9,-1.3 -8.7,-3 -10.7,-3.7 l -3.7,-1.3 3.5,-0.2 c 8.2,-0.4 13,-4 14.3,-10.9 0.8,-4.1 1.1,-17.3 0.8,-33 -0.2,-8.100003 -0.2,-15.400003 0,-16.300003 0.1,-0.9 0.5,-2.4 0.9,-3.4 1.2,-3.5 0.3,-11.9 -1.9,-17.6 -0.3,-0.9 -1.9,-4.2 -3.5,-7.4 -4.2,-8.2 -4.5,-8.9 -4.9,-10.5 -0.5,-1.8 -0.2,-5.4 0.5,-6.8 0.7,-1.3 2.2,-2.9 3.2,-3.5 1.3,-0.7 2.6,0.1 4.7,2.9 3.4,4.5 14,19.4 15.7,22.2 3.7,6 6,11.2 8,18.8 0.7,2.5 1.9,7 2.7,10.1 0.8,3.1 2.7,10.200003 4.1,15.800003 l 2.6,10.2 4.6,5.2 c 2.6,2.9 5.8,6.5 7.2,8 1.4,1.6 2.5,3 2.5,3.2 0,0.3 -34.5,29.3 -34.9,29.3 0.1,-0.1 -1.9,-2.1 -4.3,-4.4 z m -93.9,-16.4 c -1.3,-0.6 -2.2,-1.4 -2.9,-2.3 -2.1,-2.7 -2,2.4 -1.9,-68.500003 l 0.1,-64.0000001 0.7,-1.2 c 1,-1.9 2,-2.9 3.7,-3.89999995 l 1.6,-0.9 L 314.8,-3.0517578e-6 C 357.3,-0.10000305 354.2,-0.20000305 356.9,2.1999969 c 0.9,0.8 1.8,2 2.2,2.9 0.7,1.6 0.7,1.6 0.8,14.2000001 l 0.1,12.6 -1.8,-0.1 c -1.4,-0.1 -2.1,0 -3.2,0.5 -2,1 -3.9,2.9 -5.1,5.1 l -1,2 v -12.8 -12.8 h -33.6 -33.6 v 51.3 V 116.4 h 33.6 33.6 L 349,81.999997 c 0.1,-33 0.1,-34.4 0.6,-32.9 0.3,0.8 1.8,4 3.4,7 5.5,10.6 5.4,9.9 5.4,47.200003 0,27.6 -0.1,30 -1.7,33.1 -1.1,2.2 -2.7,3.7 -5.1,4.7 l -1.7,0.7 -36.1,-0.1 -36.2,0.1 z m 42.4,-5.1 c 2.9,-1.3 4.5,-3.7 4.4,-6.6 0,-4.1 -3.1,-7.2 -7.1,-7.2 -2.1,0 -3.6,0.6 -5.2,2.2 -2.2,2.2 -2.8,5.4 -1.3,8.3 0.7,1.4 2.5,3 4,3.5 1.5,0.5 3.9,0.5 5.2,-0.2 z" />
<path
id="path4201-1"
d="m 39.2,157.3 4.3,-4.3 7.1,-2.4 c 3.9,-1.3 8.7,-3 10.7,-3.7 l 3.7,-1.3 -3.5,-0.2 c -8.2,-0.4 -13,-4 -14.3,-10.9 -0.8,-4.1 -1.1,-17.3 -0.8,-33 0.2,-8.100003 0.2,-15.400003 0,-16.300003 -0.1,-0.9 -0.5,-2.4 -0.9,-3.4 -1.2,-3.5 -0.3,-11.9 1.9,-17.6 0.3,-0.9 1.9,-4.2 3.5,-7.4 4.2,-8.2 4.5,-8.9 4.9,-10.5 0.5,-1.8 0.2,-5.4 -0.5,-6.8 -0.7,-1.3 -2.2,-2.9 -3.2,-3.5 -1.3,-0.7 -2.6,0.1 -4.7,2.9 -3.4,4.5 -14,19.4 -15.7,22.2 -3.7,6 -6,11.2 -8,18.8 -0.7,2.5 -1.9,7 -2.7,10.1 -0.8,3.1 -2.7,10.200003 -4.1,15.800003 l -2.6,10.2 -4.6,5.2 c -2.6,2.9 -5.8,6.5 -7.2,8 -1.4,1.5 -2.5,3 -2.5,3.2 0,0.3 34.5,29.3 34.9,29.3 -0.1,-0.1 2,-2.1 4.3,-4.4 z m 93.9,-16.4 c 1.3,-0.6 2.2,-1.4 2.9,-2.3 2.1,-2.7 2,2.4 1.9,-68.500003 l -0.1,-64.0000001 -0.7,-1.2 c -1,-1.9 -2,-2.9 -3.7,-3.89999995 l -1.6,-0.9 L 94,-3.0517578e-6 C 51.5,-0.10000305 54.6,-0.20000305 51.9,2.1999969 c -0.9,0.8 -1.8,2 -2.2,2.9 -0.7,1.6 -0.7,1.6 -0.8,14.2000001 l -0.1,12.6 1.8,-0.1 c 1.4,-0.1 2.1,0 3.2,0.5 2,1 3.9,2.9 5.1,5.1 l 1,2 v -12.8 -12.8 h 33.6 33.6 v 51.3 V 116.4 H 93.6 60 L 59.9,81.999997 c -0.1,-33 -0.1,-34.4 -0.6,-32.9 -0.3,0.8 -1.8,4 -3.4,7 -5.5,10.6 -5.4,9.9 -5.4,47.200003 0,27.6 0.1,30 1.7,33.1 1.1,2.2 2.7,3.7 5.1,4.7 l 1.7,0.7 36.2,0.1 36.2,0.1 z m -42.4,-5.1 c -2.9,-1.3 -4.5,-3.7 -4.4,-6.6 0,-4.1 3.1,-7.2 7.1,-7.2 2.1,0 3.6,0.6 5.2,2.2 2.2,2.2 2.8,5.4 1.3,8.3 -0.7,1.4 -2.5,3 -4,3.5 -1.5,0.5 -3.8,0.5 -5.2,-0.2 z" />
<g
transform="translate(46.8,-347.3)"
id="g832">
<path
d="m 33.5,410.2 h 2.3 v 2.3 h 2.3 v 2.3 H 26.6 v -2.3 h 2.3 v -4.6 h 4.6 z m 30,20.8 h 2.3 v -2.3 H 63.5 Z M 35.8,410.2 h 2.3 v -2.3 H 35.8 Z M 68.1,431 h 2.3 v -2.3 h -2.3 z m -27.7,2.3 H 45 V 431 h -4.6 z m 20.8,0 V 431 h -2.3 v 2.3 z m -9.2,0 h 2.3 v -4.6 H 52 Z m -18.5,-30 v 2.3 h 6.9 v -2.3 z m -2.3,2.3 v -2.3 h -4.6 v 4.6 h 2.3 v -2.3 z M 38.1,401 H 22 V 384.9 H 38.1 Z M 35.8,387.2 H 24.3 v 11.5 h 11.5 z m -9.2,41.5 h 6.9 v -6.9 h -6.9 z m 23,-2.4 v 2.3 H 52 v -2.3 z M 33.5,389.5 h -6.9 v 6.9 h 6.9 z m 36.9,-4.6 V 401 H 54.3 v -16.1 z m -2.3,2.3 H 56.6 v 11.5 H 68.1 Z M 22,417.1 h 16.1 v 16.1 H 22 Z M 24.3,431 H 35.8 V 419.5 H 24.3 Z m 0,-27.7 H 22 v 11.5 h 2.3 z m 30,11.5 v 2.3 h 2.3 v -2.3 z m -7,9.3 v -2.3 H 45 v 2.3 h -4.6 v 4.6 H 45 v 2.3 h 2.3 v -4.6 h 2.3 v -2.3 z m -6.9,-30 H 45 v -2.3 h -4.6 z m 18.5,18.4 h 4.6 v 2.3 h 2.3 v -6.9 h -2.3 v -4.6 h -2.3 v 6.9 h -6.9 v 2.3 h 2.3 v 2.3 h 2.3 z m 2.3,6.9 h -2.3 v -2.3 h -2.3 v 4.6 h -6.9 v 2.3 h 4.6 v 4.6 h 2.3 v 2.3 h 2.3 v -4.6 h 9.2 V 424 h -6.9 z m 0,0 h 2.3 v -4.6 h -2.3 z m -18.5,0 v -2.3 H 45 v -2.3 h 2.3 v -2.3 h 2.3 v -4.6 h 6.9 v -4.6 h -2.3 v 2.3 H 52 v -9.2 h -2.3 v -4.6 H 52 v -6.9 h -2.3 v 4.6 h -2.3 v -4.6 h -6.9 v 4.6 h 2.3 v -2.3 H 45 v 4.6 h 2.3 v 6.9 h 2.3 v 2.3 h -2.3 v 4.6 H 45 V 401 h -2.3 v -2.3 h -2.3 v 4.6 h 2.3 v 2.3 h -2.3 v 6.9 h 2.3 v -4.6 H 45 v 4.6 h -2.3 v 2.3 h -2.3 v 6.9 H 45 v -2.3 z m 25.4,2.3 v -2.3 h -4.6 v 2.3 z m -2.3,-32.2 h -6.9 v 6.9 h 6.9 z M 47.3,419.4 H 52 v -2.3 h -2.3 v -2.3 h -2.3 v 4.6 z m 4.7,-4.6 v -2.3 h -2.3 v 2.3 z m 13.8,-9.2 h 4.6 v -2.3 h -4.6 z m 2.3,18.5 h 2.3 v -2.3 h -2.3 z m 0,-13.9 h 2.3 v -2.3 H 68.1 Z M 47.3,398.7 H 45 v 2.3 h 2.3 z m 0,0"
id="path830" />
</g>
<g
transform="translate(46.8,-347.3)"
id="g836">
<path
d="m 256.5,410.2 h 2.3 v 2.3 h 2.3 v 2.3 h -11.5 v -2.3 h 2.3 v -4.6 h 4.6 z m 30,20.8 h 2.3 v -2.3 h -2.3 z m -27.7,-20.8 h 2.3 v -2.3 h -2.3 z m 32.3,20.8 h 2.3 v -2.3 h -2.3 z m -27.7,2.3 H 268 V 431 h -4.6 z m 20.8,0 V 431 h -2.3 v 2.3 z m -9.2,0 h 2.3 v -4.6 H 275 Z m -18.5,-30 v 2.3 h 6.9 v -2.3 z m -2.3,2.3 v -2.3 h -4.6 v 4.6 h 2.3 v -2.3 z m 6.9,-4.6 H 245 v -16.1 h 16.1 z m -2.3,-13.8 h -11.5 v 11.5 h 11.5 z m -9.2,41.5 h 6.9 v -6.9 h -6.9 z m 23,-2.4 v 2.3 h 2.3 v -2.3 z m -16.1,-36.8 h -6.9 v 6.9 h 6.9 z m 36.9,-4.6 V 401 h -16.1 v -16.1 z m -2.3,2.3 h -11.5 v 11.5 h 11.5 z M 245,417.1 h 16.1 v 16.1 H 245 Z m 2.3,13.9 h 11.5 v -11.5 h -11.5 z m 0,-27.7 H 245 v 11.5 h 2.3 z m 30,11.5 v 2.3 h 2.3 v -2.3 z m -7,9.3 v -2.3 H 268 v 2.3 h -4.6 v 4.6 h 4.6 v 2.3 h 2.3 v -4.6 h 2.3 v -2.3 z m -6.9,-30 h 4.6 v -2.3 h -4.6 z m 18.5,18.4 h 4.6 v 2.3 h 2.3 v -6.9 h -2.3 v -4.6 h -2.3 v 6.9 h -6.9 v 2.3 h 2.3 v 2.3 h 2.3 z m 2.3,6.9 h -2.3 v -2.3 h -2.3 v 4.6 h -6.9 v 2.3 h 4.6 v 4.6 h 2.3 v 2.3 h 2.3 v -4.6 h 9.2 V 424 h -6.9 z m 0,0 h 2.3 v -4.6 h -2.3 z m -18.5,0 v -2.3 h 2.3 v -2.3 h 2.3 v -2.3 h 2.3 v -4.6 h 6.9 v -4.6 h -2.3 v 2.3 H 275 v -9.2 h -2.3 v -4.6 h 2.3 v -6.9 h -2.3 v 4.6 h -2.3 v -4.6 h -6.9 v 4.6 h 2.3 v -2.3 h 2.3 v 4.6 h 2.3 v 6.9 h 2.3 v 2.3 h -2.3 v 4.6 H 268 V 401 h -2.3 v -2.3 h -2.3 v 4.6 h 2.3 v 2.3 h -2.3 v 6.9 h 2.3 v -4.6 h 2.3 v 4.6 h -2.3 v 2.3 h -2.3 v 6.9 h 4.6 v -2.3 z m 25.4,2.3 v -2.3 h -4.6 v 2.3 z m -2.3,-32.2 h -6.9 v 6.9 h 6.9 z m -18.5,29.9 h 4.6 v -2.3 h -2.3 v -2.3 h -2.3 z m 4.7,-4.6 v -2.3 h -2.3 v 2.3 z m 13.8,-9.2 h 4.6 v -2.3 h -4.6 z m 2.3,18.5 h 2.3 v -2.3 h -2.3 z m 0,-13.9 h 2.3 v -2.3 h -2.3 z M 270.3,398.7 H 268 v 2.3 h 2.3 z m 0,0"
id="path834" />
</g>
<path
style="opacity:1;fill:#000000;stroke-width:3.21294165"
d="m 207.61295,88.782357 h -6.42588 v -12.85177 h 6.42588 m 0,25.703533 h -6.42588 v -6.425883 h 6.42588 m -38.5553,16.064713 h 70.68472 L 204.40001,50.227047 Z"
id="path2" /></svg>

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@@ -31,9 +31,8 @@ dependencies {
implementation 'info.guardianproject.trustedintents:trustedintents:0.2' implementation 'info.guardianproject.trustedintents:trustedintents:0.2'
implementation 'de.hdodenhof:circleimageview:2.2.0' implementation 'de.hdodenhof:circleimageview:2.2.0'
implementation 'com.google.zxing:core:3.3.0' implementation 'com.google.zxing:core:3.3.0'
implementation 'com.jpardogo.materialtabstrip:library:1.1.0'
implementation 'com.github.bumptech.glide:glide:3.8.0'
implementation 'uk.co.samuelwall:material-tap-target-prompt:2.8.0' implementation 'uk.co.samuelwall:material-tap-target-prompt:2.8.0'
implementation 'com.vanniktech:emoji-google:0.5.1'
annotationProcessor 'com.google.dagger:dagger-compiler:2.0.2' annotationProcessor 'com.google.dagger:dagger-compiler:2.0.2'
@@ -76,14 +75,14 @@ def getStdout = { command, defaultValue ->
} }
android { android {
compileSdkVersion 27 compileSdkVersion 28
buildToolsVersion '27.0.3' buildToolsVersion '28.0.2'
defaultConfig { defaultConfig {
minSdkVersion 14 minSdkVersion 15
targetSdkVersion 26 targetSdkVersion 26
versionCode 10013 versionCode 10101
versionName "1.0.13" versionName "1.1.1"
applicationId "org.briarproject.briar.android" applicationId "org.briarproject.briar.android"
buildConfigField "String", "GitHash", buildConfigField "String", "GitHash",
"\"${getStdout(['git', 'rev-parse', '--short=7', 'HEAD'], 'No commit hash')}\"" "\"${getStdout(['git', 'rev-parse', '--short=7', 'HEAD'], 'No commit hash')}\""
@@ -155,7 +154,7 @@ task verifyTranslations {
def folders = ["default", "en-US"] def folders = ["default", "en-US"]
project.file("src/main/res").eachDir { dir -> project.file("src/main/res").eachDir { dir ->
if (dir.name.startsWith("values-") && !dir.name.endsWith("night")) { if (dir.name.startsWith("values-") && !dir.name.endsWith("night") && !dir.name.endsWith("v21")) {
folders.add(dir.name.substring(7).replace("-r", "-")) folders.add(dir.name.substring(7).replace("-r", "-"))
} }
} }
@@ -185,5 +184,3 @@ task verifyTranslations {
project.afterEvaluate { project.afterEvaluate {
preBuild.dependsOn.add(verifyTranslations) preBuild.dependsOn.add(verifyTranslations)
} }

View File

@@ -27,9 +27,4 @@
-dontnote org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout -dontnote org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout
# Emoji # Emoji
-keep class org.thoughtcrime.securesms.** -keep class com.vanniktech.emoji.**
-keep class com.astuetz.PagerSlidingTabStrip$OnTabReselectedListener
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
**[] $VALUES;
public *;
}

View File

@@ -3,6 +3,7 @@ package org.briarproject.briar.android.settings;
import android.content.Intent; import android.content.Intent;
import android.support.test.espresso.contrib.DrawerActions; import android.support.test.espresso.contrib.DrawerActions;
import android.support.test.runner.AndroidJUnit4; import android.support.test.runner.AndroidJUnit4;
import android.support.v7.widget.RecyclerView;
import android.view.Gravity; import android.view.Gravity;
import org.briarproject.briar.R; import org.briarproject.briar.R;
@@ -17,9 +18,16 @@ import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches; import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.contrib.DrawerMatchers.isClosed; import static android.support.test.espresso.contrib.DrawerMatchers.isClosed;
import static android.support.test.espresso.contrib.RecyclerViewActions.scrollTo;
import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.isEnabled;
import static android.support.test.espresso.matcher.ViewMatchers.withChild;
import static android.support.test.espresso.matcher.ViewMatchers.withClassName;
import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText; import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.briarproject.briar.android.test.ViewActions.waitUntilMatches;
import static org.hamcrest.CoreMatchers.is;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
public class SettingsActivityScreenshotTest extends ScreenshotTest { public class SettingsActivityScreenshotTest extends ScreenshotTest {
@@ -48,23 +56,75 @@ public class SettingsActivityScreenshotTest extends ScreenshotTest {
.check(matches(isDisplayed())) .check(matches(isDisplayed()))
.perform(click()); .perform(click());
// open nav drawer and remove expiry warning
openNavDrawer(true);
screenshot("manual_dark_theme_nav_drawer");
}
@Test
public void appLock() {
// scroll down
onView(withClassName(is(RecyclerView.class.getName())))
.perform(scrollTo(hasDescendant(
// scroll down a bit more to have settings in the middle
withText(R.string.panic_setting))));
// wait for settings to get loaded and enabled
onView(withText(R.string.tor_mobile_data_title))
.perform(waitUntilMatches(isEnabled()));
// ensure app lock is displayed and enabled
onView(withText(R.string.pref_lock_title))
.check(matches(isDisplayed()))
.check(matches(isEnabled()))
.perform(click());
onView(withChild(withText(R.string.pref_lock_timeout_title)))
.check(matches(isDisplayed()))
.check(matches(isEnabled()));
screenshot("manual_app_lock");
// no more expiry warning to remove, because sharedprefs cached?
openNavDrawer(false);
screenshot("manual_app_lock_nav_drawer");
}
@Test
public void torSettings() {
// scroll down
onView(withClassName(is(RecyclerView.class.getName())))
.perform(scrollTo(hasDescendant(
// scroll down a bit more to have settings in the middle
withText(R.string.pref_lock_timeout_title))));
// wait for settings to get loaded and enabled
onView(withText(R.string.tor_network_setting))
.check(matches(isDisplayed()))
.perform(waitUntilMatches(isEnabled()));
screenshot("manual_tor_settings");
}
private void openNavDrawer(boolean expiry) {
// start main activity // start main activity
Intent i = Intent i =
new Intent(testRule.getActivity(), NavDrawerActivity.class); new Intent(testRule.getActivity(), NavDrawerActivity.class);
testRule.getActivity().startActivity(i); testRule.getActivity().startActivity(i);
// close expiry warning // close expiry warning
onView(withId(R.id.expiryWarningClose)) if (expiry) {
.check(matches(isDisplayed())); onView(withId(R.id.expiryWarningClose))
onView(withId(R.id.expiryWarningClose)) .check(matches(isDisplayed()));
.perform(click()); onView(withId(R.id.expiryWarningClose))
.perform(click());
}
// open navigation drawer // open navigation drawer
onView(withId(R.id.drawer_layout)) onView(withId(R.id.drawer_layout))
.check(matches(isClosed(Gravity.START))) .check(matches(isClosed(Gravity.START)))
.perform(DrawerActions.open()); .perform(DrawerActions.open());
screenshot("manual_dark_theme_nav_drawer");
} }
} }

View File

@@ -17,6 +17,7 @@
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/> <uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<uses-permission-sdk-23 android:name="android.permission.USE_BIOMETRIC" />
<application <application
android:name="org.briarproject.briar.android.BriarApplicationImpl" android:name="org.briarproject.briar.android.BriarApplicationImpl"

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