Compare commits

..

15 Commits

Author SHA1 Message Date
akwizgran
b02d89967e Use /dev/urandom for tests. 2018-08-20 16:54:46 +01:00
akwizgran
65ce049737 Enable logging to console for briar-core tests. 2018-08-20 15:53:13 +01:00
akwizgran
335c360ef8 Ignore IntroductionIntegrationTest. 2018-08-20 15:35:15 +01:00
akwizgran
fc26aaa168 Run only briar-core tests. 2018-08-20 15:23:35 +01:00
akwizgran
88224793c1 Fix cache paths. 2018-08-20 12:24:28 +01:00
akwizgran
0bf74f6a69 Environment var isn't available when creating cache. 2018-08-20 12:20:18 +01:00
akwizgran
4286621b02 Specify cache key. 2018-08-20 12:12:33 +01:00
akwizgran
b3e3b970ab List Gradle user directory. 2018-08-20 12:11:13 +01:00
akwizgran
ef10a08165 List cached directories. 2018-08-20 12:07:56 +01:00
akwizgran
094e1f8b65 List wrapper dists directory. 2018-08-20 12:06:46 +01:00
akwizgran
8b58bdb289 Remove stop command, use cache path. 2018-08-20 12:05:06 +01:00
akwizgran
7f61061f15 Stop daemon, just run Animal Sniffer. 2018-08-20 11:59:16 +01:00
akwizgran
cd127670bb Just clean, don't run tests. 2018-08-20 11:56:46 +01:00
akwizgran
a9b412be40 Slightly less minimal .gitlab-ci.yml 2018-08-20 11:56:45 +01:00
akwizgran
413360db09 Minimal .gitlab-ci.yml for debugging. 2018-08-20 11:56:45 +01:00
1035 changed files with 16870 additions and 27982 deletions

View File

@@ -36,9 +36,6 @@
<option name="JD_ALIGN_PARAM_COMMENTS" value="false" /> <option name="JD_ALIGN_PARAM_COMMENTS" value="false" />
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" /> <option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" />
</JavaCodeStyleSettings> </JavaCodeStyleSettings>
<JetCodeStyleSettings>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<Objective-C-extensions> <Objective-C-extensions>
<file> <file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" /> <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
@@ -260,11 +257,5 @@
</rules> </rules>
</arrangement> </arrangement>
</codeStyleSettings> </codeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
<option name="PARAMETER_ANNOTATION_WRAP" value="1" />
<option name="VARIABLE_ANNOTATION_WRAP" value="1" />
<option name="ENUM_CONSTANTS_WRAP" value="1" />
</codeStyleSettings>
</code_scheme> </code_scheme>
</component> </component>

View File

@@ -1,20 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All in briar-headless" type="AndroidJUnit" factoryName="Android JUnit" nameIsGenerated="true">
<module name="briar-headless" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="PACKAGE_NAME" value="org.briarproject.briar.headless" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="package" />
<option name="VM_PARAMETERS" value="" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/briar-headless" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<patterns />
<method />
</configuration>
</component>

View File

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

View File

@@ -1,5 +1,6 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="All tests in bramble-android" type="AndroidJUnit" factoryName="Android JUnit"> <configuration default="false" name="All tests in bramble-android" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="bramble-android" /> <module name="bramble-android" />
<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" />
@@ -10,10 +11,12 @@
<option name="VM_PARAMETERS" value="-ea" /> <option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" value="" /> <option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/bramble-android" /> <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/bramble-android" />
<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">
<value defaultName="singleModule" /> <value defaultName="singleModule" />
</option> </option>
<envs />
<patterns /> <patterns />
<method /> <method />
</configuration> </configuration>

View File

@@ -1,5 +1,6 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="All tests in bramble-api" type="AndroidJUnit" factoryName="Android JUnit"> <configuration default="false" name="All tests in bramble-api" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="bramble-api" /> <module name="bramble-api" />
<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" />
@@ -10,10 +11,12 @@
<option name="VM_PARAMETERS" value="-ea" /> <option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" value="" /> <option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/bramble-api" /> <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/bramble-api" />
<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">
<value defaultName="singleModule" /> <value defaultName="singleModule" />
</option> </option>
<envs />
<patterns /> <patterns />
<method /> <method />
</configuration> </configuration>

View File

@@ -1,5 +1,6 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="All tests in bramble-core" type="AndroidJUnit" factoryName="Android JUnit"> <configuration default="false" name="All tests in bramble-core" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="bramble-core" /> <module name="bramble-core" />
<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" />
@@ -10,10 +11,12 @@
<option name="VM_PARAMETERS" value="-ea" /> <option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" value="" /> <option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/bramble-core" /> <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/bramble-core" />
<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">
<value defaultName="singleModule" /> <value defaultName="singleModule" />
</option> </option>
<envs />
<patterns /> <patterns />
<method /> <method />
</configuration> </configuration>

View File

@@ -1,6 +1,7 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="All tests in bramble-java" type="AndroidJUnit" factoryName="Android JUnit"> <configuration default="false" name="All tests in bramble-j2se" type="AndroidJUnit" factoryName="Android JUnit">
<module name="bramble-java" /> <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="bramble-j2se" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" /> <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" /> <option name="ALTERNATIVE_JRE_PATH" />
<option name="PACKAGE_NAME" value="" /> <option name="PACKAGE_NAME" value="" />
@@ -9,11 +10,13 @@
<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-java" /> <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/bramble-j2se" />
<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">
<value defaultName="singleModule" /> <value defaultName="singleModule" />
</option> </option>
<envs />
<patterns /> <patterns />
<method /> <method />
</configuration> </configuration>

View File

@@ -1,5 +1,6 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="All tests in briar-android" type="AndroidJUnit" factoryName="Android JUnit"> <configuration default="false" name="All tests in briar-android" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="briar-android" /> <module name="briar-android" />
<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" />
@@ -10,10 +11,12 @@
<option name="VM_PARAMETERS" value="-ea" /> <option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" value="" /> <option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/briar-android" /> <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/briar-android" />
<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">
<value defaultName="singleModule" /> <value defaultName="singleModule" />
</option> </option>
<envs />
<patterns /> <patterns />
<method /> <method />
</configuration> </configuration>

View File

@@ -1,5 +1,6 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="All tests in briar-core" type="AndroidJUnit" factoryName="Android JUnit"> <configuration default="false" name="All tests in briar-core" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="briar-core" /> <module name="briar-core" />
<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" />
@@ -10,10 +11,12 @@
<option name="VM_PARAMETERS" value="-ea" /> <option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" value="" /> <option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/briar-core" /> <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/briar-core" />
<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">
<value defaultName="singleModule" /> <value defaultName="singleModule" />
</option> </option>
<envs />
<patterns /> <patterns />
<method /> <method />
</configuration> </configuration>

View File

@@ -1,5 +1,6 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="H2 Performance Test" type="AndroidJUnit" factoryName="Android JUnit"> <configuration default="false" name="H2 Performance Test" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="bramble-core" /> <module name="bramble-core" />
<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" />
@@ -10,10 +11,12 @@
<option name="VM_PARAMETERS" value="-ea" /> <option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" value="" /> <option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="" /> <option name="WORKING_DIRECTORY" value="" />
<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">
<value defaultName="singleModule" /> <value defaultName="singleModule" />
</option> </option>
<envs />
<patterns /> <patterns />
<method /> <method />
</configuration> </configuration>

View File

@@ -1,5 +1,6 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="HyperSQL Performance Test" type="AndroidJUnit" factoryName="Android JUnit"> <configuration default="false" name="HyperSQL Performance Test" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="bramble-core" /> <module name="bramble-core" />
<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" />
@@ -10,10 +11,12 @@
<option name="VM_PARAMETERS" value="-ea" /> <option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" value="" /> <option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="" /> <option name="WORKING_DIRECTORY" value="" />
<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">
<value defaultName="singleModule" /> <value defaultName="singleModule" />
</option> </option>
<envs />
<patterns /> <patterns />
<method /> <method />
</configuration> </configuration>

View File

@@ -1,17 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="briar-headless" type="JetRunConfigurationType" factoryName="Kotlin" singleton="true">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<option name="VM_PARAMETERS" value="" />
<option name="PROGRAM_PARAMETERS" value="-v" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="MAIN_CLASS_NAME" value="org.briarproject.briar.headless.MainKt" />
<option name="WORKING_DIRECTORY" value="" />
<module name="briar-headless" />
<envs />
<method>
<option name="Gradle.BeforeRunTask" enabled="true" tasks="jar" externalProjectPath="$PROJECT_DIR$/briar-headless" vmOptions="" scriptParameters="" />
</method>
</configuration>
</component>

View File

@@ -1,18 +1,16 @@
import com.android.build.gradle.tasks.MergeResources
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
apply plugin: 'witness' apply plugin: 'witness'
apply from: 'witness.gradle' apply from: 'witness.gradle'
android { android {
compileSdkVersion 28 compileSdkVersion 27
buildToolsVersion '28.0.3' buildToolsVersion '27.0.3'
defaultConfig { defaultConfig {
minSdkVersion 14 minSdkVersion 14
targetSdkVersion 26 targetSdkVersion 26
versionCode 10105 versionCode 10013
versionName "1.1.5" versionName "1.0.13"
consumerProguardFiles 'proguard-rules.txt' consumerProguardFiles 'proguard-rules.txt'
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
@@ -30,10 +28,9 @@ configurations {
dependencies { dependencies {
implementation project(path: ':bramble-core', configuration: 'default') implementation project(path: ':bramble-core', configuration: 'default')
tor 'org.briarproject:tor-android:0.3.4.8@zip' tor 'org.briarproject:tor-android:0.2.9.16@zip'
tor 'org.briarproject:obfs4proxy-android:0.0.7@zip'
annotationProcessor 'com.google.dagger:dagger-compiler:2.19' annotationProcessor 'com.google.dagger:dagger-compiler:2.0.2'
compileOnly 'javax.annotation:jsr250-api:1.0' compileOnly 'javax.annotation:jsr250-api:1.0'
@@ -42,29 +39,24 @@ dependencies {
testImplementation "org.jmock:jmock:2.8.2" testImplementation "org.jmock:jmock:2.8.2"
testImplementation "org.jmock:jmock-junit4:2.8.2" testImplementation "org.jmock:jmock-junit4:2.8.2"
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-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'
} }
def torBinariesDir = 'src/main/res/raw' project.afterEvaluate {
task cleanTorBinaries {
doLast {
delete fileTree(torBinariesDir) { include '*.zip' }
}
}
clean.dependsOn cleanTorBinaries
task unpackTorBinaries {
doLast {
copy { copy {
from configurations.tor.collect { zipTree(it) } from configurations.tor.collect { zipTree(it) }
into torBinariesDir into 'src/main/res/raw'
} }
}
dependsOn cleanTorBinaries
} }
tasks.withType(MergeResources) { tasks.withType(Test) {
inputs.dir torBinariesDir // Use entropy-gathering device specified on command line, if any
dependsOn unpackTorBinaries systemProperty 'java.security.egd', System.getProperty('java.security.egd')
} }

View File

@@ -1,6 +1,8 @@
package org.briarproject.bramble.plugin.tor; package org.briarproject.bramble.plugin.tor;
import org.briarproject.bramble.api.battery.BatteryManager; 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;
@@ -8,49 +10,38 @@ 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.BrambleJavaIntegrationTestComponent; import org.briarproject.bramble.test.BrambleAndroidIntegrationTestComponent;
import org.briarproject.bramble.test.BrambleTestCase; import org.briarproject.bramble.test.BrambleTestCase;
import org.briarproject.bramble.test.DaggerBrambleJavaIntegrationTestComponent; import org.briarproject.bramble.test.DaggerBrambleAndroidIntegrationTestComponent;
import org.briarproject.bramble.util.OsUtils;
import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
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 java.util.logging.Logger.getLogger;
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.fail; import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
@RunWith(Parameterized.class)
@RunWith(AndroidJUnit4.class)
public class BridgeTest extends BrambleTestCase { public class BridgeTest extends BrambleTestCase {
@Parameters private final static long TIMEOUT = SECONDS.toMillis(23);
public static Iterable<String> data() {
BrambleJavaIntegrationTestComponent component =
DaggerBrambleJavaIntegrationTestComponent.builder().build();
return component.getCircumventionProvider().getBridges();
}
private final static Logger LOG = getLogger(BridgeTest.class.getName()); private final static Logger LOG =
Logger.getLogger(BridgeTest.class.getName());
private final static long TIMEOUT = SECONDS.toMillis(30);
@Inject @Inject
NetworkManager networkManager; NetworkManager networkManager;
@@ -59,39 +50,32 @@ public class BridgeTest extends BrambleTestCase {
@Inject @Inject
CircumventionProvider circumventionProvider; CircumventionProvider circumventionProvider;
@Inject @Inject
BatteryManager batteryManager;
@Inject
EventBus eventBus; EventBus eventBus;
@Inject @Inject
BackoffFactory backoffFactory; BackoffFactory backoffFactory;
@Inject @Inject
Clock clock; Clock clock;
private final File torDir = getTestDirectory(); private final Context appContext =
private final String bridge; getTargetContext().getApplicationContext();
private UnixTorPluginFactory factory; private List<String> bridges;
private AndroidTorPluginFactory factory;
public BridgeTest(String bridge) { private volatile String currentBridge = null;
this.bridge = bridge;
}
@Before @Before
public void setUp() { public void setUp() {
// Skip this test unless it's explicitly enabled in the environment BrambleAndroidIntegrationTestComponent component =
assumeTrue(isOptionalTestEnabled(BridgeTest.class)); DaggerBrambleAndroidIntegrationTestComponent.builder().build();
// TODO: Remove this assumption when the plugin supports other platforms
assumeTrue(OsUtils.isLinux());
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();
bridges = circumventionProvider.getBridges();
CircumventionProvider bridgeProvider = new CircumventionProvider() { CircumventionProvider bridgeProvider = new CircumventionProvider() {
@Override @Override
public boolean isTorProbablyBlocked(String countryCode) { public boolean isTorProbablyBlocked(String countryCode) {
@@ -105,27 +89,28 @@ public class BridgeTest extends BrambleTestCase {
@Override @Override
public List<String> getBridges() { public List<String> getBridges() {
return singletonList(bridge); return singletonList(currentBridge);
} }
}; };
factory = new UnixTorPluginFactory(ioExecutor, networkManager, factory = new AndroidTorPluginFactory(ioExecutor, scheduler, appContext,
locationUtils, eventBus, torSocketFactory, backoffFactory, networkManager, locationUtils, eventBus, torSocketFactory,
resourceProvider, bridgeProvider, batteryManager, clock, backoffFactory, resourceProvider, bridgeProvider, clock);
torDir);
}
@After
public void tearDown() {
deleteTestDirectory(torDir);
} }
@Test @Test
public void testBridges() throws Exception { public void testBridges() throws Exception {
assertTrue(bridges.size() > 0);
for (String bridge : bridges) testBridge(bridge);
}
private void testBridge(String bridge) throws Exception {
DuplexPlugin duplexPlugin = DuplexPlugin duplexPlugin =
factory.createPlugin(new TorPluginCallBack()); factory.createPlugin(new TorPluginCallBack());
assertNotNull(duplexPlugin); assertNotNull(duplexPlugin);
UnixTorPlugin plugin = (UnixTorPlugin) duplexPlugin; AndroidTorPlugin plugin = (AndroidTorPlugin) duplexPlugin;
currentBridge = bridge;
LOG.warning("Testing " + bridge); LOG.warning("Testing " + bridge);
try { try {
plugin.start(); plugin.start();

View File

@@ -0,0 +1,20 @@
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

@@ -1,11 +1,9 @@
package org.briarproject.bramble.test; package org.briarproject.bramble.test;
import org.briarproject.bramble.BrambleJavaModule; import org.briarproject.bramble.BrambleAndroidModule;
import org.briarproject.bramble.battery.DefaultBatteryManagerModule;
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;
import org.briarproject.bramble.plugin.tor.CircumventionProvider;
import org.briarproject.bramble.system.SystemModule; import org.briarproject.bramble.system.SystemModule;
import javax.inject.Singleton; import javax.inject.Singleton;
@@ -14,16 +12,15 @@ import dagger.Component;
@Singleton @Singleton
@Component(modules = { @Component(modules = {
BrambleJavaModule.class, BrambleAndroidModule.class,
TestLifecycleModule.class, TestLifecycleModule.class,
DefaultBatteryManagerModule.class, ApplicationModule.class,
PluginModule.class, // needed for BackoffFactory PluginModule.class, // needed for BackoffFactory
EventModule.class, EventModule.class,
SystemModule.class, SystemModule.class,
}) })
public interface BrambleJavaIntegrationTestComponent { public interface BrambleAndroidIntegrationTestComponent {
void inject(BridgeTest init); void inject(BridgeTest init);
CircumventionProvider getCircumventionProvider();
} }

View File

@@ -1,11 +0,0 @@
package org.briarproject.bramble;
import org.briarproject.bramble.battery.AndroidBatteryModule;
import org.briarproject.bramble.network.AndroidNetworkModule;
public interface BrambleAndroidEagerSingletons {
void inject(AndroidBatteryModule.EagerSingletons init);
void inject(AndroidNetworkModule.EagerSingletons init);
}

View File

@@ -1,6 +1,5 @@
package org.briarproject.bramble; package org.briarproject.bramble;
import org.briarproject.bramble.battery.AndroidBatteryModule;
import org.briarproject.bramble.network.AndroidNetworkModule; import org.briarproject.bramble.network.AndroidNetworkModule;
import org.briarproject.bramble.plugin.tor.CircumventionModule; import org.briarproject.bramble.plugin.tor.CircumventionModule;
import org.briarproject.bramble.system.AndroidSystemModule; import org.briarproject.bramble.system.AndroidSystemModule;
@@ -8,15 +7,10 @@ import org.briarproject.bramble.system.AndroidSystemModule;
import dagger.Module; import dagger.Module;
@Module(includes = { @Module(includes = {
AndroidBatteryModule.class,
AndroidNetworkModule.class, AndroidNetworkModule.class,
AndroidSystemModule.class, AndroidSystemModule.class,
CircumventionModule.class CircumventionModule.class
}) })
public class BrambleAndroidModule { public class BrambleAndroidModule {
public static void initEagerSingletons(BrambleAndroidEagerSingletons c) {
c.inject(new AndroidBatteryModule.EagerSingletons());
c.inject(new AndroidNetworkModule.EagerSingletons());
}
} }

View File

@@ -9,22 +9,19 @@ import org.briarproject.bramble.api.account.AccountManager;
import org.briarproject.bramble.api.crypto.CryptoComponent; import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.db.DatabaseConfig; import org.briarproject.bramble.api.db.DatabaseConfig;
import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.util.IoUtils;
import java.io.File; import java.io.File;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;
import javax.inject.Inject; import javax.inject.Inject;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.IoUtils.deleteFileOrDir;
class AndroidAccountManager extends AccountManagerImpl class AndroidAccountManager extends AccountManagerImpl
implements AccountManager { implements AccountManager {
private static final Logger LOG = private static final Logger LOG =
getLogger(AndroidAccountManager.class.getName()); Logger.getLogger(AndroidAccountManager.class.getName());
private static final String PREF_DB_KEY = "key"; private static final String PREF_DB_KEY = "key";
@@ -40,7 +37,7 @@ class AndroidAccountManager extends AccountManagerImpl
appContext = app.getApplicationContext(); appContext = app.getApplicationContext();
} }
@GuardedBy("stateChangeLock") // Locking: stateChangeLock
@Override @Override
@Nullable @Nullable
protected String loadEncryptedDatabaseKey() { protected String loadEncryptedDatabaseKey() {
@@ -50,7 +47,7 @@ class AndroidAccountManager extends AccountManagerImpl
return key; return key;
} }
@GuardedBy("stateChangeLock") // Locking: stateChangeLock
@Nullable @Nullable
private String getDatabaseKeyFromPreferences() { private String getDatabaseKeyFromPreferences() {
String key = prefs.getString(PREF_DB_KEY, null); String key = prefs.getString(PREF_DB_KEY, null);
@@ -59,7 +56,7 @@ class AndroidAccountManager extends AccountManagerImpl
return key; return key;
} }
@GuardedBy("stateChangeLock") // Locking: stateChangeLock
private void migrateDatabaseKeyToFile(String key) { private void migrateDatabaseKeyToFile(String key) {
if (storeEncryptedDatabaseKey(key)) { if (storeEncryptedDatabaseKey(key)) {
if (prefs.edit().remove(PREF_DB_KEY).commit()) if (prefs.edit().remove(PREF_DB_KEY).commit())
@@ -84,7 +81,7 @@ class AndroidAccountManager extends AccountManagerImpl
return PreferenceManager.getDefaultSharedPreferences(appContext); return PreferenceManager.getDefaultSharedPreferences(appContext);
} }
@GuardedBy("stateChangeLock") // Locking: stateChangeLock
private void deleteAppData(SharedPreferences... clear) { private void deleteAppData(SharedPreferences... clear) {
// Clear and commit shared preferences // Clear and commit shared preferences
for (SharedPreferences prefs : clear) { for (SharedPreferences prefs : clear) {
@@ -100,7 +97,7 @@ class AndroidAccountManager extends AccountManagerImpl
for (File child : children) { for (File child : children) {
String name = child.getName(); String name = child.getName();
if (!name.equals("lib") && !name.equals("shared_prefs")) { if (!name.equals("lib") && !name.equals("shared_prefs")) {
deleteFileOrDir(child); IoUtils.deleteFileOrDir(child);
} }
} }
} }

View File

@@ -1,81 +0,0 @@
package org.briarproject.bramble.battery;
import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import org.briarproject.bramble.api.battery.BatteryManager;
import org.briarproject.bramble.api.battery.event.BatteryEvent;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.lifecycle.Service;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Logger;
import javax.inject.Inject;
import static android.content.Intent.ACTION_BATTERY_CHANGED;
import static android.content.Intent.ACTION_POWER_CONNECTED;
import static android.content.Intent.ACTION_POWER_DISCONNECTED;
import static android.os.BatteryManager.EXTRA_PLUGGED;
import static java.util.logging.Level.INFO;
import static java.util.logging.Logger.getLogger;
class AndroidBatteryManager implements BatteryManager, Service {
private static final Logger LOG =
getLogger(AndroidBatteryManager.class.getName());
private final Context appContext;
private final EventBus eventBus;
private final AtomicBoolean used = new AtomicBoolean(false);
private volatile BroadcastReceiver batteryReceiver = null;
@Inject
AndroidBatteryManager(Application app, EventBus eventBus) {
this.appContext = app.getApplicationContext();
this.eventBus = eventBus;
}
@Override
public boolean isCharging() {
// Get the sticky intent for ACTION_BATTERY_CHANGED
IntentFilter filter = new IntentFilter(ACTION_BATTERY_CHANGED);
Intent i = appContext.registerReceiver(null, filter);
if (i == null) return false;
int status = i.getIntExtra(EXTRA_PLUGGED, 0);
return status != 0;
}
@Override
public void startService() {
if (used.getAndSet(true)) throw new IllegalStateException();
batteryReceiver = new BatteryReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_POWER_CONNECTED);
filter.addAction(ACTION_POWER_DISCONNECTED);
appContext.registerReceiver(batteryReceiver, filter);
}
@Override
public void stopService() {
if (batteryReceiver != null)
appContext.unregisterReceiver(batteryReceiver);
}
private class BatteryReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context ctx, Intent i) {
String action = i.getAction();
if (LOG.isLoggable(INFO)) LOG.info("Received broadcast " + action);
if (ACTION_POWER_CONNECTED.equals(action))
eventBus.broadcast(new BatteryEvent(true));
else if (ACTION_POWER_DISCONNECTED.equals(action))
eventBus.broadcast(new BatteryEvent(false));
}
}
}

View File

@@ -1,27 +0,0 @@
package org.briarproject.bramble.battery;
import org.briarproject.bramble.api.battery.BatteryManager;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import javax.inject.Inject;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
@Module
public class AndroidBatteryModule {
public static class EagerSingletons {
@Inject
BatteryManager batteryManager;
}
@Provides
@Singleton
BatteryManager provideBatteryManager(LifecycleManager lifecycleManager,
AndroidBatteryManager batteryManager) {
lifecycleManager.registerService(batteryManager);
return batteryManager;
}
}

View File

@@ -13,7 +13,8 @@ import org.briarproject.bramble.api.lifecycle.Service;
import org.briarproject.bramble.api.network.NetworkManager; import org.briarproject.bramble.api.network.NetworkManager;
import org.briarproject.bramble.api.network.NetworkStatus; import org.briarproject.bramble.api.network.NetworkStatus;
import org.briarproject.bramble.api.network.event.NetworkStatusEvent; import org.briarproject.bramble.api.network.event.NetworkStatusEvent;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.bramble.api.system.Scheduler; import org.briarproject.bramble.api.system.Scheduler;
import java.util.concurrent.Future; import java.util.concurrent.Future;
@@ -33,17 +34,16 @@ import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.os.Build.VERSION.SDK_INT; import static android.os.Build.VERSION.SDK_INT;
import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED; import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED;
import static java.util.Objects.requireNonNull;
import static java.util.concurrent.TimeUnit.MINUTES; import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS; import static java.util.concurrent.TimeUnit.SECONDS;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static java.util.logging.Logger.getLogger;
@NotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault
class AndroidNetworkManager implements NetworkManager, Service { class AndroidNetworkManager implements NetworkManager, Service {
private static final Logger LOG = private static final Logger LOG =
getLogger(AndroidNetworkManager.class.getName()); Logger.getLogger(AndroidNetworkManager.class.getName());
// See android.net.wifi.WifiManager // See android.net.wifi.WifiManager
private static final String WIFI_AP_STATE_CHANGED_ACTION = private static final String WIFI_AP_STATE_CHANGED_ACTION =
@@ -56,7 +56,6 @@ class AndroidNetworkManager implements NetworkManager, Service {
new AtomicReference<>(); new AtomicReference<>();
private final AtomicBoolean used = new AtomicBoolean(false); private final AtomicBoolean used = new AtomicBoolean(false);
@Nullable
private volatile BroadcastReceiver networkStateReceiver = null; private volatile BroadcastReceiver networkStateReceiver = null;
@Inject @Inject
@@ -90,8 +89,9 @@ class AndroidNetworkManager implements NetworkManager, Service {
@Override @Override
public NetworkStatus getNetworkStatus() { public NetworkStatus getNetworkStatus() {
ConnectivityManager cm = (ConnectivityManager) requireNonNull( ConnectivityManager cm = (ConnectivityManager)
appContext.getSystemService(CONNECTIVITY_SERVICE)); appContext.getSystemService(CONNECTIVITY_SERVICE);
if (cm == null) throw new AssertionError();
NetworkInfo net = cm.getActiveNetworkInfo(); NetworkInfo net = cm.getActiveNetworkInfo();
boolean connected = net != null && net.isConnected(); boolean connected = net != null && net.isConnected();
boolean wifi = connected && net.getType() == TYPE_WIFI; boolean wifi = connected && net.getType() == TYPE_WIFI;

View File

@@ -3,7 +3,6 @@ package org.briarproject.bramble.network;
import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.network.NetworkManager; import org.briarproject.bramble.api.network.NetworkManager;
import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import dagger.Module; import dagger.Module;
@@ -12,11 +11,6 @@ import dagger.Provides;
@Module @Module
public class AndroidNetworkModule { public class AndroidNetworkModule {
public static class EagerSingletons {
@Inject
NetworkManager networkManager;
}
@Provides @Provides
@Singleton @Singleton
NetworkManager provideNetworkManager(LifecycleManager lifecycleManager, NetworkManager provideNetworkManager(LifecycleManager lifecycleManager,

View File

@@ -16,26 +16,18 @@ import org.briarproject.bramble.api.plugin.PluginException;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
import org.briarproject.bramble.api.system.AndroidExecutor; import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.util.AndroidUtils; import org.briarproject.bramble.util.AndroidUtils;
import org.briarproject.bramble.util.IoUtils;
import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static android.bluetooth.BluetoothAdapter.ACTION_DISCOVERY_FINISHED;
import static android.bluetooth.BluetoothAdapter.ACTION_DISCOVERY_STARTED;
import static android.bluetooth.BluetoothAdapter.ACTION_SCAN_MODE_CHANGED; import static android.bluetooth.BluetoothAdapter.ACTION_SCAN_MODE_CHANGED;
import static android.bluetooth.BluetoothAdapter.ACTION_STATE_CHANGED; import static android.bluetooth.BluetoothAdapter.ACTION_STATE_CHANGED;
import static android.bluetooth.BluetoothAdapter.EXTRA_SCAN_MODE; import static android.bluetooth.BluetoothAdapter.EXTRA_SCAN_MODE;
@@ -45,27 +37,18 @@ import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERA
import static android.bluetooth.BluetoothAdapter.SCAN_MODE_NONE; import static android.bluetooth.BluetoothAdapter.SCAN_MODE_NONE;
import static android.bluetooth.BluetoothAdapter.STATE_OFF; import static android.bluetooth.BluetoothAdapter.STATE_OFF;
import static android.bluetooth.BluetoothAdapter.STATE_ON; import static android.bluetooth.BluetoothAdapter.STATE_ON;
import static android.bluetooth.BluetoothDevice.ACTION_FOUND;
import static android.bluetooth.BluetoothDevice.EXTRA_DEVICE;
import static java.util.Collections.shuffle;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> { class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
private static final Logger LOG = private static final Logger LOG =
getLogger(AndroidBluetoothPlugin.class.getName()); Logger.getLogger(AndroidBluetoothPlugin.class.getName());
private static final int MAX_DISCOVERY_MS = 10_000;
private final AndroidExecutor androidExecutor; private final AndroidExecutor androidExecutor;
private final Context appContext; private final Context appContext;
private final Clock clock;
private volatile boolean wasEnabledByUs = false; private volatile boolean wasEnabledByUs = false;
private volatile BluetoothStateReceiver receiver = null; private volatile BluetoothStateReceiver receiver = null;
@@ -75,13 +58,12 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
AndroidBluetoothPlugin(BluetoothConnectionLimiter connectionLimiter, AndroidBluetoothPlugin(BluetoothConnectionLimiter connectionLimiter,
Executor ioExecutor, AndroidExecutor androidExecutor, Executor ioExecutor, AndroidExecutor androidExecutor,
Context appContext, SecureRandom secureRandom, Clock clock, Context appContext, SecureRandom secureRandom, Backoff backoff,
Backoff backoff, DuplexPluginCallback callback, int maxLatency) { DuplexPluginCallback callback, int maxLatency) {
super(connectionLimiter, ioExecutor, secureRandom, backoff, callback, super(connectionLimiter, ioExecutor, secureRandom, backoff, callback,
maxLatency); maxLatency);
this.androidExecutor = androidExecutor; this.androidExecutor = androidExecutor;
this.appContext = appContext; this.appContext = appContext;
this.clock = clock;
} }
@Override @Override
@@ -161,7 +143,11 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
@Override @Override
void tryToClose(@Nullable BluetoothServerSocket ss) { void tryToClose(@Nullable BluetoothServerSocket ss) {
IoUtils.tryToClose(ss, LOG, WARNING); try {
if (ss != null) ss.close();
} catch (IOException e) {
logException(LOG, WARNING, e);
}
} }
@Override @Override
@@ -191,78 +177,18 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
s.connect(); s.connect();
return wrapSocket(s); return wrapSocket(s);
} catch (IOException e) { } catch (IOException e) {
IoUtils.tryToClose(s, LOG, WARNING); tryToClose(s);
throw e; throw e;
} }
} }
@Override private void tryToClose(@Nullable Closeable c) {
@Nullable
DuplexTransportConnection discoverAndConnect(String uuid) {
if (adapter == null) return null;
for (String address : discoverDevices()) {
try { try {
if (LOG.isLoggable(INFO)) if (c != null) c.close();
LOG.info("Connecting to " + scrubMacAddress(address));
return connectTo(address, uuid);
} catch (IOException e) { } catch (IOException e) {
if (LOG.isLoggable(INFO)) { logException(LOG, WARNING, e);
LOG.info("Could not connect to "
+ scrubMacAddress(address));
} }
} }
}
LOG.info("Could not connect to any devices");
return null;
}
private Collection<String> discoverDevices() {
List<String> addresses = new ArrayList<>();
BlockingQueue<Intent> intents = new LinkedBlockingQueue<>();
DiscoveryReceiver receiver = new DiscoveryReceiver(intents);
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_DISCOVERY_STARTED);
filter.addAction(ACTION_DISCOVERY_FINISHED);
filter.addAction(ACTION_FOUND);
appContext.registerReceiver(receiver, filter);
try {
if (adapter.startDiscovery()) {
long now = clock.currentTimeMillis();
long end = now + MAX_DISCOVERY_MS;
while (now < end) {
Intent i = intents.poll(end - now, MILLISECONDS);
if (i == null) break;
String action = i.getAction();
if (ACTION_DISCOVERY_STARTED.equals(action)) {
LOG.info("Discovery started");
} else if (ACTION_DISCOVERY_FINISHED.equals(action)) {
LOG.info("Discovery finished");
break;
} else if (ACTION_FOUND.equals(action)) {
BluetoothDevice d = i.getParcelableExtra(EXTRA_DEVICE);
String address = d.getAddress();
if (LOG.isLoggable(INFO))
LOG.info("Discovered " + scrubMacAddress(address));
if (!addresses.contains(address))
addresses.add(address);
}
now = clock.currentTimeMillis();
}
} else {
LOG.info("Could not start discovery");
}
} catch (InterruptedException e) {
LOG.info("Interrupted while discovering devices");
Thread.currentThread().interrupt();
} finally {
LOG.info("Cancelling discovery");
adapter.cancelDiscovery();
appContext.unregisterReceiver(receiver);
}
// Shuffle the addresses so we don't always try the same one first
shuffle(addresses);
return addresses;
}
private class BluetoothStateReceiver extends BroadcastReceiver { private class BluetoothStateReceiver extends BroadcastReceiver {
@@ -281,18 +207,4 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
} }
} }
} }
private static class DiscoveryReceiver extends BroadcastReceiver {
private final BlockingQueue<Intent> intents;
private DiscoveryReceiver(BlockingQueue<Intent> intents) {
this.intents = intents;
}
@Override
public void onReceive(Context ctx, Intent intent) {
intents.add(intent);
}
}
} }

View File

@@ -11,7 +11,6 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory; import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory;
import org.briarproject.bramble.api.system.AndroidExecutor; import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.bramble.api.system.Clock;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
@@ -34,19 +33,17 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
private final Context appContext; private final Context appContext;
private final SecureRandom secureRandom; private final SecureRandom secureRandom;
private final EventBus eventBus; private final EventBus eventBus;
private final Clock clock;
private final BackoffFactory backoffFactory; private final BackoffFactory backoffFactory;
public AndroidBluetoothPluginFactory(Executor ioExecutor, public AndroidBluetoothPluginFactory(Executor ioExecutor,
AndroidExecutor androidExecutor, Context appContext, AndroidExecutor androidExecutor, Context appContext,
SecureRandom secureRandom, EventBus eventBus, Clock clock, SecureRandom secureRandom, EventBus eventBus,
BackoffFactory backoffFactory) { BackoffFactory backoffFactory) {
this.ioExecutor = ioExecutor; this.ioExecutor = ioExecutor;
this.androidExecutor = androidExecutor; this.androidExecutor = androidExecutor;
this.appContext = appContext; this.appContext = appContext;
this.secureRandom = secureRandom; this.secureRandom = secureRandom;
this.eventBus = eventBus; this.eventBus = eventBus;
this.clock = clock;
this.backoffFactory = backoffFactory; this.backoffFactory = backoffFactory;
} }
@@ -68,7 +65,7 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
MAX_POLLING_INTERVAL, BACKOFF_BASE); MAX_POLLING_INTERVAL, BACKOFF_BASE);
AndroidBluetoothPlugin plugin = new AndroidBluetoothPlugin( AndroidBluetoothPlugin plugin = new AndroidBluetoothPlugin(
connectionLimiter, ioExecutor, androidExecutor, appContext, connectionLimiter, ioExecutor, androidExecutor, appContext,
secureRandom, clock, backoff, callback, MAX_LATENCY); secureRandom, backoff, callback, MAX_LATENCY);
eventBus.addListener(plugin); eventBus.addListener(plugin);
return plugin; return plugin;
} }

View File

@@ -32,19 +32,17 @@ import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.os.Build.VERSION.SDK_INT; import static android.os.Build.VERSION.SDK_INT;
import static java.util.Collections.emptyList; import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
import static java.util.Objects.requireNonNull;
import static java.util.logging.Logger.getLogger;
@NotNullByDefault @NotNullByDefault
class AndroidLanTcpPlugin extends LanTcpPlugin implements EventListener { class AndroidLanTcpPlugin extends LanTcpPlugin implements EventListener {
private static final Logger LOG =
getLogger(AndroidLanTcpPlugin.class.getName());
private static final byte[] WIFI_AP_ADDRESS_BYTES = private static final byte[] WIFI_AP_ADDRESS_BYTES =
{(byte) 192, (byte) 168, 43, 1}; {(byte) 192, (byte) 168, 43, 1};
private static final InetAddress WIFI_AP_ADDRESS; private static final InetAddress WIFI_AP_ADDRESS;
private static final Logger LOG =
Logger.getLogger(AndroidLanTcpPlugin.class.getName());
static { static {
try { try {
WIFI_AP_ADDRESS = InetAddress.getByAddress(WIFI_AP_ADDRESS_BYTES); WIFI_AP_ADDRESS = InetAddress.getByAddress(WIFI_AP_ADDRESS_BYTES);
@@ -68,8 +66,10 @@ class AndroidLanTcpPlugin extends LanTcpPlugin implements EventListener {
// Don't execute more than one connection status check at a time // Don't execute more than one connection status check at a time
connectionStatusExecutor = connectionStatusExecutor =
new PoliteExecutor("AndroidLanTcpPlugin", ioExecutor, 1); new PoliteExecutor("AndroidLanTcpPlugin", ioExecutor, 1);
connectivityManager = (ConnectivityManager) requireNonNull( ConnectivityManager connectivityManager = (ConnectivityManager)
appContext.getSystemService(CONNECTIVITY_SERVICE)); appContext.getSystemService(CONNECTIVITY_SERVICE);
if (connectivityManager == null) throw new AssertionError();
this.connectivityManager = connectivityManager;
wifiManager = (WifiManager) appContext.getApplicationContext() wifiManager = (WifiManager) appContext.getApplicationContext()
.getSystemService(WIFI_SERVICE); .getSystemService(WIFI_SERVICE);
socketFactory = SocketFactory.getDefault(); socketFactory = SocketFactory.getDefault();

View File

@@ -6,9 +6,9 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManager.NameNotFoundException;
import android.os.PowerManager; import android.os.PowerManager;
import org.briarproject.bramble.api.battery.BatteryManager;
import org.briarproject.bramble.api.network.NetworkManager; import org.briarproject.bramble.api.network.NetworkManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.bramble.api.plugin.Backoff; import org.briarproject.bramble.api.plugin.Backoff;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
@@ -25,10 +25,10 @@ import javax.net.SocketFactory;
import static android.content.Context.MODE_PRIVATE; import static android.content.Context.MODE_PRIVATE;
import static android.content.Context.POWER_SERVICE; import static android.content.Context.POWER_SERVICE;
import static android.os.PowerManager.PARTIAL_WAKE_LOCK; import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
import static java.util.Objects.requireNonNull;
import static java.util.concurrent.TimeUnit.MINUTES; import static java.util.concurrent.TimeUnit.MINUTES;
@NotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault
class AndroidTorPlugin extends TorPlugin { class AndroidTorPlugin extends TorPlugin {
// This tag may prevent Huawei's power manager from killing us // This tag may prevent Huawei's power manager from killing us
@@ -41,17 +41,17 @@ class AndroidTorPlugin extends TorPlugin {
Context appContext, NetworkManager networkManager, Context appContext, NetworkManager networkManager,
LocationUtils locationUtils, SocketFactory torSocketFactory, LocationUtils locationUtils, SocketFactory torSocketFactory,
Clock clock, ResourceProvider resourceProvider, Clock clock, ResourceProvider resourceProvider,
CircumventionProvider circumventionProvider, CircumventionProvider circumventionProvider, Backoff backoff,
BatteryManager batteryManager, Backoff backoff,
DuplexPluginCallback callback, String architecture, int maxLatency, DuplexPluginCallback callback, String architecture, int maxLatency,
int maxIdleTime) { int maxIdleTime) {
super(ioExecutor, networkManager, locationUtils, torSocketFactory, super(ioExecutor, networkManager, locationUtils, torSocketFactory,
clock, resourceProvider, circumventionProvider, batteryManager, clock, resourceProvider, circumventionProvider, backoff,
backoff, callback, architecture, maxLatency, maxIdleTime, callback, architecture, maxLatency, maxIdleTime,
appContext.getDir("tor", MODE_PRIVATE)); appContext.getDir("tor", MODE_PRIVATE));
this.appContext = appContext; this.appContext = appContext;
PowerManager pm = (PowerManager) PowerManager pm = (PowerManager)
requireNonNull(appContext.getSystemService(POWER_SERVICE)); appContext.getSystemService(POWER_SERVICE);
assert pm != null;
wakeLock = new RenewableWakeLock(pm, scheduler, PARTIAL_WAKE_LOCK, wakeLock = new RenewableWakeLock(pm, scheduler, PARTIAL_WAKE_LOCK,
WAKE_LOCK_TAG, 1, MINUTES); WAKE_LOCK_TAG, 1, MINUTES);
} }

View File

@@ -1,8 +1,8 @@
package org.briarproject.bramble.plugin.tor; package org.briarproject.bramble.plugin.tor;
import android.content.Context; import android.content.Context;
import android.os.Build;
import org.briarproject.bramble.api.battery.BatteryManager;
import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.network.NetworkManager; import org.briarproject.bramble.api.network.NetworkManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@@ -25,15 +25,12 @@ import java.util.logging.Logger;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import javax.net.SocketFactory; import javax.net.SocketFactory;
import static android.os.Build.VERSION.SDK_INT;
import static java.util.logging.Logger.getLogger;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
public class AndroidTorPluginFactory implements DuplexPluginFactory { public class AndroidTorPluginFactory implements DuplexPluginFactory {
private static final Logger LOG = private static final Logger LOG =
getLogger(AndroidTorPluginFactory.class.getName()); Logger.getLogger(AndroidTorPluginFactory.class.getName());
private static final int MAX_LATENCY = 30 * 1000; // 30 seconds 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 MAX_IDLE_TIME = 30 * 1000; // 30 seconds
@@ -51,7 +48,6 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
private final BackoffFactory backoffFactory; private final BackoffFactory backoffFactory;
private final ResourceProvider resourceProvider; private final ResourceProvider resourceProvider;
private final CircumventionProvider circumventionProvider; private final CircumventionProvider circumventionProvider;
private final BatteryManager batteryManager;
private final Clock clock; private final Clock clock;
public AndroidTorPluginFactory(Executor ioExecutor, public AndroidTorPluginFactory(Executor ioExecutor,
@@ -59,8 +55,7 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
NetworkManager networkManager, LocationUtils locationUtils, NetworkManager networkManager, LocationUtils locationUtils,
EventBus eventBus, SocketFactory torSocketFactory, EventBus eventBus, SocketFactory torSocketFactory,
BackoffFactory backoffFactory, ResourceProvider resourceProvider, BackoffFactory backoffFactory, ResourceProvider resourceProvider,
CircumventionProvider circumventionProvider, CircumventionProvider circumventionProvider, Clock clock) {
BatteryManager batteryManager, Clock clock) {
this.ioExecutor = ioExecutor; this.ioExecutor = ioExecutor;
this.scheduler = scheduler; this.scheduler = scheduler;
this.appContext = appContext; this.appContext = appContext;
@@ -71,7 +66,6 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
this.backoffFactory = backoffFactory; this.backoffFactory = backoffFactory;
this.resourceProvider = resourceProvider; this.resourceProvider = resourceProvider;
this.circumventionProvider = circumventionProvider; this.circumventionProvider = circumventionProvider;
this.batteryManager = batteryManager;
this.clock = clock; this.clock = clock;
} }
@@ -104,14 +98,14 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
return null; return null;
} }
// Use position-independent executable for SDK >= 16 // Use position-independent executable for SDK >= 16
if (SDK_INT >= 16) architecture += "_pie"; if (Build.VERSION.SDK_INT >= 16) architecture += "_pie";
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL, Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
MAX_POLLING_INTERVAL, BACKOFF_BASE); MAX_POLLING_INTERVAL, BACKOFF_BASE);
AndroidTorPlugin plugin = new AndroidTorPlugin(ioExecutor, scheduler, AndroidTorPlugin plugin = new AndroidTorPlugin(ioExecutor, scheduler,
appContext, networkManager, locationUtils, torSocketFactory, appContext, networkManager, locationUtils, torSocketFactory,
clock, resourceProvider, circumventionProvider, batteryManager, clock, resourceProvider, circumventionProvider, backoff,
backoff, callback, architecture, MAX_LATENCY, MAX_IDLE_TIME); callback, architecture, MAX_LATENCY, MAX_IDLE_TIME);
eventBus.addListener(plugin); eventBus.addListener(plugin);
return plugin; return plugin;
} }

View File

@@ -15,13 +15,12 @@ import java.util.logging.Logger;
import javax.inject.Inject; import javax.inject.Inject;
import static android.content.Context.TELEPHONY_SERVICE; import static android.content.Context.TELEPHONY_SERVICE;
import static java.util.logging.Logger.getLogger;
@NotNullByDefault @NotNullByDefault
class AndroidLocationUtils implements LocationUtils { class AndroidLocationUtils implements LocationUtils {
private static final Logger LOG = private static final Logger LOG =
getLogger(AndroidLocationUtils.class.getName()); Logger.getLogger(AndroidLocationUtils.class.getName());
private final Context appContext; private final Context appContext;
@@ -60,14 +59,14 @@ class AndroidLocationUtils implements LocationUtils {
} }
private String getCountryFromPhoneNetwork() { private String getCountryFromPhoneNetwork() {
TelephonyManager tm = (TelephonyManager) Object o = appContext.getSystemService(TELEPHONY_SERVICE);
appContext.getSystemService(TELEPHONY_SERVICE); TelephonyManager tm = (TelephonyManager) o;
return tm == null ? "" : tm.getNetworkCountryIso(); return tm.getNetworkCountryIso();
} }
private String getCountryFromSimCard() { private String getCountryFromSimCard() {
TelephonyManager tm = (TelephonyManager) Object o = appContext.getSystemService(TELEPHONY_SERVICE);
appContext.getSystemService(TELEPHONY_SERVICE); TelephonyManager tm = (TelephonyManager) o;
return tm == null ? "" : tm.getSimCountryIso(); return tm.getSimCountryIso();
} }
} }

View File

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

View File

@@ -1,6 +1,5 @@
package org.briarproject.bramble.system; package org.briarproject.bramble.system;
import android.annotation.SuppressLint;
import android.app.Application; import android.app.Application;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
@@ -8,6 +7,7 @@ import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager; import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Parcel; import android.os.Parcel;
import android.os.StrictMode; import android.os.StrictMode;
import android.provider.Settings; import android.provider.Settings;
@@ -22,14 +22,11 @@ import javax.annotation.concurrent.Immutable;
import javax.inject.Inject; import javax.inject.Inject;
import static android.content.Context.WIFI_SERVICE; import static android.content.Context.WIFI_SERVICE;
import static android.os.Build.FINGERPRINT;
import static android.os.Build.SERIAL;
import static android.os.Build.VERSION.SDK_INT;
import static android.provider.Settings.Secure.ANDROID_ID; import static android.provider.Settings.Secure.ANDROID_ID;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
class AndroidSecureRandomProvider extends UnixSecureRandomProvider { class AndroidSecureRandomProvider extends LinuxSecureRandomProvider {
private static final int SEED_LENGTH = 32; private static final int SEED_LENGTH = 32;
@@ -40,28 +37,25 @@ class AndroidSecureRandomProvider extends UnixSecureRandomProvider {
appContext = app.getApplicationContext(); appContext = app.getApplicationContext();
} }
@SuppressLint("HardwareIds")
@Override @Override
protected void writeToEntropyPool(DataOutputStream out) throws IOException { protected void writeToEntropyPool(DataOutputStream out) throws IOException {
super.writeToEntropyPool(out); super.writeToEntropyPool(out);
out.writeInt(android.os.Process.myPid()); out.writeInt(android.os.Process.myPid());
out.writeInt(android.os.Process.myTid()); out.writeInt(android.os.Process.myTid());
out.writeInt(android.os.Process.myUid()); out.writeInt(android.os.Process.myUid());
if (FINGERPRINT != null) out.writeUTF(FINGERPRINT); if (Build.FINGERPRINT != null) out.writeUTF(Build.FINGERPRINT);
if (SERIAL != null) out.writeUTF(SERIAL); if (Build.SERIAL != null) out.writeUTF(Build.SERIAL);
ContentResolver contentResolver = appContext.getContentResolver(); ContentResolver contentResolver = appContext.getContentResolver();
String id = Settings.Secure.getString(contentResolver, ANDROID_ID); String id = Settings.Secure.getString(contentResolver, ANDROID_ID);
if (id != null) out.writeUTF(id); if (id != null) out.writeUTF(id);
Parcel parcel = Parcel.obtain(); Parcel parcel = Parcel.obtain();
WifiManager wm = (WifiManager) appContext.getApplicationContext() WifiManager wm =
.getSystemService(WIFI_SERVICE); (WifiManager) appContext.getSystemService(WIFI_SERVICE);
if (wm != null) {
List<WifiConfiguration> configs = wm.getConfiguredNetworks(); List<WifiConfiguration> configs = wm.getConfiguredNetworks();
if (configs != null) { if (configs != null) {
for (WifiConfiguration config : configs) for (WifiConfiguration config : configs)
parcel.writeParcelable(config, 0); parcel.writeParcelable(config, 0);
} }
}
BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter(); BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
if (bt != null) { if (bt != null) {
for (BluetoothDevice device : bt.getBondedDevices()) for (BluetoothDevice device : bt.getBondedDevices())
@@ -76,18 +70,20 @@ class AndroidSecureRandomProvider extends UnixSecureRandomProvider {
// Silence strict mode // Silence strict mode
StrictMode.ThreadPolicy tp = StrictMode.allowThreadDiskWrites(); StrictMode.ThreadPolicy tp = StrictMode.allowThreadDiskWrites();
super.writeSeed(); super.writeSeed();
if (SDK_INT >= 16 && SDK_INT <= 18) applyOpenSslFix(); if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT <= 18)
applyOpenSslFix();
StrictMode.setThreadPolicy(tp); StrictMode.setThreadPolicy(tp);
} }
// Based on https://android-developers.googleblog.com/2013/08/some-securerandom-thoughts.html // Based on https://android-developers.googleblog.com/2013/08/some-securerandom-thoughts.html
private void applyOpenSslFix() { private void applyOpenSslFix() {
byte[] seed = new UnixSecureRandomSpi().engineGenerateSeed(SEED_LENGTH); byte[] seed = new LinuxSecureRandomSpi().engineGenerateSeed(
SEED_LENGTH);
try { try {
// Seed the OpenSSL PRNG // Seed the OpenSSL PRNG
Class.forName("org.apache.harmony.xnet.provider.jsse.NativeCrypto") Class.forName("org.apache.harmony.xnet.provider.jsse.NativeCrypto")
.getMethod("RAND_seed", byte[].class) .getMethod("RAND_seed", byte[].class)
.invoke(null, (Object) seed); .invoke(null, seed);
// Mix the output of the Linux PRNG into the OpenSSL PRNG // Mix the output of the Linux PRNG into the OpenSSL PRNG
int bytesRead = (Integer) Class.forName( int bytesRead = (Integer) Class.forName(
"org.apache.harmony.xnet.provider.jsse.NativeCrypto") "org.apache.harmony.xnet.provider.jsse.NativeCrypto")

View File

@@ -3,35 +3,36 @@ package org.briarproject.bramble.util;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.content.Context; import android.content.Context;
import android.os.Build;
import android.provider.Settings; import android.provider.Settings;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.logging.Logger;
import static android.content.Context.MODE_PRIVATE; import static android.content.Context.MODE_PRIVATE;
import static android.os.Build.CPU_ABI;
import static android.os.Build.CPU_ABI2;
import static android.os.Build.SUPPORTED_ABIS;
import static android.os.Build.VERSION.SDK_INT;
import static java.util.Arrays.asList;
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
public class AndroidUtils { public class AndroidUtils {
private static final Logger LOG =
Logger.getLogger(AndroidUtils.class.getName());
// Fake Bluetooth address returned by BluetoothAdapter on API 23 and later // Fake Bluetooth address returned by BluetoothAdapter on API 23 and later
private static final String FAKE_BLUETOOTH_ADDRESS = "02:00:00:00:00:00"; private static final String FAKE_BLUETOOTH_ADDRESS = "02:00:00:00:00:00";
private static final String STORED_REPORTS = "dev-reports"; private static final String STORED_REPORTS = "dev-reports";
@SuppressWarnings("deprecation")
public static Collection<String> getSupportedArchitectures() { public static Collection<String> getSupportedArchitectures() {
List<String> abis = new ArrayList<>(); List<String> abis = new ArrayList<>();
if (SDK_INT >= 21) { if (Build.VERSION.SDK_INT >= 21) {
abis.addAll(asList(SUPPORTED_ABIS)); abis.addAll(Arrays.asList(Build.SUPPORTED_ABIS));
} else { } else {
abis.add(CPU_ABI); abis.add(Build.CPU_ABI);
if (CPU_ABI2 != null) abis.add(CPU_ABI2); if (Build.CPU_ABI2 != null) abis.add(Build.CPU_ABI2);
} }
return abis; return abis;
} }
@@ -51,7 +52,7 @@ public class AndroidUtils {
} }
private static boolean isValidBluetoothAddress(String address) { private static boolean isValidBluetoothAddress(String address) {
return !isNullOrEmpty(address) return !StringUtils.isNullOrEmpty(address)
&& BluetoothAdapter.checkBluetoothAddress(address) && BluetoothAdapter.checkBluetoothAddress(address)
&& !address.equals(FAKE_BLUETOOTH_ADDRESS); && !address.equals(FAKE_BLUETOOTH_ADDRESS);
} }

View File

@@ -10,19 +10,17 @@ import java.util.concurrent.TimeUnit;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;
import javax.annotation.concurrent.ThreadSafe; import javax.annotation.concurrent.ThreadSafe;
import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static java.util.logging.Logger.getLogger;
@ThreadSafe @ThreadSafe
@NotNullByDefault @NotNullByDefault
public class RenewableWakeLock { public class RenewableWakeLock {
private static final Logger LOG = private static final Logger LOG =
getLogger(RenewableWakeLock.class.getName()); Logger.getLogger(RenewableWakeLock.class.getName());
/** /**
* Automatically release the lock this many milliseconds after it's due * Automatically release the lock this many milliseconds after it's due
@@ -38,12 +36,10 @@ public class RenewableWakeLock {
private final Runnable renewTask; private final Runnable renewTask;
private final Object lock = new Object(); private final Object lock = new Object();
@GuardedBy("lock")
@Nullable @Nullable
private PowerManager.WakeLock wakeLock; private PowerManager.WakeLock wakeLock; // Locking: lock
@GuardedBy("lock")
@Nullable @Nullable
private ScheduledFuture future; private ScheduledFuture future; // Locking: lock
public RenewableWakeLock(PowerManager powerManager, public RenewableWakeLock(PowerManager powerManager,
ScheduledExecutorService scheduler, int levelAndFlags, String tag, ScheduledExecutorService scheduler, int levelAndFlags, String tag,

View File

@@ -0,0 +1,8 @@
Bridge 131.252.210.150:8081 0E858AC201BF0F3FA3C462F64844CBFFC7297A42
Bridge 67.205.189.122:8443 12D64D5D44E20169585E7378580C0D33A872AD98
Bridge 45.32.148.146:8443 0CE016FB2462D8BF179AE71F7D702D09DEAC3F1D
Bridge 148.251.90.59:7510 019F727CA6DCA6CA5C90B55E477B7D87981E75BC
Bridge 195.91.239.8:9001 BA83F62551545655BBEBBFF353A45438D73FD45A
Bridge 185.165.184.217:6429 64CC94BEC51254E4409AD059192833854CCB95F0
Bridge 45.55.1.74:8443 6F18FEFBB0CAECD5ABA755312FCCB34FC11A7AB8
Bridge 95.85.40.163:9001 40057BE9CF76B6C5BDBE713753468BE0A990DE9C

View File

@@ -1,57 +1,53 @@
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.tools.analytics-library:protos:26.2.1:protos-26.2.1.jar:2f371f5b1f551e85ab08be4d6a2873471b3d44afd1ebf6aa3298f3b796bf691f', 'com.android.support.test:monitor:1.0.2:monitor-1.0.2.aar:38ef4fa98a32dc55550ff49bb36a583e178b3a9b830fcb8dcc27bfc4254bc2bc',
'com.android.tools.analytics-library:shared:26.2.1:shared-26.2.1.jar:4c1e4e705fa4d45f23aaea230557f6508155012d9c296337787c1d7b26a97f5a', 'com.android.support.test:runner:1.0.2:runner-1.0.2.aar:f04b9ae342975ba1cb3e4a06e13426e3e6b8a73faa45acba604493d83c9a4f00',
'com.android.tools.analytics-library:tracker:26.2.1:tracker-26.2.1.jar:4a624ecc976539f755ddb0bb8dfc2dd3d08326cfec59a098dbd70f701ca7fb75', 'com.android.support:support-annotations:27.1.1:support-annotations-27.1.1.jar:3365960206c3d2b09e845f555e7f88f8effc8d2f00b369e66c4be384029299cf',
'com.android.tools.build:aapt2:3.2.1-4818971:aapt2-3.2.1-4818971-linux.jar:f431b6f96c91a2c155144b091a9c97d9805c589fe8efc9c930b6cd346cb60a1e', 'com.android.tools.analytics-library:protos:26.1.3:protos-26.1.3.jar:818c9f256f141d9dafec03a1aa2b94d240b2c140acfd7ee31a8b3e6c2b9479e3',
'com.android.tools.build:apksig:3.2.1:apksig-3.2.1.jar:2b46f2feffea66037aab29e4261b2433c190194a6ef97b958511eb157f2ccba5', 'com.android.tools.analytics-library:shared:26.1.3:shared-26.1.3.jar:7110706c7ada96c8b6f5ca80c478291bc7899d46277de2c48527e045442401a3',
'com.android.tools.build:apkzlib:3.2.1:apkzlib-3.2.1.jar:c39ad0313905932431fe81c8899c2cf39a4d92ad6c4edcaa4b25432f461452aa', 'com.android.tools.analytics-library:tracker:26.1.3:tracker-26.1.3.jar:4155424bf2ce4872da83332579a1707252bc66cbd77c5144fdc4483d0f2e1418',
'com.android.tools.build:builder-model:3.2.1:builder-model-3.2.1.jar:a9f68e6abcec122f9cb5ad352d3f05a3eb03acbcdca95e4d25c16310c2c965ff', 'com.android.tools.build:apksig:3.1.3:apksig-3.1.3.jar:7e1f8e675a6e768e5b56405e41d6c3cc05befe62e601b04177de1029902c9c89',
'com.android.tools.build:builder-test-api:3.2.1:builder-test-api-3.2.1.jar:533ac6c2b5884bb54967a33791f2628dfdfac7981af39417a333b43d4379b6be', 'com.android.tools.build:builder-model:3.1.3:builder-model-3.1.3.jar:06ad1c422d679fc698451479cb40ba863849d67bfd1de23f6d2c16d78b024b0b',
'com.android.tools.build:builder:3.2.1:builder-3.2.1.jar:aedcbfd115dbe91d09b4113e66ef50589b558d0aa3b2f133b1d867c9b87fae83', 'com.android.tools.build:builder-test-api:3.1.3:builder-test-api-3.1.3.jar:4d989f780436794f0f8b2f50e9e079b786571eac90f26c208ab2ae6d4012f389',
'com.android.tools.build:gradle-api:3.2.1:gradle-api-3.2.1.jar:57cf0ac5ac1dca8afdb3f62b94265e776e7dcfa641cc3844fb53a05193de208d', 'com.android.tools.build:builder:3.1.3:builder-3.1.3.jar:8a1092012c89d0ec1ee2eff09c5708c71ef4482a6862df8d3a44a67fccace01c',
'com.android.tools.build:manifest-merger:26.2.1:manifest-merger-26.2.1.jar:8830573263361035d38cfdcb51e2db94029c93865b21334f5fbf8a27984281a6', 'com.android.tools.build:gradle-api:3.1.3:gradle-api-3.1.3.jar:01e4df521456aef66514336f1d492346730dd1fb8f6433a89f62da834941ed72',
'com.android.tools.ddms:ddmlib:26.2.1:ddmlib-26.2.1.jar:a4bf0a29a19980bf27269465cc782064656750b77c26728f82f9e148b705218b', 'com.android.tools.build:manifest-merger:26.1.3:manifest-merger-26.1.3.jar:1e4fc7e932adb4607082409800e5e6fccb42e6c5360ae5990094bf522f3ada55',
'com.android.tools.external.com-intellij:intellij-core:26.2.1:intellij-core-26.2.1.jar:4925ad1892c2687cb1a63427d440ef519c8c59215fefe0dc5d541d5d411fcafe', 'com.android.tools.ddms:ddmlib:26.1.3:ddmlib-26.1.3.jar:c54931cd68df5d1ea2923b3b320eae47cd2307a5a916bb8674c0acf93cd1d3cd',
'com.android.tools.external.com-intellij:kotlin-compiler:26.2.1:kotlin-compiler-26.2.1.jar:daa064fd708f340ee25fb9823c4c74104ac77f1370b76d907eb9ae6daec0a2ae', 'com.android.tools.external.com-intellij:intellij-core:26.1.3:intellij-core-26.1.3.jar:af67f5535fef2e1a28b1007a4acb8c5deb6a1e33b8afe7b11d012c9e778ebcec',
'com.android.tools.external.org-jetbrains:uast:26.2.1:uast-26.2.1.jar:f10f7258d2ab9189562cc0f9ad838c0378fdba439229173390a99de02ebac75b', 'com.android.tools.external.com-intellij:kotlin-compiler:26.1.3:kotlin-compiler-26.1.3.jar:c746d2859dc11cc05c84b692b3498d3a621e0929511f8440ee009c6557838fd4',
'com.android.tools.layoutlib:layoutlib-api:26.2.1:layoutlib-api-26.2.1.jar:ddbf4fca123733fa011595b1cc1f4ac2937ed327b60990711fafc33c775c2ade', 'com.android.tools.external.org-jetbrains:uast:26.1.3:uast-26.1.3.jar:3f3f6651d0c7685a77ecb22e9c82d6b49fdf24322c17360768dc530678f43265',
'com.android.tools.lint:lint-api:26.2.1:lint-api-26.2.1.jar:3b57e739de567b98bc9ab56c2c0ee66fc026b4adf5843e8f9804ca0666a6f66e', 'com.android.tools.layoutlib:layoutlib-api:26.1.3:layoutlib-api-26.1.3.jar:10bc73ce706c45629872d6a999dbe12116df64e24f47ff93b7b13121ff57b4b0',
'com.android.tools.lint:lint-checks:26.2.1:lint-checks-26.2.1.jar:c86f4cc9aaee722ee4ad70062f7b5af91e9b041914af27adc09f545ab0fb3bc6', 'com.android.tools.lint:lint-api:26.1.3:lint-api-26.1.3.jar:6f97323f9af8deda86278717885b5c927f3766757db89709f52d11d42b6fb751',
'com.android.tools.lint:lint-gradle-api:26.2.1:lint-gradle-api-26.2.1.jar:2283e7af32e301565f2a797e531f0fc8c648077d457afb3ffdddbee638976c2f', 'com.android.tools.lint:lint-checks:26.1.3:lint-checks-26.1.3.jar:73c3d53784c9ce3e6d5968506581918e0179645d20809927ca4a001dd766b001',
'com.android.tools.lint:lint-gradle:26.2.1:lint-gradle-26.2.1.jar:8fd90b2f3ec788cbb9801c07ab3e1ea2255aa31a6093157d7ea0ff13d0315ecb', 'com.android.tools.lint:lint-gradle-api:26.1.3:lint-gradle-api-26.1.3.jar:7ca3c4866ec21dc21d53a9d86f752b77ace6f6c610a0c9dc877313856c733d9d',
'com.android.tools.lint:lint-kotlin:26.2.1:lint-kotlin-26.2.1.jar:7a6a5d2b18f69cf1b900d857c2632b4c683713c533295933b8b759f8cab4a877', 'com.android.tools.lint:lint-gradle:26.1.3:lint-gradle-26.1.3.jar:db0c354b8f4b6f6637e31f91c564785a59ff896325331fcbc3de7458e0b6c067',
'com.android.tools.lint:lint:26.2.1:lint-26.2.1.jar:7848b82ae988b90dee259ae7c7e86e05cbf52db6cd21c8bbd38ce7df08f3f8c5', 'com.android.tools.lint:lint-kotlin:26.1.3:lint-kotlin-26.1.3.jar:94e2b0f4565a241561cfb8fc1222bb3f132a3b98d2a90421dbb72ee8358e7d68',
'com.android.tools:annotations:26.2.1:annotations-26.2.1.jar:7391c6a1e080174b96e64ceb078dadd31ce4d8a2d2fee0ec65be202126f90f24', 'com.android.tools.lint:lint:26.1.3:lint-26.1.3.jar:8d5f32c989c6d191d712e90ad3ca2d1c409313599551d04d834caa44d26c78df',
'com.android.tools:common:26.2.1:common-26.2.1.jar:a50aab2d6411ff68f4004a87c7e93d87d8e980a0ec3b352246549897ea2d78e5', 'com.android.tools:annotations:26.1.3:annotations-26.1.3.jar:c950430b24ac5d58fc97e7283b8f0115f99587e76e08b4e1e2aaa780f2d77323',
'com.android.tools:dvlib:26.2.1:dvlib-26.2.1.jar:72a83bf2839b1df9b1fbf67ba45d1bfb9f966cd774da4320c762b2be8f1688aa', 'com.android.tools:common:26.1.3:common-26.1.3.jar:7c31a90581a148ab219f615a59667f0dded7fa39b248529784474da3c2274ef2',
'com.android.tools:repository:26.2.1:repository-26.2.1.jar:fa74dae09103faef703df38550ad8fa244c5b6d1bf90d6198be932292b3d9cc1', 'com.android.tools:dvlib:26.1.3:dvlib-26.1.3.jar:0cae87906f53d3f1088366a916ed180a7312b6d9919b90797f238875c8492855',
'com.android.tools:sdk-common:26.2.1:sdk-common-26.2.1.jar:759d4b292ca69a35cf961fca377b54158fc6c88108978006999442e80a011cf4', 'com.android.tools:repository:26.1.3:repository-26.1.3.jar:52d4539cc68db91b261e2a33b2c8206b26e05539078758dc28cfb3854adb4f59',
'com.android.tools:sdklib:26.2.1:sdklib-26.2.1.jar:248df7ad5eac4aeb6f96c394c76760de4b7b89ac056e54d0c21a739368b91b45', 'com.android.tools:sdk-common:26.1.3:sdk-common-26.1.3.jar:1948603ca9ff22c7ebb3178000bffa3a9dd2ca1cc5cb0c793cae08468b8fcfc1',
'com.android.tools:sdklib:26.1.3:sdklib-26.1.3.jar:4adcfaad9514607098d2c51503c39811112d3050f4d1e744c01c7f08f591032b',
'com.google.code.findbugs:jsr305:1.3.9:jsr305-1.3.9.jar:905721a0eea90a81534abb7ee6ef4ea2e5e645fa1def0a5cd88402df1b46c9ed', 'com.google.code.findbugs:jsr305:1.3.9:jsr305-1.3.9.jar:905721a0eea90a81534abb7ee6ef4ea2e5e645fa1def0a5cd88402df1b46c9ed',
'com.google.code.gson:gson:2.8.0:gson-2.8.0.jar:c6221763bd79c4f1c3dc7f750b5f29a0bb38b367b81314c4f71896e340c40825', 'com.google.code.gson:gson:2.7:gson-2.7.jar:2d43eb5ea9e133d2ee2405cc14f5ee08951b8361302fdd93494a3a997b508d32',
'com.google.dagger:dagger-compiler:2.19:dagger-compiler-2.19.jar:27a4b202a2de908182edb261f8c0a264e08e5e4733d7514bc7fbf0d31da5c0fc', 'com.google.dagger:dagger-compiler:2.0.2:dagger-compiler-2.0.2.jar:b74bc9de063dd4c6400b232231f2ef5056145b8fbecbf5382012007dd1c071b3',
'com.google.dagger:dagger-producers:2.19:dagger-producers-2.19.jar:a17663abe0fc38b676026950907d4c5f5e2bf338375415861eaff6e3bdb0b768', 'com.google.dagger:dagger-producers:2.0-beta:dagger-producers-2.0-beta.jar:99ec15e8a0507ba569e7655bc1165ee5e5ca5aa914b3c8f7e2c2458f724edd6b',
'com.google.dagger:dagger-spi:2.19:dagger-spi-2.19.jar:e7a6379d82c841f6aac2866948ad1eed716528707814602842a8d844ce04e2e1', 'com.google.dagger:dagger:2.0.2:dagger-2.0.2.jar:84c0282ed8be73a29e0475d639da030b55dee72369e58dd35ae7d4fe6243dcf9',
'com.google.dagger:dagger:2.19:dagger-2.19.jar:514b6f1e0727c6572e1d65cb27e4ae668b7aeaeb93a29515182965265b609939',
'com.google.errorprone:error_prone_annotations:2.0.18:error_prone_annotations-2.0.18.jar:cb4cfad870bf563a07199f3ebea5763f0dec440fcda0b318640b1feaa788656b', 'com.google.errorprone:error_prone_annotations:2.0.18:error_prone_annotations-2.0.18.jar:cb4cfad870bf563a07199f3ebea5763f0dec440fcda0b318640b1feaa788656b',
'com.google.errorprone:error_prone_annotations:2.1.3:error_prone_annotations-2.1.3.jar:03d0329547c13da9e17c634d1049ea2ead093925e290567e1a364fd6b1fc7ff8', 'com.google.guava:guava:18.0:guava-18.0.jar:d664fbfc03d2e5ce9cab2a44fb01f1d0bf9dfebeccc1a473b1f9ea31f79f6f99',
'com.google.errorprone:javac-shaded:9-dev-r4023-3:javac-shaded-9-dev-r4023-3.jar:65bfccf60986c47fbc17c9ebab0be626afc41741e0a6ec7109e0768817a36f30', 'com.google.guava:guava:22.0:guava-22.0.jar:1158e94c7de4da480873f0b4ab4a1da14c0d23d4b1902cc94a58a6f0f9ab579e',
'com.google.googlejavaformat:google-java-format:1.5:google-java-format-1.5.jar:aa19ad7850fb85178aa22f2fddb163b84d6ce4d0035872f30d4408195ca1144e',
'com.google.guava:guava:23.0:guava-23.0.jar:7baa80df284117e5b945b19b98d367a85ea7b7801bd358ff657946c3bd1b6596',
'com.google.guava:guava:25.0-jre:guava-25.0-jre.jar:3fd4341776428c7e0e5c18a7c10de129475b69ab9d30aeafbb5c277bb6074fa9',
'com.google.j2objc:j2objc-annotations:1.1:j2objc-annotations-1.1.jar:40ceb7157feb263949e0f503fe5f71689333a621021aa20ce0d0acee3badaa0f', 'com.google.j2objc:j2objc-annotations:1.1:j2objc-annotations-1.1.jar:40ceb7157feb263949e0f503fe5f71689333a621021aa20ce0d0acee3badaa0f',
'com.google.jimfs:jimfs:1.1:jimfs-1.1.jar:c4828e28d7c0a930af9387510b3bada7daa5c04d7c25a75c7b8b081f1c257ddd', 'com.google.jimfs:jimfs:1.1:jimfs-1.1.jar:c4828e28d7c0a930af9387510b3bada7daa5c04d7c25a75c7b8b081f1c257ddd',
'com.google.protobuf:protobuf-java:3.4.0:protobuf-java-3.4.0.jar:dce7e66b32456a1b1198da0caff3a8acb71548658391e798c79369241e6490a4', 'com.google.protobuf:protobuf-java:3.4.0:protobuf-java-3.4.0.jar:dce7e66b32456a1b1198da0caff3a8acb71548658391e798c79369241e6490a4',
'com.googlecode.json-simple:json-simple:1.1:json-simple-1.1.jar:2d9484f4c649f708f47f9a479465fc729770ee65617dca3011836602264f6439', 'com.googlecode.json-simple:json-simple:1.1:json-simple-1.1.jar:2d9484f4c649f708f47f9a479465fc729770ee65617dca3011836602264f6439',
'com.squareup:javapoet:1.11.1:javapoet-1.11.1.jar:9cbf2107be499ec6e95afd36b58e3ca122a24166cdd375732e51267d64058e90',
'com.squareup:javawriter:2.5.0:javawriter-2.5.0.jar:fcfb09fb0ea0aa97d3cfe7ea792398081348e468f126b3603cb3803f240197f0', 'com.squareup:javawriter:2.5.0:javawriter-2.5.0.jar:fcfb09fb0ea0aa97d3cfe7ea792398081348e468f126b3603cb3803f240197f0',
'com.sun.activation:javax.activation:1.2.0:javax.activation-1.2.0.jar:993302b16cd7056f21e779cc577d175a810bb4900ef73cd8fbf2b50f928ba9ce', 'com.sun.activation:javax.activation:1.2.0:javax.activation-1.2.0.jar:993302b16cd7056f21e779cc577d175a810bb4900ef73cd8fbf2b50f928ba9ce',
'com.sun.istack:istack-commons-runtime:2.21:istack-commons-runtime-2.21.jar:c33e67a0807095f02a0e2da139412dd7c4f9cc1a4c054b3e434f96831ba950f4', 'com.sun.istack:istack-commons-runtime:2.21:istack-commons-runtime-2.21.jar:c33e67a0807095f02a0e2da139412dd7c4f9cc1a4c054b3e434f96831ba950f4',
'com.sun.xml.fastinfoset:FastInfoset:1.2.13:FastInfoset-1.2.13.jar:27a77db909f3c2833c0b1a37c55af1db06045118ad2eed96ce567b6632bce038', 'com.sun.xml.fastinfoset:FastInfoset:1.2.13:FastInfoset-1.2.13.jar:27a77db909f3c2833c0b1a37c55af1db06045118ad2eed96ce567b6632bce038',
'commons-codec:commons-codec:1.9:commons-codec-1.9.jar:ad19d2601c3abf0b946b5c3a4113e226a8c1e3305e395b90013b78dd94a723ce', 'commons-codec:commons-codec:1.6:commons-codec-1.6.jar:54b34e941b8e1414bd3e40d736efd3481772dc26db3296f6aa45cec9f6203d86',
'commons-logging:commons-logging:1.2:commons-logging-1.2.jar:daddea1ea0be0f56978ab3006b8ac92834afeefbd9b7e4e6316fca57df0fa636', 'commons-logging:commons-logging:1.1.1:commons-logging-1.1.1.jar:ce6f913cad1f0db3aad70186d65c5bc7ffcc9a99e3fe8e0b137312819f7c362f',
'it.unimi.dsi:fastutil:7.2.0:fastutil-7.2.0.jar:74fa208043740642f7e6eb09faba15965218ad2f50ce3020efb100136e4b591c', 'it.unimi.dsi:fastutil:7.2.0:fastutil-7.2.0.jar:74fa208043740642f7e6eb09faba15965218ad2f50ce3020efb100136e4b591c',
'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f', 'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f',
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff', 'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
@@ -62,15 +58,13 @@ 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.apache.commons:commons-compress:1.12:commons-compress-1.12.jar:2c1542faf343185b7cab9c3d55c8ae5471d6d095d3887a4adefdbdf2984dc0b6', 'org.apache.commons:commons-compress:1.12:commons-compress-1.12.jar:2c1542faf343185b7cab9c3d55c8ae5471d6d095d3887a4adefdbdf2984dc0b6',
'org.apache.httpcomponents:httpclient:4.5.2:httpclient-4.5.2.jar:0dffc621400d6c632f55787d996b8aeca36b30746a716e079a985f24d8074057', 'org.apache.httpcomponents:httpclient:4.2.6:httpclient-4.2.6.jar:362e9324ee7c697e21279e20077b52737ddef3f1b2c1a7abe5ad34b465145550',
'org.apache.httpcomponents:httpcore:4.4.5:httpcore-4.4.5.jar:64d5453874cab7e40a7065cb01a9a9ca1053845a9786b478878b679e0580cec3', 'org.apache.httpcomponents:httpcore:4.2.5:httpcore-4.2.5.jar:e5e82da4cc66c8d917bbf743e3c0752efe8522735e7fc9dbddb65bccea81cfe9',
'org.apache.httpcomponents:httpmime:4.5.2:httpmime-4.5.2.jar:231a3f7e4962053db2be8461d5422e68fc458a3a7dd7d8ada803a348e21f8f07', 'org.apache.httpcomponents:httpmime:4.1:httpmime-4.1.jar:31629566148e8a47688ae43b420abc3ecd783ed15b33bebc00824bf24c9b15aa',
'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.bouncycastle:bcpkix-jdk15on:1.56:bcpkix-jdk15on-1.56.jar:7043dee4e9e7175e93e0b36f45b1ec1ecb893c5f755667e8b916eb8dd201c6ca', 'org.bouncycastle:bcpkix-jdk15on:1.56:bcpkix-jdk15on-1.56.jar:7043dee4e9e7175e93e0b36f45b1ec1ecb893c5f755667e8b916eb8dd201c6ca',
'org.bouncycastle:bcprov-jdk15on:1.56:bcprov-jdk15on-1.56.jar:963e1ee14f808ffb99897d848ddcdb28fa91ddda867eb18d303e82728f878349', 'org.bouncycastle:bcprov-jdk15on:1.56:bcprov-jdk15on-1.56.jar:963e1ee14f808ffb99897d848ddcdb28fa91ddda867eb18d303e82728f878349',
'org.briarproject:obfs4proxy-android:0.0.7:obfs4proxy-android-0.0.7.zip:abdfb5d889d848de9bf214f9276abbf454808a505b870819eccc9a9e985bf617', 'org.briarproject:tor-android:0.2.9.16:tor-android-0.2.9.16.zip:515e33dda6a30853c885a2de2c79ae1ab9ad8b6db44f5db8890333ec2e24f4ae',
'org.briarproject:tor-android:0.3.4.8:tor-android-0.3.4.8.zip:989a0352d9d8d8172cd6c2137654e165e5d2beb10ed1211bab3814e224ad1926',
'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d',
'org.codehaus.groovy:groovy-all:2.4.12:groovy-all-2.4.12.jar:6a56af4bd48903d56bec62821876cadefafd007360cc6bd0d8f7aa8d72b38be4', 'org.codehaus.groovy:groovy-all:2.4.12:groovy-all-2.4.12.jar:6a56af4bd48903d56bec62821876cadefafd007360cc6bd0d8f7aa8d72b38be4',
'org.codehaus.mojo:animal-sniffer-annotations:1.14:animal-sniffer-annotations-1.14.jar:2068320bd6bad744c3673ab048f67e30bef8f518996fa380033556600669905d', 'org.codehaus.mojo:animal-sniffer-annotations:1.14:animal-sniffer-annotations-1.14.jar:2068320bd6bad744c3673ab048f67e30bef8f518996fa380033556600669905d',
'org.glassfish.jaxb:jaxb-core:2.2.11:jaxb-core-2.2.11.jar:37bcaee8ebb04362c8352a5bf6221b86967ecdab5164c696b10b9a2bb587b2aa', 'org.glassfish.jaxb:jaxb-core:2.2.11:jaxb-core-2.2.11.jar:37bcaee8ebb04362c8352a5bf6221b86967ecdab5164c696b10b9a2bb587b2aa',
@@ -79,10 +73,9 @@ dependencyVerification {
'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.jetbrains.kotlin:kotlin-reflect:1.2.0:kotlin-reflect-1.2.0.jar:4f48a872bad6e4d9c053f4ad610d11e4012ad7e58dc19a03dd5eb811f36069dd', 'org.jetbrains.kotlin:kotlin-reflect:1.2.0:kotlin-reflect-1.2.0.jar:4f48a872bad6e4d9c053f4ad610d11e4012ad7e58dc19a03dd5eb811f36069dd',
'org.jetbrains.kotlin:kotlin-stdlib-common:1.2.71:kotlin-stdlib-common-1.2.71.jar:63999687ff2fce8a592dd180ffbbf8f1d21c26b4044c55cdc74ff3cf3b3cf328', 'org.jetbrains.kotlin:kotlin-stdlib-jre7:1.2.0:kotlin-stdlib-jre7-1.2.0.jar:c7a20fb951d437797afe8980aff6c1e5a03f310c661ba58ba1d4fa90cb0f2926',
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.71:kotlin-stdlib-jdk7-1.2.71.jar:b136bd61b240e07d4d92ce00d3bd1dbf584400a7bf5f220c2f3cd22446858082', 'org.jetbrains.kotlin:kotlin-stdlib-jre8:1.2.0:kotlin-stdlib-jre8-1.2.0.jar:633524eee6ef1941f7cb1dab7ee3927b0a221ceee9047aeb5515f4cbb990c82a',
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.2.71:kotlin-stdlib-jdk8-1.2.71.jar:ac3c8abf47790b64b4f7e2509a53f0c145e061ac1612a597520535d199946ea9', 'org.jetbrains.kotlin:kotlin-stdlib:1.2.0:kotlin-stdlib-1.2.0.jar:05cfd9f5ac0b41910703a8925f7211a495909b27a2ffdd1c5106f1689aeafcd4',
'org.jetbrains.kotlin:kotlin-stdlib:1.2.71:kotlin-stdlib-1.2.71.jar:4c895c270b87f5fec2a2796e1d89c15407ee821de961527c28588bb46afbc68b',
'org.jetbrains.trove4j:trove4j:20160824:trove4j-20160824.jar:1917871c8deb468307a584680c87a44572f5a8b0b98c6d397fc0f5f86596dbe7', 'org.jetbrains.trove4j:trove4j:20160824:trove4j-20160824.jar:1917871c8deb468307a584680c87a44572f5a8b0b98c6d397fc0f5f86596dbe7',
'org.jetbrains:annotations:13.0:annotations-13.0.jar:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478', 'org.jetbrains:annotations:13.0:annotations-13.0.jar:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478',
'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',
@@ -91,11 +84,11 @@ dependencyVerification {
'org.jmock:jmock:2.8.2:jmock-2.8.2.jar:6c73cb4a2e6dbfb61fd99c9a768539c170ab6568e57846bd60dbf19596b65b16', 'org.jmock:jmock:2.8.2:jmock-2.8.2.jar:6c73cb4a2e6dbfb61fd99c9a768539c170ab6568e57846bd60dbf19596b65b16',
'org.jvnet.staxex:stax-ex:1.7.7:stax-ex-1.7.7.jar:a31ff7d77163c0deb09e7fee59ad35ae44c2cee2cc8552a116ccd1583d813fb4', 'org.jvnet.staxex:stax-ex:1.7.7:stax-ex-1.7.7.jar:a31ff7d77163c0deb09e7fee59ad35ae44c2cee2cc8552a116ccd1583d813fb4',
'org.objenesis:objenesis:2.1:objenesis-2.1.jar:c74330cc6b806c804fd37e74487b4fe5d7c2750c5e15fbc6efa13bdee1bdef80', 'org.objenesis:objenesis:2.1:objenesis-2.1.jar:c74330cc6b806c804fd37e74487b4fe5d7c2750c5e15fbc6efa13bdee1bdef80',
'org.ow2.asm:asm-analysis:6.0:asm-analysis-6.0.jar:2f1a6387219c3a6cc4856481f221b03bd9f2408a326d416af09af5d6f608c1f4', 'org.ow2.asm:asm-analysis:5.1:asm-analysis-5.1.jar:a34658f5c5de4b573eef21131cc32cc25f7b66407944f312b28ec2e56abb1fa9',
'org.ow2.asm:asm-commons:6.0:asm-commons-6.0.jar:f1bce5c648a96a017bdcd01fe5d59af9845297fd7b79b81c015a6fbbd9719abf', 'org.ow2.asm:asm-commons:5.1:asm-commons-5.1.jar:97b3786e1f55e74bddf8ad102bf50e33bbcbc1f6b7fd7b36f0bbbb25cd4981be',
'org.ow2.asm:asm-tree:6.0:asm-tree-6.0.jar:887998fb69727c8759e4d253f856822801e33f9fd4caa566b3ac58ee92106215', 'org.ow2.asm:asm-tree:5.1:asm-tree-5.1.jar:c0de2bbc4cb8297419659813ecd4ed1d077ed1dd5c1f5544cc5143e493e84c10',
'org.ow2.asm:asm-util:6.0:asm-util-6.0.jar:356afebdb0f870175262e5188f8709a3b17aa2a5a6a4b0340b04d4b449bca5f6', 'org.ow2.asm:asm-util:5.1:asm-util-5.1.jar:ee032c39ae5e3cd099148fbba9a2124f9ed613e5cb93e03ee0fa8808ce364040',
'org.ow2.asm:asm:5.0.4:asm-5.0.4.jar:896618ed8ae62702521a78bc7be42b7c491a08e6920a15f89a3ecdec31e9a220', 'org.ow2.asm:asm:5.0.4:asm-5.0.4.jar:896618ed8ae62702521a78bc7be42b7c491a08e6920a15f89a3ecdec31e9a220',
'org.ow2.asm:asm:6.0:asm-6.0.jar:dd8971c74a4e697899a8e95caae4ea8760ea6c486dc6b97b1795e75760420461', 'org.ow2.asm:asm:5.1:asm-5.1.jar:d2da399a9967c69f0a21739256fa79d284222c223082cacadc17372244764b54',
] ]
} }

View File

@@ -7,13 +7,15 @@ apply plugin: 'witness'
apply from: 'witness.gradle' apply from: 'witness.gradle'
dependencies { dependencies {
implementation "com.google.dagger:dagger:2.19" implementation "com.google.dagger:dagger:2.0.2"
implementation 'com.google.code.findbugs:jsr305:3.0.2' implementation 'com.google.code.findbugs:jsr305:3.0.2'
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
testImplementation "org.jmock:jmock:2.8.2" testImplementation "org.jmock:jmock:2.8.2"
testImplementation "org.jmock:jmock-junit4:2.8.2" testImplementation "org.jmock:jmock-junit4:2.8.2"
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-core:1.3"
signature 'org.codehaus.mojo.signature:java16:1.1@signature' signature 'org.codehaus.mojo.signature:java16:1.1@signature'
} }
@@ -29,3 +31,8 @@ task jarTest(type: Jar, dependsOn: testClasses) {
artifacts { artifacts {
testOutput jarTest testOutput jarTest
} }
tasks.withType(Test) {
// Use entropy-gathering device specified on command line, if any
systemProperty 'java.security.egd', System.getProperty('java.security.egd')
}

View File

@@ -1,14 +1,13 @@
package org.briarproject.bramble.api; package org.briarproject.bramble.api;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.util.StringUtils;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator; import java.util.Comparator;
import javax.annotation.concurrent.ThreadSafe; import javax.annotation.concurrent.ThreadSafe;
import static org.briarproject.bramble.util.StringUtils.toHexString;
/** /**
* A wrapper around a byte array, to allow it to be stored in maps etc. * A wrapper around a byte array, to allow it to be stored in maps etc.
*/ */
@@ -57,7 +56,8 @@ public class Bytes implements Comparable<Bytes> {
@Override @Override
public String toString() { public String toString() {
return getClass().getSimpleName() + "(" + toHexString(getBytes()) + ")"; return getClass().getSimpleName() +
"(" + StringUtils.toHexString(getBytes()) + ")";
} }
public static class BytesComparator implements Comparator<Bytes> { public static class BytesComparator implements Comparator<Bytes> {

View File

@@ -2,6 +2,7 @@ package org.briarproject.bramble.api;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
@@ -9,8 +10,6 @@ import java.util.Set;
import javax.annotation.concurrent.NotThreadSafe; import javax.annotation.concurrent.NotThreadSafe;
import static java.util.Collections.unmodifiableSet;
@NotThreadSafe @NotThreadSafe
@NotNullByDefault @NotNullByDefault
public class Multiset<T> { public class Multiset<T> {
@@ -97,6 +96,6 @@ public class Multiset<T> {
* is unmodifiable. * is unmodifiable.
*/ */
public Set<T> keySet() { public Set<T> keySet() {
return unmodifiableSet(map.keySet()); return Collections.unmodifiableSet(map.keySet());
} }
} }

View File

@@ -1,10 +0,0 @@
package org.briarproject.bramble.api;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface Nameable {
String getName();
}

View File

@@ -1,26 +0,0 @@
package org.briarproject.bramble.api;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
@Immutable
@NotNullByDefault
public class Pair<A, B> {
private final A first;
private final B second;
public Pair(A first, B second) {
this.first = first;
this.second = second;
}
public A getFirst() {
return first;
}
public B getSecond() {
return second;
}
}

View File

@@ -38,18 +38,4 @@ public abstract class StringMap extends Hashtable<String, String> {
public void putInt(String key, int value) { public void putInt(String key, int value) {
put(key, String.valueOf(value)); put(key, String.valueOf(value));
} }
public long getLong(String key, long defaultValue) {
String s = get(key);
if (s == null) return defaultValue;
try {
return Long.valueOf(s);
} catch (NumberFormatException e) {
return defaultValue;
}
}
public void putLong(String key, long value) {
put(key, String.valueOf(value));
}
} }

View File

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

View File

@@ -1,6 +0,0 @@
package org.briarproject.bramble.api.battery;
public interface BatteryManager {
boolean isCharging();
}

View File

@@ -1,19 +0,0 @@
package org.briarproject.bramble.api.battery.event;
import org.briarproject.bramble.api.event.Event;
/**
* An event that is broadcast when the device starts or stops charging.
*/
public class BatteryEvent extends Event {
private final boolean charging;
public BatteryEvent(boolean charging) {
this.charging = charging;
}
public boolean isCharging() {
return charging;
}
}

View File

@@ -5,11 +5,10 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import static java.util.Collections.emptyList;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
public class BdfMessageContext { public class BdfMessageContext {
@@ -24,7 +23,7 @@ public class BdfMessageContext {
} }
public BdfMessageContext(BdfDictionary dictionary) { public BdfMessageContext(BdfDictionary dictionary) {
this(dictionary, emptyList()); this(dictionary, Collections.emptyList());
} }
public BdfDictionary getDictionary() { public BdfDictionary getDictionary() {

View File

@@ -9,14 +9,14 @@ 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.validation.MessageValidator; import org.briarproject.bramble.api.sync.ValidationManager.MessageValidator;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import static java.util.logging.Logger.getLogger; 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;
@Immutable @Immutable
@@ -24,7 +24,7 @@ import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOC
public abstract class BdfMessageValidator implements MessageValidator { public abstract class BdfMessageValidator implements MessageValidator {
protected static final Logger LOG = protected static final Logger LOG =
getLogger(BdfMessageValidator.class.getName()); Logger.getLogger(BdfMessageValidator.class.getName());
protected final ClientHelper clientHelper; protected final ClientHelper clientHelper;
protected final MetadataEncoder metadataEncoder; protected final MetadataEncoder metadataEncoder;
@@ -49,9 +49,14 @@ public abstract class BdfMessageValidator implements MessageValidator {
throw new InvalidMessageException( throw new InvalidMessageException(
"Timestamp is too far in the future"); "Timestamp is too far in the future");
} }
byte[] raw = m.getRaw();
if (raw.length <= MESSAGE_HEADER_LENGTH) {
throw new InvalidMessageException("Message is too short");
}
try { try {
BdfList bodyList = clientHelper.toList(m.getBody()); BdfList body = clientHelper.toList(raw, MESSAGE_HEADER_LENGTH,
BdfMessageContext result = validateMessage(m, g, bodyList); raw.length - MESSAGE_HEADER_LENGTH);
BdfMessageContext result = validateMessage(m, g, body);
Metadata meta = metadataEncoder.encode(result.getDictionary()); Metadata meta = metadataEncoder.encode(result.getDictionary());
return new MessageContext(meta, result.getDependencies()); return new MessageContext(meta, result.getDependencies());
} catch (FormatException e) { } catch (FormatException e) {

View File

@@ -16,6 +16,8 @@ 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 {
@@ -30,12 +32,16 @@ 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

@@ -4,12 +4,8 @@ import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.util.StringUtils.toUtf8;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
public class Contact { public class Contact {
@@ -17,21 +13,13 @@ public class Contact {
private final ContactId id; private final ContactId id;
private final Author author; private final Author author;
private final AuthorId localAuthorId; private final AuthorId localAuthorId;
@Nullable
private final String alias;
private final boolean verified, active; private final boolean verified, active;
public Contact(ContactId id, Author author, AuthorId localAuthorId, public Contact(ContactId id, Author author, AuthorId localAuthorId,
@Nullable String alias, boolean verified, boolean active) { boolean verified, boolean active) {
if (alias != null) {
int aliasLength = toUtf8(alias).length;
if (aliasLength == 0 || aliasLength > MAX_AUTHOR_NAME_LENGTH)
throw new IllegalArgumentException();
}
this.id = id; this.id = id;
this.author = author; this.author = author;
this.localAuthorId = localAuthorId; this.localAuthorId = localAuthorId;
this.alias = alias;
this.verified = verified; this.verified = verified;
this.active = active; this.active = active;
} }
@@ -48,11 +36,6 @@ public class Contact {
return localAuthorId; return localAuthorId;
} }
@Nullable
public String getAlias() {
return alias;
}
public boolean isVerified() { public boolean isVerified() {
return verified; return verified;
} }

View File

@@ -5,16 +5,11 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.AuthorInfo;
import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.util.Collection; import java.util.Collection;
import javax.annotation.Nullable;
import static org.briarproject.bramble.api.contact.PendingContact.PendingContactState.FAILED;
@NotNullByDefault @NotNullByDefault
public interface ContactManager { public interface ContactManager {
@@ -54,35 +49,6 @@ public interface ContactManager {
long timestamp, boolean alice, boolean verified, boolean active) long timestamp, boolean alice, boolean verified, boolean active)
throws DbException; throws DbException;
/**
* Returns the static link that needs to be sent to the contact to be added.
*/
String getRemoteContactLink();
/**
* Returns true if the given link is syntactically valid.
*/
boolean isValidRemoteContactLink(String link);
/**
* Requests a new contact to be added via the given {@code link}.
*
* @param link The link received from the contact we want to add.
* @param alias The alias the user has given this contact.
* @return A PendingContact representing the contact to be added.
*/
PendingContact addRemoteContactRequest(String link, String alias);
/**
* Returns a list of {@link PendingContact}s.
*/
Collection<PendingContact> getPendingContacts();
/**
* Removes a {@link PendingContact} that is in state {@link FAILED}.
*/
void removePendingContact(PendingContact pendingContact);
/** /**
* Returns the contact with the given ID. * Returns the contact with the given ID.
*/ */
@@ -127,18 +93,6 @@ public interface ContactManager {
void setContactActive(Transaction txn, ContactId c, boolean active) void setContactActive(Transaction txn, ContactId c, boolean active)
throws DbException; throws DbException;
/**
* Sets an alias name for the contact or unsets it if alias is null.
*/
void setContactAlias(Transaction txn, ContactId c, @Nullable String alias)
throws DbException;
/**
* Sets an alias name for the contact or unsets it if alias is null.
*/
void setContactAlias(ContactId c, @Nullable String alias)
throws DbException;
/** /**
* Return true if a contact with this name and public key already exists * Return true if a contact with this name and public key already exists
*/ */
@@ -151,16 +105,6 @@ public interface ContactManager {
boolean contactExists(AuthorId remoteAuthorId, AuthorId localAuthorId) boolean contactExists(AuthorId remoteAuthorId, AuthorId localAuthorId)
throws DbException; throws DbException;
/**
* Returns the {@link AuthorInfo} for the given author.
*/
AuthorInfo getAuthorInfo(AuthorId a) throws DbException;
/**
* Returns the {@link AuthorInfo} for the given author.
*/
AuthorInfo getAuthorInfo(Transaction txn, AuthorId a) throws DbException;
interface ContactHook { interface ContactHook {
void addingContact(Transaction txn, Contact c) throws DbException; void addingContact(Transaction txn, Contact c) throws DbException;

View File

@@ -1,54 +0,0 @@
package org.briarproject.bramble.api.contact;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
@Immutable
@NotNullByDefault
public class PendingContact {
public enum PendingContactState {
WAITING_FOR_CONNECTION,
CONNECTED,
ADDING_CONTACT,
FAILED
}
private final PendingContactId id;
private final String alias;
private final PendingContactState state;
private final long timestamp;
public PendingContact(PendingContactId id, String alias,
PendingContactState state, long timestamp) {
this.id = id;
this.alias = alias;
this.state = state;
this.timestamp = timestamp;
}
public String getAlias() {
return alias;
}
public PendingContactState getState() {
return state;
}
public long getTimestamp() {
return timestamp;
}
@Override
public int hashCode() {
return id.hashCode();
}
@Override
public boolean equals(Object o) {
return o instanceof PendingContact &&
id.equals(((PendingContact) o).id);
}
}

View File

@@ -1,11 +0,0 @@
package org.briarproject.bramble.api.contact;
import org.briarproject.bramble.api.UniqueId;
public class PendingContactId extends UniqueId {
public PendingContactId(byte[] id) {
super(id);
}
}

View File

@@ -1,34 +0,0 @@
package org.briarproject.bramble.api.contact.event;
import org.briarproject.bramble.api.contact.PendingContact.PendingContactState;
import org.briarproject.bramble.api.contact.PendingContactId;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
/**
* An event that is broadcast when a pending contact's state is changed.
*/
@Immutable
@NotNullByDefault
public class PendingContactStateChangedEvent extends Event {
private final PendingContactId id;
private final PendingContactState state;
public PendingContactStateChangedEvent(PendingContactId id,
PendingContactState state) {
this.id = id;
this.state = state;
}
public PendingContactId getId() {
return id;
}
public PendingContactState getPendingContactState() {
return state;
}
}

View File

@@ -4,6 +4,7 @@ import org.briarproject.bramble.api.Bytes;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap; import java.util.TreeMap;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -23,9 +24,9 @@ public class BdfDictionary extends TreeMap<String, Object> {
* ); * );
* </pre> * </pre>
*/ */
public static BdfDictionary of(BdfEntry... entries) { public static BdfDictionary of(Entry<String, ?>... entries) {
BdfDictionary d = new BdfDictionary(); BdfDictionary d = new BdfDictionary();
for (BdfEntry e : entries) d.put(e.getKey(), e.getValue()); for (Entry<String, ?> e : entries) d.put(e.getKey(), e.getValue());
return d; return d;
} }

View File

@@ -4,12 +4,12 @@ import org.briarproject.bramble.api.Bytes;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe; import javax.annotation.concurrent.NotThreadSafe;
import static java.util.Arrays.asList;
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE; import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
@NotThreadSafe @NotThreadSafe
@@ -22,7 +22,7 @@ public class BdfList extends ArrayList<Object> {
* </pre> * </pre>
*/ */
public static BdfList of(Object... items) { public static BdfList of(Object... items) {
return new BdfList(asList(items)); return new BdfList(Arrays.asList(items));
} }
public BdfList() { public BdfList() {
@@ -33,7 +33,6 @@ public class BdfList extends ArrayList<Object> {
super(items); super(items);
} }
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
private boolean isInRange(int index) { private boolean isInRange(int index) {
return index >= 0 && index < size(); return index >= 0 && index < size();
} }

View File

@@ -1,71 +0,0 @@
package org.briarproject.bramble.api.data;
import org.briarproject.bramble.api.Bytes;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.annotation.Nullable;
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
import static org.briarproject.bramble.util.StringUtils.toHexString;
@NotNullByDefault
public class BdfStringUtils {
public static String toString(@Nullable Object o) throws FormatException {
return toString(o, 0);
}
private static String toString(@Nullable Object o, int indent)
throws FormatException {
if (o == null || o == NULL_VALUE) return "null";
if (o instanceof Boolean) return o.toString();
if (o instanceof Number) return o.toString();
if (o instanceof String) return "\"" + o + "\"";
if (o instanceof Bytes)
return "x" + toHexString(((Bytes) o).getBytes());
if (o instanceof byte[])
return "x" + toHexString((byte[]) o);
if (o instanceof List) {
List<?> list = (List) o;
StringBuilder sb = new StringBuilder();
sb.append("[\n");
int i = 0, size = list.size();
for (Object e : list) {
indent(sb, indent + 1);
sb.append(toString(e, indent + 1));
if (i++ < size - 1) sb.append(',');
sb.append('\n');
}
indent(sb, indent);
sb.append(']');
return sb.toString();
}
if (o instanceof Map) {
Map<?, ?> map = (Map) o;
StringBuilder sb = new StringBuilder();
sb.append("{\n");
int i = 0, size = map.size();
for (Entry e : map.entrySet()) {
indent(sb, indent + 1);
sb.append(toString(e.getKey(), indent + 1));
sb.append(": ");
sb.append(toString(e.getValue(), indent + 1));
if (i++ < size - 1) sb.append(',');
sb.append('\n');
}
indent(sb, indent);
sb.append('}');
return sb.toString();
}
throw new FormatException();
}
private static void indent(StringBuilder sb, int indent) {
for (int i = 0; i < indent; i++) sb.append('\t');
}
}

View File

@@ -19,7 +19,6 @@ import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.sync.MessageStatus; import org.briarproject.bramble.api.sync.MessageStatus;
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.validation.MessageState;
import org.briarproject.bramble.api.transport.KeySet; import org.briarproject.bramble.api.transport.KeySet;
import org.briarproject.bramble.api.transport.KeySetId; import org.briarproject.bramble.api.transport.KeySetId;
import org.briarproject.bramble.api.transport.TransportKeys; import org.briarproject.bramble.api.transport.TransportKeys;
@@ -29,6 +28,8 @@ import java.util.Map;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static org.briarproject.bramble.api.sync.ValidationManager.State;
/** /**
* Encapsulates the database implementation and exposes high-level operations * Encapsulates the database implementation and exposes high-level operations
* to other components. * to other components.
@@ -75,27 +76,6 @@ public interface DatabaseComponent {
*/ */
void endTransaction(Transaction txn); void endTransaction(Transaction txn);
/**
* Runs the given task within a transaction.
*/
<E extends Exception> void transaction(boolean readOnly,
DbRunnable<E> task) throws DbException, E;
/**
* Runs the given task within a transaction and returns the result of the
* task.
*/
<R, E extends Exception> R transactionWithResult(boolean readOnly,
DbCallable<R, E> task) throws DbException, E;
/**
* Runs the given task within a transaction and returns the result of the
* task, which may be null.
*/
@Nullable
<R, E extends Exception> R transactionWithNullableResult(boolean readOnly,
NullableDbCallable<R, E> task) throws DbException, E;
/** /**
* Stores a contact associated with the given local and remote pseudonyms, * Stores a contact associated with the given local and remote pseudonyms,
* and returns an ID for the contact. * and returns an ID for the contact.
@@ -171,13 +151,13 @@ public interface DatabaseComponent {
throws DbException; throws DbException;
/** /**
* Returns a batch of messages for the given contact, with a total length * Returns a batch of raw messages for the given contact, with a total
* less than or equal to the given length, for transmission over a * length 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<Message> generateBatch(Transaction txn, ContactId c, Collection<byte[]> generateBatch(Transaction txn, ContactId c,
int maxLength, int maxLatency) throws DbException; int maxLength, int maxLatency) throws DbException;
/** /**
@@ -198,14 +178,14 @@ public interface DatabaseComponent {
throws DbException; throws DbException;
/** /**
* Returns a batch of messages for the given contact, with a total length * Returns a batch of raw messages for the given contact, with a total
* less than or equal to the given length, for transmission over a * length 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<Message> generateRequestedBatch(Transaction txn, ContactId c, Collection<byte[]> generateRequestedBatch(Transaction txn, ContactId c,
int maxLength, int maxLatency) throws DbException; int maxLength, int maxLatency) throws DbException;
/** /**
@@ -283,15 +263,6 @@ 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/>
@@ -326,6 +297,15 @@ 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/>
@@ -373,12 +353,12 @@ public interface DatabaseComponent {
/** /**
* 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
* {@link MessageState UNKNOWN} is returned. * {@link State UNKNOWN} is returned.
* <p/> * <p/>
* Read-only. * Read-only.
*/ */
Map<MessageId, MessageState> getMessageDependencies(Transaction txn, Map<MessageId, State> getMessageDependencies(Transaction txn, MessageId m)
MessageId m) throws DbException; throws DbException;
/** /**
* Returns the IDs and states of all dependents of the given message. * Returns the IDs and states of all dependents of the given message.
@@ -387,16 +367,15 @@ public interface DatabaseComponent {
* <p/> * <p/>
* Read-only. * Read-only.
*/ */
Map<MessageId, MessageState> getMessageDependents(Transaction txn, Map<MessageId, State> getMessageDependents(Transaction txn, MessageId m)
MessageId m) throws DbException; throws DbException;
/** /**
* Gets the validation and delivery state of the given message. * Gets the validation and delivery state of the given message.
* <p/> * <p/>
* Read-only. * Read-only.
*/ */
MessageState getMessageState(Transaction txn, MessageId m) State getMessageState(Transaction txn, MessageId m) throws DbException;
throws DbException;
/** /**
* Returns the status of the given delivered message with respect to the * Returns the status of the given delivered message with respect to the
@@ -523,12 +502,6 @@ public interface DatabaseComponent {
void setContactActive(Transaction txn, ContactId c, boolean active) void setContactActive(Transaction txn, ContactId c, boolean active)
throws DbException; throws DbException;
/**
* Sets an alias name for the contact or unsets it if alias is null.
*/
void setContactAlias(Transaction txn, ContactId c, @Nullable String alias)
throws DbException;
/** /**
* Sets the given group's visibility to the given contact. * Sets the given group's visibility to the given contact.
*/ */
@@ -543,7 +516,7 @@ public interface DatabaseComponent {
/** /**
* Sets the validation and delivery state of the given message. * Sets the validation and delivery state of the given message.
*/ */
void setMessageState(Transaction txn, MessageId m, MessageState state) void setMessageState(Transaction txn, MessageId m, State state)
throws DbException; throws DbException;
/** /**

View File

@@ -1,9 +0,0 @@
package org.briarproject.bramble.api.db;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface DbCallable<R, E extends Exception> {
R call(Transaction txn) throws DbException, E;
}

View File

@@ -1,9 +0,0 @@
package org.briarproject.bramble.api.db;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface DbRunnable<E extends Exception> {
void run(Transaction txn) throws DbException, E;
}

View File

@@ -1,9 +0,0 @@
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

@@ -6,10 +6,6 @@ public interface MigrationListener {
* This is called when a migration is started while opening the database. * This is called when a migration is started while opening the database.
* It will be called once for each migration being applied. * It will be called once for each migration being applied.
*/ */
void onDatabaseMigration(); void onMigrationRun();
/**
* This is called when compaction is started while opening the database.
*/
void onDatabaseCompaction();
} }

View File

@@ -1,12 +0,0 @@
package org.briarproject.bramble.api.db;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.Nullable;
@NotNullByDefault
public interface NullableDbCallable<R, E extends Exception> {
@Nullable
R call(Transaction txn) throws DbException, E;
}

View File

@@ -3,12 +3,11 @@ package org.briarproject.bramble.api.db;
import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.Event;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import javax.annotation.concurrent.NotThreadSafe; import javax.annotation.concurrent.NotThreadSafe;
import static java.util.Collections.emptyList;
/** /**
* A wrapper around a database transaction. Transactions are not thread-safe. * A wrapper around a database transaction. Transactions are not thread-safe.
*/ */
@@ -54,7 +53,7 @@ public class Transaction {
* Returns any events attached to the transaction. * Returns any events attached to the transaction.
*/ */
public List<Event> getEvents() { public List<Event> getEvents() {
if (events == null) return emptyList(); if (events == null) return Collections.emptyList();
return events; return events;
} }

View File

@@ -1,20 +1,23 @@
package org.briarproject.bramble.api.identity; package org.briarproject.bramble.api.identity;
import org.briarproject.bramble.api.Nameable;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.util.StringUtils;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
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;
import static org.briarproject.bramble.util.StringUtils.toUtf8;
/** /**
* A pseudonym for a user. * A pseudonym for a user.
*/ */
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
public class Author implements Nameable { public class Author {
public enum Status {
NONE, ANONYMOUS, UNKNOWN, UNVERIFIED, VERIFIED, OURSELVES
}
/** /**
* The current version of the author structure. * The current version of the author structure.
@@ -28,7 +31,7 @@ public class Author implements Nameable {
public Author(AuthorId id, int formatVersion, String name, public Author(AuthorId id, int formatVersion, String name,
byte[] publicKey) { byte[] publicKey) {
int nameLength = toUtf8(name).length; int nameLength = StringUtils.toUtf8(name).length;
if (nameLength == 0 || nameLength > MAX_AUTHOR_NAME_LENGTH) if (nameLength == 0 || nameLength > MAX_AUTHOR_NAME_LENGTH)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
if (publicKey.length == 0 || publicKey.length > MAX_PUBLIC_KEY_LENGTH) if (publicKey.length == 0 || publicKey.length > MAX_PUBLIC_KEY_LENGTH)

View File

@@ -1,56 +0,0 @@
package org.briarproject.bramble.api.identity;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
@Immutable
@NotNullByDefault
public class AuthorInfo {
public enum Status {
NONE, ANONYMOUS, UNKNOWN, UNVERIFIED, VERIFIED, OURSELVES;
public boolean isContact() {
return this == UNVERIFIED || this == VERIFIED;
}
}
private final Status status;
@Nullable
private final String alias;
public AuthorInfo(Status status, @Nullable String alias) {
this.status = status;
this.alias = alias;
}
public AuthorInfo(Status status) {
this(status, null);
}
public Status getStatus() {
return status;
}
@Nullable
public String getAlias() {
return alias;
}
@Override
public int hashCode() {
int hashCode = status.ordinal();
if (alias != null) hashCode += alias.hashCode();
return hashCode;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof AuthorInfo)) return false;
AuthorInfo info = (AuthorInfo) o;
return status == info.status &&
(alias == null ? info.alias == null : alias.equals(info.alias));
}
}

View File

@@ -3,6 +3,7 @@ package org.briarproject.bramble.api.identity;
import org.briarproject.bramble.api.crypto.CryptoExecutor; import org.briarproject.bramble.api.crypto.CryptoExecutor;
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.db.Transaction;
import org.briarproject.bramble.api.identity.Author.Status;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault @NotNullByDefault
@@ -36,4 +37,14 @@ public interface IdentityManager {
*/ */
LocalAuthor getLocalAuthor(Transaction txn) throws DbException; LocalAuthor getLocalAuthor(Transaction txn) throws DbException;
/**
* Returns the {@link Status} of the given author.
*/
Status getAuthorStatus(AuthorId a) throws DbException;
/**
* Returns the {@link Status} of the given author.
*/
Status getAuthorStatus(Transaction txn, AuthorId a) throws DbException;
} }

View File

@@ -3,13 +3,7 @@ package org.briarproject.bramble.api.keyagreement;
public interface KeyAgreementConstants { public interface KeyAgreementConstants {
/** /**
* The version of the BQP protocol used in beta releases. This version * The current version of the BQP protocol. Version number 89 is reserved.
* number is reserved.
*/
byte BETA_PROTOCOL_VERSION = 89;
/**
* The current version of the BQP protocol.
*/ */
byte PROTOCOL_VERSION = 4; byte PROTOCOL_VERSION = 4;
@@ -21,7 +15,7 @@ public interface KeyAgreementConstants {
/** /**
* The connection timeout in milliseconds. * The connection timeout in milliseconds.
*/ */
long CONNECTION_TIMEOUT = 60_000; long CONNECTION_TIMEOUT = 20 * 1000;
/** /**
* The transport identifier for Bluetooth. * The transport identifier for Bluetooth.

View File

@@ -1,20 +0,0 @@
package org.briarproject.bramble.api.keyagreement;
import java.io.IOException;
/**
* Thrown when a QR code that has been scanned uses a protocol version that is
* not supported.
*/
public class UnsupportedVersionException extends IOException {
private final boolean tooOld;
public UnsupportedVersionException(boolean tooOld) {
this.tooOld = tooOld;
}
public boolean isTooOld() {
return tooOld;
}
}

View File

@@ -34,8 +34,7 @@ public interface LifecycleManager {
*/ */
enum LifecycleState { enum LifecycleState {
STARTING, MIGRATING_DATABASE, COMPACTING_DATABASE, STARTING_SERVICES, STARTING, MIGRATING_DATABASE, STARTING_SERVICES, RUNNING, STOPPING;
RUNNING, STOPPING;
public boolean isAfter(LifecycleState state) { public boolean isAfter(LifecycleState state) {
return ordinal() > state.ordinal(); return ordinal() > state.ordinal();

View File

@@ -1,15 +0,0 @@
package org.briarproject.bramble.api.nullsafety;
import javax.annotation.Nullable;
@NotNullByDefault
public class NullSafety {
/**
* Stand-in for `Objects.requireNonNull()`.
*/
public static <T> T requireNonNull(@Nullable T t) {
if (t == null) throw new NullPointerException();
return t;
}
}

View File

@@ -4,8 +4,7 @@ public interface TorConstants {
TransportId ID = new TransportId("org.briarproject.bramble.tor"); TransportId ID = new TransportId("org.briarproject.bramble.tor");
String PROP_ONION_V2 = "onion"; String PROP_ONION = "onion";
String PROP_ONION_V3 = "onion3";
int SOCKS_PORT = 59050; int SOCKS_PORT = 59050;
int CONTROL_PORT = 59051; int CONTROL_PORT = 59051;
@@ -13,14 +12,12 @@ 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 = "network2"; String PREF_TOR_NETWORK = "network";
String PREF_TOR_PORT = "port"; String PREF_TOR_PORT = "port";
String PREF_TOR_MOBILE = "useMobileData"; String PREF_TOR_DISABLE_BLOCKED = "disableWhenBlocked";
String PREF_TOR_ONLY_WHEN_CHARGING = "onlyWhenCharging";
int PREF_TOR_NETWORK_AUTOMATIC = 0; int PREF_TOR_NETWORK_NEVER = 0;
int PREF_TOR_NETWORK_WITHOUT_BRIDGES = 1; int PREF_TOR_NETWORK_WIFI = 1;
int PREF_TOR_NETWORK_WITH_BRIDGES = 2; int PREF_TOR_NETWORK_ALWAYS = 2;
int PREF_TOR_NETWORK_NEVER = 3;
} }

View File

@@ -1,6 +1,6 @@
package org.briarproject.bramble.api.plugin; package org.briarproject.bramble.api.plugin;
import static org.briarproject.bramble.util.StringUtils.toUtf8; import org.briarproject.bramble.util.StringUtils;
/** /**
* Type-safe wrapper for a namespaced string that uniquely identifies a * Type-safe wrapper for a namespaced string that uniquely identifies a
@@ -11,12 +11,12 @@ public class TransportId {
/** /**
* The maximum length of a transport identifier in UTF-8 bytes. * The maximum length of a transport identifier in UTF-8 bytes.
*/ */
public static final int MAX_TRANSPORT_ID_LENGTH = 100; public static int MAX_TRANSPORT_ID_LENGTH = 100;
private final String id; private final String id;
public TransportId(String id) { public TransportId(String id) {
int length = toUtf8(id).length; int length = StringUtils.toUtf8(id).length;
if (length == 0 || length > MAX_TRANSPORT_ID_LENGTH) if (length == 0 || length > MAX_TRANSPORT_ID_LENGTH)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
this.id = id; this.id = id;

View File

@@ -1,7 +1,6 @@
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
@@ -12,11 +11,6 @@ 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,7 +2,6 @@ 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;
@@ -14,18 +13,12 @@ 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, Settings settings) { public SettingsUpdatedEvent(String namespace) {
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

@@ -1,11 +1,10 @@
package org.briarproject.bramble.api.sync; package org.briarproject.bramble.api.sync;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.util.StringUtils;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.util.StringUtils.toUtf8;
/** /**
* Type-safe wrapper for a namespaced string that uniquely identifies a sync * Type-safe wrapper for a namespaced string that uniquely identifies a sync
* client. * client.
@@ -17,12 +16,12 @@ public class ClientId implements Comparable<ClientId> {
/** /**
* The maximum length of a client identifier in UTF-8 bytes. * The maximum length of a client identifier in UTF-8 bytes.
*/ */
public static final int MAX_CLIENT_ID_LENGTH = 100; public static int MAX_CLIENT_ID_LENGTH = 100;
private final String id; private final String id;
public ClientId(String id) { public ClientId(String id) {
int length = toUtf8(id).length; int length = StringUtils.toUtf8(id).length;
if (length == 0 || length > MAX_CLIENT_ID_LENGTH) if (length == 0 || length > MAX_CLIENT_ID_LENGTH)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
this.id = id; this.id = id;

View File

@@ -1,6 +1,6 @@
package org.briarproject.bramble.api.sync; package org.briarproject.bramble.api.sync;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH; import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_LENGTH;
import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH; import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
public class Message { public class Message {
@@ -13,16 +13,17 @@ public class Message {
private final MessageId id; private final MessageId id;
private final GroupId groupId; private final GroupId groupId;
private final long timestamp; private final long timestamp;
private final byte[] body; private final byte[] raw;
public Message(MessageId id, GroupId groupId, long timestamp, byte[] body) { public Message(MessageId id, GroupId groupId, long timestamp, byte[] raw) {
if (body.length == 0) throw new IllegalArgumentException(); if (raw.length <= MESSAGE_HEADER_LENGTH)
if (body.length > MAX_MESSAGE_BODY_LENGTH) throw new IllegalArgumentException();
if (raw.length > MAX_MESSAGE_LENGTH)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
this.id = id; this.id = id;
this.groupId = groupId; this.groupId = groupId;
this.timestamp = timestamp; this.timestamp = timestamp;
this.body = body; this.raw = raw;
} }
/** /**
@@ -49,15 +50,15 @@ public class Message {
/** /**
* Returns the length of the raw message in bytes. * Returns the length of the raw message in bytes.
*/ */
public int getRawLength() { public int getLength() {
return MESSAGE_HEADER_LENGTH + body.length; return raw.length;
} }
/** /**
* Returns the message body. * Returns the raw message.
*/ */
public byte[] getBody() { public byte[] getRaw() {
return body; return raw;
} }
@Override @Override

View File

@@ -4,11 +4,10 @@ import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import static java.util.Collections.emptyList;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
public class MessageContext { public class MessageContext {
@@ -23,7 +22,7 @@ public class MessageContext {
} }
public MessageContext(Metadata metadata) { public MessageContext(Metadata metadata) {
this(metadata, emptyList()); this(metadata, Collections.emptyList());
} }
public Metadata getMetadata() { public Metadata getMetadata() {

View File

@@ -9,5 +9,5 @@ public interface MessageFactory {
Message createMessage(byte[] raw); Message createMessage(byte[] raw);
byte[] getRawMessage(Message m); Message createMessage(MessageId m, byte[] raw);
} }

View File

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

View File

@@ -0,0 +1,87 @@
package org.briarproject.bramble.api.sync;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
/**
* Responsible for managing message validators and passing them messages to
* validate.
*/
@NotNullByDefault
public interface ValidationManager {
enum State {
UNKNOWN(0), INVALID(1), PENDING(2), DELIVERED(3);
private final int value;
State(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public static State fromValue(int value) {
for (State s : values()) if (s.value == value) return s;
throw new IllegalArgumentException();
}
}
/**
* Registers the message validator for the given client. This method
* should be called before
* {@link LifecycleManager#startServices(SecretKey)}.
*/
void registerMessageValidator(ClientId c, int majorVersion,
MessageValidator v);
/**
* Registers the incoming message hook for the given client. The hook will
* be called once for each incoming message that passes validation. This
* method should be called before
* {@link LifecycleManager#startServices(SecretKey)}.
*/
void registerIncomingMessageHook(ClientId c, int majorVersion,
IncomingMessageHook hook);
interface MessageValidator {
/**
* Validates the given message and returns its metadata and
* dependencies.
*/
MessageContext validateMessage(Message m, Group g)
throws InvalidMessageException;
}
interface IncomingMessageHook {
/**
* Called once for each incoming message that passes validation.
*
* @return whether or not this message should be shared
* @throws DbException Should only be used for real database errors.
* If this is thrown, delivery will be attempted again at next startup,
* whereas if an InvalidMessageException is thrown,
* the message will be permanently invalidated.
* @throws InvalidMessageException for any non-database error
* that occurs while handling remotely created data.
* This includes errors that occur while handling locally created data
* in a context controlled by remotely created data
* (for example, parsing the metadata of a dependency
* of an incoming message).
* Throwing this will delete the incoming message and its metadata
* marking it as invalid in the database.
* Never rethrow DbException as InvalidMessageException!
*/
boolean incomingMessage(Transaction txn, Message m, Metadata meta)
throws DbException, InvalidMessageException;
}
}

View File

@@ -3,10 +3,11 @@ package org.briarproject.bramble.api.sync.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.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.sync.validation.MessageState;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.sync.ValidationManager.State;
/** /**
* An event that is broadcast when a message state changed. * An event that is broadcast when a message state changed.
*/ */
@@ -16,10 +17,10 @@ public class MessageStateChangedEvent extends Event {
private final MessageId messageId; private final MessageId messageId;
private final boolean local; private final boolean local;
private final MessageState state; private final State state;
public MessageStateChangedEvent(MessageId messageId, boolean local, public MessageStateChangedEvent(MessageId messageId, boolean local,
MessageState state) { State state) {
this.messageId = messageId; this.messageId = messageId;
this.local = local; this.local = local;
this.state = state; this.state = state;
@@ -33,7 +34,7 @@ public class MessageStateChangedEvent extends Event {
return local; return local;
} }
public MessageState getState() { public State getState() {
return state; return state;
} }

View File

@@ -1,31 +0,0 @@
package org.briarproject.bramble.api.sync.validation;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.sync.InvalidMessageException;
import org.briarproject.bramble.api.sync.Message;
public interface IncomingMessageHook {
/**
* Called once for each incoming message that passes validation.
*
* @return whether or not this message should be shared
* @throws DbException Should only be used for real database errors.
* If this is thrown, delivery will be attempted again at next startup,
* whereas if an InvalidMessageException is thrown,
* the message will be permanently invalidated.
* @throws InvalidMessageException for any non-database error
* that occurs while handling remotely created data.
* This includes errors that occur while handling locally created data
* in a context controlled by remotely created data
* (for example, parsing the metadata of a dependency
* of an incoming message).
* Throwing this will delete the incoming message and its metadata
* marking it as invalid in the database.
* Never rethrow DbException as InvalidMessageException!
*/
boolean incomingMessage(Transaction txn, Message m, Metadata meta)
throws DbException, InvalidMessageException;
}

View File

@@ -1,21 +0,0 @@
package org.briarproject.bramble.api.sync.validation;
public enum MessageState {
UNKNOWN(0), INVALID(1), PENDING(2), DELIVERED(3);
private final int value;
MessageState(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public static MessageState fromValue(int value) {
for (MessageState s : values()) if (s.value == value) return s;
throw new IllegalArgumentException();
}
}

View File

@@ -1,16 +0,0 @@
package org.briarproject.bramble.api.sync.validation;
import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.InvalidMessageException;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageContext;
public interface MessageValidator {
/**
* Validates the given message and returns its metadata and
* dependencies.
*/
MessageContext validateMessage(Message m, Group g)
throws InvalidMessageException;
}

View File

@@ -1,31 +0,0 @@
package org.briarproject.bramble.api.sync.validation;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.ClientId;
/**
* Responsible for managing message validators and passing them messages to
* validate.
*/
@NotNullByDefault
public interface ValidationManager {
/**
* Registers the {@link MessageValidator} for the given client. This method
* should be called before
* {@link LifecycleManager#startServices(SecretKey)}.
*/
void registerMessageValidator(ClientId c, int majorVersion,
MessageValidator v);
/**
* Registers the {@link IncomingMessageHook} for the given client. The hook
* will be called once for each incoming message that passes validation.
* This method should be called before
* {@link LifecycleManager#startServices(SecretKey)}.
*/
void registerIncomingMessageHook(ClientId c, int majorVersion,
IncomingMessageHook hook);
}

View File

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

View File

@@ -38,13 +38,6 @@ public interface ClientVersioningManager {
Visibility getClientVisibility(Transaction txn, ContactId contactId, Visibility getClientVisibility(Transaction txn, ContactId contactId,
ClientId clientId, int majorVersion) throws DbException; ClientId clientId, int majorVersion) throws DbException;
/**
* Returns the minor version of the given client that is supported by the
* given contact, or -1 if the contact does not support the client.
*/
int getClientMinorVersion(Transaction txn, ContactId contactId,
ClientId clientId, int majorVersion) throws DbException;
interface ClientVersioningHook { interface ClientVersioningHook {
void onClientVisibilityChanging(Transaction txn, Contact c, void onClientVisibilityChanging(Transaction txn, Contact c,

View File

@@ -8,21 +8,17 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault @NotNullByDefault
public class IoUtils { public class IoUtils {
private static final Logger LOG = getLogger(IoUtils.class.getName()); private static final Logger LOG = Logger.getLogger(IoUtils.class.getName());
public static void deleteFileOrDir(File f) { public static void deleteFileOrDir(File f) {
if (f.isFile()) { if (f.isFile()) {
@@ -58,35 +54,16 @@ public class IoUtils {
out.flush(); out.flush();
out.close(); out.close();
} catch (IOException e) { } catch (IOException e) {
tryToClose(in, LOG, WARNING); tryToClose(in);
tryToClose(out, LOG, WARNING); tryToClose(out);
} }
} }
public static void tryToClose(@Nullable Closeable c, Logger logger, private static void tryToClose(@Nullable Closeable c) {
Level level) {
try { try {
if (c != null) c.close(); if (c != null) c.close();
} catch (IOException e) { } catch (IOException e) {
logException(logger, level, e); // We did our best
}
}
public static void tryToClose(@Nullable Socket s, Logger logger,
Level level) {
try {
if (s != null) s.close();
} catch (IOException e) {
logException(logger, level, e);
}
}
public static void tryToClose(@Nullable ServerSocket ss, Logger logger,
Level level) {
try {
if (ss != null) ss.close();
} catch (IOException e) {
logException(logger, level, e);
} }
} }

View File

@@ -10,6 +10,8 @@ public class OsUtils {
@Nullable @Nullable
private static final String os = System.getProperty("os.name"); private static final String os = System.getProperty("os.name");
@Nullable @Nullable
private static final String version = System.getProperty("os.version");
@Nullable
private static final String vendor = System.getProperty("java.vendor"); private static final String vendor = System.getProperty("java.vendor");
public static boolean isWindows() { public static boolean isWindows() {

View File

@@ -47,7 +47,7 @@ public class StringUtils {
try { try {
return s.getBytes("UTF-8"); return s.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
throw new AssertionError(e); throw new RuntimeException(e);
} }
} }
@@ -63,7 +63,7 @@ public class StringUtils {
try { try {
return decoder.decode(buffer).toString(); return decoder.decode(buffer).toString();
} catch (CharacterCodingException e) { } catch (CharacterCodingException e) {
throw new AssertionError(e); throw new RuntimeException(e);
} }
} }

View File

@@ -7,15 +7,13 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static org.briarproject.bramble.util.StringUtils.toUtf8;
@NotNullByDefault @NotNullByDefault
public class ValidationUtils { public class ValidationUtils {
public static void checkLength(@Nullable String s, int minLength, public static void checkLength(@Nullable String s, int minLength,
int maxLength) throws FormatException { int maxLength) throws FormatException {
if (s != null) { if (s != null) {
int length = toUtf8(s).length; int length = StringUtils.toUtf8(s).length;
if (length < minLength) throw new FormatException(); if (length < minLength) throw new FormatException();
if (length > maxLength) throw new FormatException(); if (length > maxLength) throw new FormatException();
} }
@@ -23,7 +21,7 @@ public class ValidationUtils {
public static void checkLength(@Nullable String s, int length) public static void checkLength(@Nullable String s, int length)
throws FormatException { throws FormatException {
if (s != null && toUtf8(s).length != length) if (s != null && StringUtils.toUtf8(s).length != length)
throw new FormatException(); throw new FormatException();
} }

View File

@@ -8,7 +8,6 @@ import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map.Entry; import java.util.Map.Entry;
import static java.util.Collections.singletonMap;
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE; import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@@ -20,15 +19,15 @@ public class BdfDictionaryTest extends BrambleTestCase {
public void testConstructors() { public void testConstructors() {
assertEquals(Collections.<String, Object>emptyMap(), assertEquals(Collections.<String, Object>emptyMap(),
new BdfDictionary()); new BdfDictionary());
assertEquals(singletonMap("foo", NULL_VALUE), assertEquals(Collections.singletonMap("foo", NULL_VALUE),
new BdfDictionary(singletonMap("foo", NULL_VALUE))); new BdfDictionary(Collections.singletonMap("foo", NULL_VALUE)));
} }
@Test @Test
public void testFactoryMethod() { public void testFactoryMethod() {
assertEquals(Collections.<String, Object>emptyMap(), assertEquals(Collections.<String, Object>emptyMap(),
BdfDictionary.of()); BdfDictionary.of());
assertEquals(singletonMap("foo", NULL_VALUE), assertEquals(Collections.singletonMap("foo", NULL_VALUE),
BdfDictionary.of(new BdfEntry("foo", NULL_VALUE))); BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)));
} }
@@ -68,7 +67,7 @@ public class BdfDictionaryTest extends BrambleTestCase {
} }
@Test @Test
public void testKeySetIteratorIsOrderedByKeys() { public void testKeySetIteratorIsOrderedByKeys() throws Exception {
BdfDictionary d = new BdfDictionary(); BdfDictionary d = new BdfDictionary();
d.put("a", 1); d.put("a", 1);
d.put("d", 4); d.put("d", 4);
@@ -87,7 +86,7 @@ public class BdfDictionaryTest extends BrambleTestCase {
} }
@Test @Test
public void testValuesIteratorIsOrderedByKeys() { public void testValuesIteratorIsOrderedByKeys() throws Exception {
BdfDictionary d = new BdfDictionary(); BdfDictionary d = new BdfDictionary();
d.put("a", 1); d.put("a", 1);
d.put("d", 4); d.put("d", 4);
@@ -106,7 +105,7 @@ public class BdfDictionaryTest extends BrambleTestCase {
} }
@Test @Test
public void testEntrySetIteratorIsOrderedByKeys() { public void testEntrySetIteratorIsOrderedByKeys() throws Exception {
BdfDictionary d = new BdfDictionary(); BdfDictionary d = new BdfDictionary();
d.put("a", 1); d.put("a", 1);
d.put("d", 4); d.put("d", 4);

View File

@@ -5,31 +5,26 @@ import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.test.BrambleTestCase; import org.briarproject.bramble.test.BrambleTestCase;
import org.junit.Test; import org.junit.Test;
import java.util.Random; import java.util.Arrays;
import java.util.Collections;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE; import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
public class BdfListTest extends BrambleTestCase { public class BdfListTest extends BrambleTestCase {
private final Random random = new Random();
@Test @Test
public void testConstructors() { public void testConstructors() {
assertEquals(emptyList(), new BdfList()); assertEquals(Collections.emptyList(), new BdfList());
assertEquals(asList(1, 2, NULL_VALUE), assertEquals(Arrays.asList(1, 2, NULL_VALUE),
new BdfList(asList(1, 2, NULL_VALUE))); new BdfList(Arrays.asList(1, 2, NULL_VALUE)));
} }
@Test @Test
public void testFactoryMethod() { public void testFactoryMethod() {
assertEquals(emptyList(), BdfList.of()); assertEquals(Collections.emptyList(), BdfList.of());
assertEquals(asList(1, 2, NULL_VALUE), assertEquals(Arrays.asList(1, 2, NULL_VALUE),
BdfList.of(1, 2, NULL_VALUE)); BdfList.of(1, 2, NULL_VALUE));
} }
@@ -69,21 +64,22 @@ public class BdfListTest extends BrambleTestCase {
} }
@Test @Test
public void testIndexOutOfBoundsReturnsDefaultValue() { @SuppressWarnings("ConstantConditions")
public void testIndexOutOfBoundsReturnsDefaultValue() throws Exception {
BdfList list = BdfList.of(1, 2, 3); BdfList list = BdfList.of(1, 2, 3);
boolean defaultBoolean = random.nextBoolean(); boolean defaultBoolean = true;
assertEquals(defaultBoolean, list.getBoolean(-1, defaultBoolean)); assertEquals(defaultBoolean, list.getBoolean(-1, defaultBoolean));
assertEquals(defaultBoolean, list.getBoolean(3, defaultBoolean)); assertEquals(defaultBoolean, list.getBoolean(3, defaultBoolean));
Long defaultLong = random.nextLong(); Long defaultLong = 123L;
assertEquals(defaultLong, list.getLong(-1, defaultLong)); assertEquals(defaultLong, list.getLong(-1, defaultLong));
assertEquals(defaultLong, list.getLong(3, defaultLong)); assertEquals(defaultLong, list.getLong(3, defaultLong));
Double defaultDouble = random.nextDouble(); Double defaultDouble = 1.23;
assertEquals(defaultDouble, list.getDouble(-1, defaultDouble)); assertEquals(defaultDouble, list.getDouble(-1, defaultDouble));
assertEquals(defaultDouble, list.getDouble(3, defaultDouble)); assertEquals(defaultDouble, list.getDouble(3, defaultDouble));
String defaultString = getRandomString(123); String defaultString = "123";
assertEquals(defaultString, list.getString(-1, defaultString)); assertEquals(defaultString, list.getString(-1, defaultString));
assertEquals(defaultString, list.getString(3, defaultString)); assertEquals(defaultString, list.getString(3, defaultString));
byte[] defaultBytes = getRandomBytes(123); byte[] defaultBytes = new byte[] {1, 2, 3};
assertArrayEquals(defaultBytes, list.getRaw(-1, defaultBytes)); assertArrayEquals(defaultBytes, list.getRaw(-1, defaultBytes));
assertArrayEquals(defaultBytes, list.getRaw(3, defaultBytes)); assertArrayEquals(defaultBytes, list.getRaw(3, defaultBytes));
BdfList defaultList = BdfList.of(1, 2, 3); BdfList defaultList = BdfList.of(1, 2, 3);
@@ -99,17 +95,18 @@ public class BdfListTest extends BrambleTestCase {
} }
@Test @Test
public void testWrongTypeReturnsDefaultValue() { @SuppressWarnings("ConstantConditions")
public void testWrongTypeReturnsDefaultValue() throws Exception {
BdfList list = BdfList.of(1, 2, 3, true); BdfList list = BdfList.of(1, 2, 3, true);
boolean defaultBoolean = random.nextBoolean(); boolean defaultBoolean = true;
assertEquals(defaultBoolean, list.getBoolean(0, defaultBoolean)); assertEquals(defaultBoolean, list.getBoolean(0, defaultBoolean));
Long defaultLong = random.nextLong(); Long defaultLong = 123L;
assertEquals(defaultLong, list.getLong(3, defaultLong)); assertEquals(defaultLong, list.getLong(3, defaultLong));
Double defaultDouble = random.nextDouble(); Double defaultDouble = 1.23;
assertEquals(defaultDouble, list.getDouble(0, defaultDouble)); assertEquals(defaultDouble, list.getDouble(0, defaultDouble));
String defaultString = getRandomString(123); String defaultString = "123";
assertEquals(defaultString, list.getString(0, defaultString)); assertEquals(defaultString, list.getString(0, defaultString));
byte[] defaultBytes = getRandomBytes(123); byte[] defaultBytes = new byte[] {1, 2, 3};
assertArrayEquals(defaultBytes, list.getRaw(0, defaultBytes)); assertArrayEquals(defaultBytes, list.getRaw(0, defaultBytes));
BdfList defaultList = BdfList.of(1, 2, 3); BdfList defaultList = BdfList.of(1, 2, 3);
assertEquals(defaultList, list.getList(0, defaultList)); assertEquals(defaultList, list.getList(0, defaultList));

View File

@@ -1,42 +0,0 @@
package org.briarproject.bramble.api.identity;
import org.briarproject.bramble.test.BrambleTestCase;
import org.junit.Test;
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.NONE;
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.VERIFIED;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
public class AuthorInfoTest extends BrambleTestCase {
@Test
public void testEquals() {
assertEquals(
new AuthorInfo(NONE),
new AuthorInfo(NONE, null)
);
assertEquals(
new AuthorInfo(NONE, "test"),
new AuthorInfo(NONE, "test")
);
assertNotEquals(
new AuthorInfo(NONE),
new AuthorInfo(VERIFIED)
);
assertNotEquals(
new AuthorInfo(NONE, "test"),
new AuthorInfo(NONE)
);
assertNotEquals(
new AuthorInfo(NONE),
new AuthorInfo(NONE, "test")
);
assertNotEquals(
new AuthorInfo(NONE, "a"),
new AuthorInfo(NONE, "b")
);
}
}

View File

@@ -1,23 +0,0 @@
package org.briarproject.bramble.test;
import org.briarproject.bramble.api.system.Clock;
public class ArrayClock implements Clock {
private final long[] times;
private int index = 0;
public ArrayClock(long... times) {
this.times = times;
}
@Override
public long currentTimeMillis() {
return times[index++];
}
@Override
public void sleep(long milliseconds) throws InterruptedException {
Thread.sleep(milliseconds);
}
}

View File

@@ -1,24 +0,0 @@
package org.briarproject.bramble.test;
import org.briarproject.bramble.api.system.Clock;
import java.util.concurrent.atomic.AtomicLong;
public class SettableClock implements Clock {
private final AtomicLong time;
public SettableClock(AtomicLong time) {
this.time = time;
}
@Override
public long currentTimeMillis() {
return time.get();
}
@Override
public void sleep(long milliseconds) throws InterruptedException {
Thread.sleep(milliseconds);
}
}

View File

@@ -12,18 +12,18 @@ import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message; 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.util.IoUtils;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; 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 java.util.Collections.sort;
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;
@@ -32,7 +32,7 @@ import static org.briarproject.bramble.api.properties.TransportPropertyConstants
import static org.briarproject.bramble.api.sync.ClientId.MAX_CLIENT_ID_LENGTH; import static org.briarproject.bramble.api.sync.ClientId.MAX_CLIENT_ID_LENGTH;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH; import static org.briarproject.bramble.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH; import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
import static org.briarproject.bramble.util.IoUtils.deleteFileOrDir; import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
import static org.briarproject.bramble.util.StringUtils.getRandomString; import static org.briarproject.bramble.util.StringUtils.getRandomString;
public class TestUtils { public class TestUtils {
@@ -40,7 +40,6 @@ 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();
@@ -48,10 +47,8 @@ public class TestUtils {
} }
public static void deleteTestDirectory(File testDir) { public static void deleteTestDirectory(File testDir) {
deleteFileOrDir(testDir); IoUtils.deleteFileOrDir(testDir);
// Delete parent directory only if it's empty testDir.getParentFile().delete(); // Delete if empty
//noinspection ResultOfMethodCallIgnored
testDir.getParentFile().delete();
} }
public static byte[] getRandomBytes(int length) { public static byte[] getRandomBytes(int length) {
@@ -104,8 +101,9 @@ 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,
timestamp); created);
} }
public static Author getAuthor() { public static Author getAuthor() {
@@ -133,13 +131,14 @@ public class TestUtils {
public static Message getMessage(GroupId groupId) { public static Message getMessage(GroupId groupId) {
int bodyLength = 1 + random.nextInt(MAX_MESSAGE_BODY_LENGTH); int bodyLength = 1 + random.nextInt(MAX_MESSAGE_BODY_LENGTH);
return getMessage(groupId, bodyLength); return getMessage(groupId, MESSAGE_HEADER_LENGTH + bodyLength);
} }
public static Message getMessage(GroupId groupId, int bodyLength) { public static Message getMessage(GroupId groupId, int rawLength) {
MessageId id = new MessageId(getRandomId()); MessageId id = new MessageId(getRandomId());
byte[] body = getRandomBytes(bodyLength); byte[] raw = getRandomBytes(rawLength);
return new Message(id, groupId, timestamp, body); long timestamp = System.currentTimeMillis();
return new Message(id, groupId, timestamp, raw);
} }
public static double getMedian(Collection<? extends Number> samples) { public static double getMedian(Collection<? extends Number> samples) {
@@ -147,7 +146,7 @@ public class TestUtils {
if (size == 0) throw new IllegalArgumentException(); if (size == 0) throw new IllegalArgumentException();
List<Double> sorted = new ArrayList<>(size); List<Double> sorted = new ArrayList<>(size);
for (Number n : samples) sorted.add(n.doubleValue()); for (Number n : samples) sorted.add(n.doubleValue());
sort(sorted); Collections.sort(sorted);
if (size % 2 == 1) return sorted.get(size / 2); if (size % 2 == 1) return sorted.get(size / 2);
double low = sorted.get(size / 2 - 1), high = sorted.get(size / 2); double low = sorted.get(size / 2 - 1), high = sorted.get(size / 2);
return (low + high) / 2; return (low + high) / 2;
@@ -175,10 +174,4 @@ 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

@@ -2,7 +2,7 @@ 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.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7', 'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
'com.google.dagger:dagger:2.19:dagger-2.19.jar:514b6f1e0727c6572e1d65cb27e4ae668b7aeaeb93a29515182965265b609939', 'com.google.dagger:dagger:2.0.2:dagger-2.0.2.jar:84c0282ed8be73a29e0475d639da030b55dee72369e58dd35ae7d4fe6243dcf9',
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff', 'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
'junit:junit:4.12:junit-4.12.jar:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a', 'junit:junit:4.12:junit-4.12.jar:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a',
'org.apache.ant:ant-launcher:1.9.4:ant-launcher-1.9.4.jar:7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d', 'org.apache.ant:ant-launcher:1.9.4:ant-launcher-1.9.4.jar:7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d',

View File

@@ -3,10 +3,10 @@ sourceCompatibility = 1.8
targetCompatibility = 1.8 targetCompatibility = 1.8
apply plugin: 'ru.vyarus.animalsniffer' apply plugin: 'ru.vyarus.animalsniffer'
apply plugin: 'net.ltgt.apt'
apply plugin: 'idea' apply plugin: 'idea'
apply plugin: 'witness' apply plugin: 'witness'
apply from: 'witness.gradle' apply from: 'witness.gradle'
apply from: '../dagger.gradle'
dependencies { dependencies {
implementation project(path: ':bramble-api', configuration: 'default') implementation project(path: ':bramble-api', configuration: 'default')
@@ -14,10 +14,10 @@ dependencies {
implementation 'com.h2database:h2:1.4.192' // The last version that supports Java 1.6 implementation 'com.h2database:h2:1.4.192' // The last version that supports Java 1.6
implementation 'org.bitlet:weupnp:0.1.4' implementation 'org.bitlet:weupnp:0.1.4'
implementation 'net.i2p.crypto:eddsa:0.2.0' implementation 'net.i2p.crypto:eddsa:0.2.0'
implementation 'org.whispersystems:curve25519-java:0.5.0' implementation 'org.whispersystems:curve25519-java:0.4.1'
implementation 'org.briarproject:jtorctl:0.3' implementation 'org.briarproject:jtorctl:0.3'
annotationProcessor 'com.google.dagger:dagger-compiler:2.19' apt 'com.google.dagger:dagger-compiler:2.0.2'
testImplementation project(path: ':bramble-api', configuration: 'testOutput') testImplementation project(path: ':bramble-api', configuration: 'testOutput')
testImplementation 'org.hsqldb:hsqldb:2.3.5' // The last version that supports Java 1.6 testImplementation 'org.hsqldb:hsqldb:2.3.5' // The last version that supports Java 1.6
@@ -25,13 +25,15 @@ dependencies {
testImplementation "org.jmock:jmock:2.8.2" testImplementation "org.jmock:jmock:2.8.2"
testImplementation "org.jmock:jmock-junit4:2.8.2" testImplementation "org.jmock:jmock-junit4:2.8.2"
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-core:1.3"
testAnnotationProcessor 'com.google.dagger:dagger-compiler:2.19' testApt 'com.google.dagger:dagger-compiler:2.0.2'
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-java // needed to make test output available to bramble-j2se
configurations { configurations {
testOutput.extendsFrom(testCompile) testOutput.extendsFrom(testCompile)
} }
@@ -42,3 +44,8 @@ task jarTest(type: Jar, dependsOn: testClasses) {
artifacts { artifacts {
testOutput jarTest testOutput jarTest
} }
tasks.withType(Test) {
// Use entropy-gathering device specified on command line, if any
systemProperty 'java.security.egd', System.getProperty('java.security.egd')
}

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