Compare commits

..

6 Commits

Author SHA1 Message Date
Torsten Grote
2d5f5d4419 WIP: FakeTestData proof-of-concept 2018-09-19 10:51:47 -03:00
Torsten Grote
8393513871 Remove code from TestDataCreator that breaks encapsulation 2018-09-19 10:50:09 -03:00
Torsten Grote
38270fbee8 Throw AssertionError when creating an account while a database key is in memory 2018-09-18 17:53:41 -03:00
Torsten Grote
65c0646812 Refactor tests so that all test data is created in the first test 2018-09-18 17:41:40 -03:00
Torsten Grote
0416583e8c Split up UI and Screenshot tests
Closes #1377
2018-09-18 17:41:40 -03:00
Torsten Grote
91f8c801b8 Create Screenshot of Conversation for Manual 2018-09-18 17:41:40 -03:00
623 changed files with 8868 additions and 14184 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

@@ -24,7 +24,6 @@
<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-java" run_configuration_type="AndroidJUnit" />
<option name="RunConfigurationTask" enabled="true" run_configuration_name="All tests in briar-core" run_configuration_type="AndroidJUnit" /> <option name="RunConfigurationTask" enabled="true" run_configuration_name="All tests in briar-core" run_configuration_type="AndroidJUnit" />
<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,5 +1,6 @@
<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-java" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="bramble-java" /> <module name="bramble-java" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" /> <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" /> <option name="ALTERNATIVE_JRE_PATH" />
@@ -10,10 +11,12 @@
<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-java" />
<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 10101
versionName "1.1.5" versionName "1.1.1"
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,13 @@ 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"
} }
def torBinariesDir = 'src/main/res/raw' project.afterEvaluate {
copy {
task cleanTorBinaries { from configurations.tor.collect { zipTree(it) }
doLast { into 'src/main/res/raw'
delete fileTree(torBinariesDir) { include '*.zip' }
} }
} }
clean.dependsOn cleanTorBinaries
task unpackTorBinaries {
doLast {
copy {
from configurations.tor.collect { zipTree(it) }
into torBinariesDir
}
}
dependsOn cleanTorBinaries
}
tasks.withType(MergeResources) {
inputs.dir torBinariesDir
dependsOn unpackTorBinaries
}

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

@@ -1,84 +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.BATTERY_STATUS_CHARGING;
import static android.os.BatteryManager.BATTERY_STATUS_FULL;
import static android.os.BatteryManager.EXTRA_STATUS;
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_STATUS, -1);
return status == BATTERY_STATUS_CHARGING ||
status == BATTERY_STATUS_FULL;
}
@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

@@ -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,27 +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.Collections;
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;
@@ -46,12 +37,8 @@ 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.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 org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress; import static org.briarproject.bramble.util.LogUtils.logException;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
@@ -60,11 +47,8 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
private static final Logger LOG = private static final Logger LOG =
Logger.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;
@@ -74,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
@@ -160,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
@@ -190,77 +177,17 @@ 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 {
if (LOG.isLoggable(INFO))
LOG.info("Connecting to " + scrubMacAddress(address));
return connectTo(address, uuid);
} catch (IOException e) {
if (LOG.isLoggable(INFO)) {
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 { try {
if (adapter.startDiscovery()) { if (c != null) c.close();
long now = clock.currentTimeMillis(); } catch (IOException e) {
long end = now + MAX_DISCOVERY_MS; logException(LOG, WARNING, e);
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
Collections.shuffle(addresses);
return addresses;
} }
private class BluetoothStateReceiver extends BroadcastReceiver { private class BluetoothStateReceiver extends BroadcastReceiver {
@@ -280,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

@@ -6,7 +6,6 @@ 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.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
@@ -42,18 +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)
appContext.getSystemService(POWER_SERVICE); appContext.getSystemService(POWER_SERVICE);
if (pm == null) throw new AssertionError(); 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

@@ -3,7 +3,6 @@ package org.briarproject.bramble.plugin.tor;
import android.content.Context; import android.content.Context;
import android.os.Build; 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;
@@ -49,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,
@@ -57,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;
@@ -69,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;
} }
@@ -108,8 +104,8 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
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

@@ -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;
@@ -27,7 +26,7 @@ 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;
@@ -38,7 +37,6 @@ 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);
@@ -51,14 +49,12 @@ class AndroidSecureRandomProvider extends UnixSecureRandomProvider {
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) {
@@ -81,13 +77,13 @@ class AndroidSecureRandomProvider extends UnixSecureRandomProvider {
// 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( byte[] seed = new LinuxSecureRandomSpi().engineGenerateSeed(
SEED_LENGTH); 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

@@ -11,12 +11,15 @@ import java.util.ArrayList;
import java.util.Arrays; 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.VERSION.SDK_INT;
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";
@@ -25,7 +28,7 @@ public class AndroidUtils {
@SuppressWarnings("deprecation") @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(Arrays.asList(Build.SUPPORTED_ABIS)); abis.addAll(Arrays.asList(Build.SUPPORTED_ABIS));
} else { } else {
abis.add(Build.CPU_ABI); abis.add(Build.CPU_ABI);

View File

@@ -1,57 +1,50 @@
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.tools.analytics-library:protos:26.1.3:protos-26.1.3.jar:818c9f256f141d9dafec03a1aa2b94d240b2c140acfd7ee31a8b3e6c2b9479e3',
'com.android.tools.analytics-library:shared:26.2.1:shared-26.2.1.jar:4c1e4e705fa4d45f23aaea230557f6508155012d9c296337787c1d7b26a97f5a', 'com.android.tools.analytics-library:shared:26.1.3:shared-26.1.3.jar:7110706c7ada96c8b6f5ca80c478291bc7899d46277de2c48527e045442401a3',
'com.android.tools.analytics-library:tracker:26.2.1:tracker-26.2.1.jar:4a624ecc976539f755ddb0bb8dfc2dd3d08326cfec59a098dbd70f701ca7fb75', 'com.android.tools.analytics-library:tracker:26.1.3:tracker-26.1.3.jar:4155424bf2ce4872da83332579a1707252bc66cbd77c5144fdc4483d0f2e1418',
'com.android.tools.build:aapt2:3.2.1-4818971:aapt2-3.2.1-4818971-linux.jar:f431b6f96c91a2c155144b091a9c97d9805c589fe8efc9c930b6cd346cb60a1e', 'com.android.tools.build:apksig:3.1.3:apksig-3.1.3.jar:7e1f8e675a6e768e5b56405e41d6c3cc05befe62e601b04177de1029902c9c89',
'com.android.tools.build:apksig:3.2.1:apksig-3.2.1.jar:2b46f2feffea66037aab29e4261b2433c190194a6ef97b958511eb157f2ccba5', 'com.android.tools.build:builder-model:3.1.3:builder-model-3.1.3.jar:06ad1c422d679fc698451479cb40ba863849d67bfd1de23f6d2c16d78b024b0b',
'com.android.tools.build:apkzlib:3.2.1:apkzlib-3.2.1.jar:c39ad0313905932431fe81c8899c2cf39a4d92ad6c4edcaa4b25432f461452aa', 'com.android.tools.build:builder-test-api:3.1.3:builder-test-api-3.1.3.jar:4d989f780436794f0f8b2f50e9e079b786571eac90f26c208ab2ae6d4012f389',
'com.android.tools.build:builder-model:3.2.1:builder-model-3.2.1.jar:a9f68e6abcec122f9cb5ad352d3f05a3eb03acbcdca95e4d25c16310c2c965ff', 'com.android.tools.build:builder:3.1.3:builder-3.1.3.jar:8a1092012c89d0ec1ee2eff09c5708c71ef4482a6862df8d3a44a67fccace01c',
'com.android.tools.build:builder-test-api:3.2.1:builder-test-api-3.2.1.jar:533ac6c2b5884bb54967a33791f2628dfdfac7981af39417a333b43d4379b6be', 'com.android.tools.build:gradle-api:3.1.3:gradle-api-3.1.3.jar:01e4df521456aef66514336f1d492346730dd1fb8f6433a89f62da834941ed72',
'com.android.tools.build:builder:3.2.1:builder-3.2.1.jar:aedcbfd115dbe91d09b4113e66ef50589b558d0aa3b2f133b1d867c9b87fae83', 'com.android.tools.build:manifest-merger:26.1.3:manifest-merger-26.1.3.jar:1e4fc7e932adb4607082409800e5e6fccb42e6c5360ae5990094bf522f3ada55',
'com.android.tools.build:gradle-api:3.2.1:gradle-api-3.2.1.jar:57cf0ac5ac1dca8afdb3f62b94265e776e7dcfa641cc3844fb53a05193de208d', 'com.android.tools.ddms:ddmlib:26.1.3:ddmlib-26.1.3.jar:c54931cd68df5d1ea2923b3b320eae47cd2307a5a916bb8674c0acf93cd1d3cd',
'com.android.tools.build:manifest-merger:26.2.1:manifest-merger-26.2.1.jar:8830573263361035d38cfdcb51e2db94029c93865b21334f5fbf8a27984281a6', 'com.android.tools.external.com-intellij:intellij-core:26.1.3:intellij-core-26.1.3.jar:af67f5535fef2e1a28b1007a4acb8c5deb6a1e33b8afe7b11d012c9e778ebcec',
'com.android.tools.ddms:ddmlib:26.2.1:ddmlib-26.2.1.jar:a4bf0a29a19980bf27269465cc782064656750b77c26728f82f9e148b705218b', 'com.android.tools.external.com-intellij:kotlin-compiler:26.1.3:kotlin-compiler-26.1.3.jar:c746d2859dc11cc05c84b692b3498d3a621e0929511f8440ee009c6557838fd4',
'com.android.tools.external.com-intellij:intellij-core:26.2.1:intellij-core-26.2.1.jar:4925ad1892c2687cb1a63427d440ef519c8c59215fefe0dc5d541d5d411fcafe', 'com.android.tools.external.org-jetbrains:uast:26.1.3:uast-26.1.3.jar:3f3f6651d0c7685a77ecb22e9c82d6b49fdf24322c17360768dc530678f43265',
'com.android.tools.external.com-intellij:kotlin-compiler:26.2.1:kotlin-compiler-26.2.1.jar:daa064fd708f340ee25fb9823c4c74104ac77f1370b76d907eb9ae6daec0a2ae', 'com.android.tools.layoutlib:layoutlib-api:26.1.3:layoutlib-api-26.1.3.jar:10bc73ce706c45629872d6a999dbe12116df64e24f47ff93b7b13121ff57b4b0',
'com.android.tools.external.org-jetbrains:uast:26.2.1:uast-26.2.1.jar:f10f7258d2ab9189562cc0f9ad838c0378fdba439229173390a99de02ebac75b', 'com.android.tools.lint:lint-api:26.1.3:lint-api-26.1.3.jar:6f97323f9af8deda86278717885b5c927f3766757db89709f52d11d42b6fb751',
'com.android.tools.layoutlib:layoutlib-api:26.2.1:layoutlib-api-26.2.1.jar:ddbf4fca123733fa011595b1cc1f4ac2937ed327b60990711fafc33c775c2ade', 'com.android.tools.lint:lint-checks:26.1.3:lint-checks-26.1.3.jar:73c3d53784c9ce3e6d5968506581918e0179645d20809927ca4a001dd766b001',
'com.android.tools.lint:lint-api:26.2.1:lint-api-26.2.1.jar:3b57e739de567b98bc9ab56c2c0ee66fc026b4adf5843e8f9804ca0666a6f66e', 'com.android.tools.lint:lint-gradle-api:26.1.3:lint-gradle-api-26.1.3.jar:7ca3c4866ec21dc21d53a9d86f752b77ace6f6c610a0c9dc877313856c733d9d',
'com.android.tools.lint:lint-checks:26.2.1:lint-checks-26.2.1.jar:c86f4cc9aaee722ee4ad70062f7b5af91e9b041914af27adc09f545ab0fb3bc6', 'com.android.tools.lint:lint-gradle:26.1.3:lint-gradle-26.1.3.jar:db0c354b8f4b6f6637e31f91c564785a59ff896325331fcbc3de7458e0b6c067',
'com.android.tools.lint:lint-gradle-api:26.2.1:lint-gradle-api-26.2.1.jar:2283e7af32e301565f2a797e531f0fc8c648077d457afb3ffdddbee638976c2f', 'com.android.tools.lint:lint-kotlin:26.1.3:lint-kotlin-26.1.3.jar:94e2b0f4565a241561cfb8fc1222bb3f132a3b98d2a90421dbb72ee8358e7d68',
'com.android.tools.lint:lint-gradle:26.2.1:lint-gradle-26.2.1.jar:8fd90b2f3ec788cbb9801c07ab3e1ea2255aa31a6093157d7ea0ff13d0315ecb', 'com.android.tools.lint:lint:26.1.3:lint-26.1.3.jar:8d5f32c989c6d191d712e90ad3ca2d1c409313599551d04d834caa44d26c78df',
'com.android.tools.lint:lint-kotlin:26.2.1:lint-kotlin-26.2.1.jar:7a6a5d2b18f69cf1b900d857c2632b4c683713c533295933b8b759f8cab4a877', 'com.android.tools:annotations:26.1.3:annotations-26.1.3.jar:c950430b24ac5d58fc97e7283b8f0115f99587e76e08b4e1e2aaa780f2d77323',
'com.android.tools.lint:lint:26.2.1:lint-26.2.1.jar:7848b82ae988b90dee259ae7c7e86e05cbf52db6cd21c8bbd38ce7df08f3f8c5', 'com.android.tools:common:26.1.3:common-26.1.3.jar:7c31a90581a148ab219f615a59667f0dded7fa39b248529784474da3c2274ef2',
'com.android.tools:annotations:26.2.1:annotations-26.2.1.jar:7391c6a1e080174b96e64ceb078dadd31ce4d8a2d2fee0ec65be202126f90f24', 'com.android.tools:dvlib:26.1.3:dvlib-26.1.3.jar:0cae87906f53d3f1088366a916ed180a7312b6d9919b90797f238875c8492855',
'com.android.tools:common:26.2.1:common-26.2.1.jar:a50aab2d6411ff68f4004a87c7e93d87d8e980a0ec3b352246549897ea2d78e5', 'com.android.tools:repository:26.1.3:repository-26.1.3.jar:52d4539cc68db91b261e2a33b2c8206b26e05539078758dc28cfb3854adb4f59',
'com.android.tools:dvlib:26.2.1:dvlib-26.2.1.jar:72a83bf2839b1df9b1fbf67ba45d1bfb9f966cd774da4320c762b2be8f1688aa', 'com.android.tools:sdk-common:26.1.3:sdk-common-26.1.3.jar:1948603ca9ff22c7ebb3178000bffa3a9dd2ca1cc5cb0c793cae08468b8fcfc1',
'com.android.tools:repository:26.2.1:repository-26.2.1.jar:fa74dae09103faef703df38550ad8fa244c5b6d1bf90d6198be932292b3d9cc1', 'com.android.tools:sdklib:26.1.3:sdklib-26.1.3.jar:4adcfaad9514607098d2c51503c39811112d3050f4d1e744c01c7f08f591032b',
'com.android.tools:sdk-common:26.2.1:sdk-common-26.2.1.jar:759d4b292ca69a35cf961fca377b54158fc6c88108978006999442e80a011cf4',
'com.android.tools:sdklib:26.2.1:sdklib-26.2.1.jar:248df7ad5eac4aeb6f96c394c76760de4b7b89ac056e54d0c21a739368b91b45',
'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 +55,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 +70,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 +81,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'
} }

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

@@ -9,7 +9,7 @@ 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;
@@ -48,8 +48,12 @@ 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[] body = m.getBody();
if (body.length == 0) {
throw new InvalidMessageException("Message is too short");
}
try { try {
BdfList bodyList = clientHelper.toList(m.getBody()); BdfList bodyList = clientHelper.toList(body);
BdfMessageContext result = validateMessage(m, g, bodyList); BdfMessageContext result = validateMessage(m, g, bodyList);
Metadata meta = metadataEncoder.encode(result.getDictionary()); Metadata meta = metadataEncoder.encode(result.getDictionary());
return new MessageContext(meta, result.getDependencies()); return new MessageContext(meta, result.getDependencies());

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,14 +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;
@NotNullByDefault @NotNullByDefault
public interface ContactManager { public interface ContactManager {
@@ -96,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
*/ */
@@ -120,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,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.
@@ -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

@@ -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

@@ -1,6 +1,5 @@
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 org.briarproject.bramble.util.StringUtils;
@@ -14,7 +13,11 @@ import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_K
*/ */
@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.

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

@@ -1,20 +0,0 @@
package org.briarproject.bramble.api.io;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.sync.tree.TreeHash;
import java.util.List;
public interface BlockSink {
/**
* Stores a block of the message with the given temporary ID.
*/
void putBlock(HashingId h, int blockNumber, byte[] data) throws DbException;
/**
* Sets the hash tree path of a previously stored block.
*/
void setPath(HashingId h, int blockNumber, List<TreeHash> path)
throws DbException;
}

View File

@@ -1,27 +0,0 @@
package org.briarproject.bramble.api.io;
import org.briarproject.bramble.api.UniqueId;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageId;
import javax.annotation.concurrent.ThreadSafe;
/**
* Type-safe wrapper for a byte array that uniquely identifies a
* {@link Message} while it's being hashed and the {@link MessageId} is not
* yet known.
*/
@ThreadSafe
@NotNullByDefault
public class HashingId extends UniqueId {
public HashingId(byte[] id) {
super(id);
}
@Override
public boolean equals(Object o) {
return o instanceof HashingId && super.equals(o);
}
}

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;

View File

@@ -16,7 +16,6 @@ public class Message {
private final byte[] body; private final byte[] body;
public Message(MessageId id, GroupId groupId, long timestamp, byte[] body) { public Message(MessageId id, GroupId groupId, long timestamp, byte[] body) {
if (body.length == 0) throw new IllegalArgumentException();
if (body.length > MAX_MESSAGE_BODY_LENGTH) if (body.length > MAX_MESSAGE_BODY_LENGTH)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
this.id = id; this.id = id;

View File

@@ -1,7 +1,6 @@
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.api.sync.tree.TreeHash;
@NotNullByDefault @NotNullByDefault
public interface MessageFactory { public interface MessageFactory {
@@ -11,6 +10,4 @@ public interface MessageFactory {
Message createMessage(byte[] raw); Message createMessage(byte[] raw);
byte[] getRawMessage(Message m); byte[] getRawMessage(Message m);
MessageId getMessageId(GroupId g, long timestamp, TreeHash rootHash);
} }

View File

@@ -24,12 +24,6 @@ public class MessageId extends UniqueId {
public static final String BLOCK_LABEL = public static final String BLOCK_LABEL =
"org.briarproject.bramble/MESSAGE_BLOCK"; "org.briarproject.bramble/MESSAGE_BLOCK";
/**
* Label for hashing two tree hashes to produce a parent.
*/
public static final String TREE_LABEL =
"org.briarproject.bramble/MESSAGE_TREE";
public MessageId(byte[] id) { public MessageId(byte[] id) {
super(id); super(id);
} }

View File

@@ -35,9 +35,4 @@ public interface SyncConstants {
* The maximum number of message IDs in an ack, offer or request record. * The maximum number of message IDs in an ack, offer or request record.
*/ */
int MAX_MESSAGE_IDS = MAX_RECORD_PAYLOAD_BYTES / UniqueId.LENGTH; int MAX_MESSAGE_IDS = MAX_RECORD_PAYLOAD_BYTES / UniqueId.LENGTH;
/**
* The maximum length of a message block in bytes.
*/
int MAX_BLOCK_LENGTH = 32 * 2014; // 32 KiB
} }

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,21 +0,0 @@
package org.briarproject.bramble.api.sync.tree;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public class LeafNode extends TreeNode {
public LeafNode(TreeHash hash, int blockNumber) {
super(hash, 0, blockNumber, blockNumber);
}
@Override
public TreeNode getLeftChild() {
throw new UnsupportedOperationException();
}
@Override
public TreeNode getRightChild() {
throw new UnsupportedOperationException();
}
}

View File

@@ -1,26 +0,0 @@
package org.briarproject.bramble.api.sync.tree;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public class ParentNode extends TreeNode {
private final TreeNode left, right;
public ParentNode(TreeHash hash, TreeNode left, TreeNode right) {
super(hash, Math.max(left.getHeight(), right.getHeight()) + 1,
left.getFirstBlockNumber(), right.getLastBlockNumber());
this.left = left;
this.right = right;
}
@Override
public TreeNode getLeftChild() {
return left;
}
@Override
public TreeNode getRightChild() {
return right;
}
}

View File

@@ -1,21 +0,0 @@
package org.briarproject.bramble.api.sync.tree;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.io.BlockSink;
import org.briarproject.bramble.api.io.HashingId;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.io.IOException;
import java.io.InputStream;
@NotNullByDefault
public interface StreamHasher {
/**
* Reads the given input stream, divides the data into blocks, stores
* the blocks and the resulting hash tree using the given block sink and
* temporary ID, and returns the hash tree.
*/
TreeNode hash(InputStream in, BlockSink sink, HashingId h)
throws IOException, DbException;
}

View File

@@ -1,24 +0,0 @@
package org.briarproject.bramble.api.sync.tree;
import org.briarproject.bramble.api.UniqueId;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.ThreadSafe;
/**
* Type-safe wrapper for a byte array that uniquely identifies a sequence of
* one or more message blocks.
*/
@ThreadSafe
@NotNullByDefault
public class TreeHash extends UniqueId {
public TreeHash(byte[] id) {
super(id);
}
@Override
public boolean equals(Object o) {
return o instanceof TreeHash && super.equals(o);
}
}

View File

@@ -1,11 +0,0 @@
package org.briarproject.bramble.api.sync.tree;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface TreeHasher {
LeafNode hashBlock(int blockNumber, byte[] data);
ParentNode mergeTrees(TreeNode left, TreeNode right);
}

View File

@@ -1,38 +0,0 @@
package org.briarproject.bramble.api.sync.tree;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public abstract class TreeNode {
private final TreeHash hash;
private final int height, firstBlockNumber, lastBlockNumber;
TreeNode(TreeHash hash, int height, int firstBlockNumber,
int lastBlockNumber) {
this.hash = hash;
this.height = height;
this.firstBlockNumber = firstBlockNumber;
this.lastBlockNumber = lastBlockNumber;
}
public TreeHash getHash() {
return hash;
}
public int getHeight() {
return height;
}
public int getFirstBlockNumber() {
return firstBlockNumber;
}
public int getLastBlockNumber() {
return lastBlockNumber;
}
public abstract TreeNode getLeftChild();
public abstract TreeNode getRightChild();
}

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

@@ -8,15 +8,12 @@ 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 org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault @NotNullByDefault
public class IoUtils { public class IoUtils {
@@ -57,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

@@ -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,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

@@ -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,8 +25,10 @@ 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'
} }

View File

@@ -8,7 +8,7 @@ import org.briarproject.bramble.lifecycle.LifecycleModule;
import org.briarproject.bramble.plugin.PluginModule; import org.briarproject.bramble.plugin.PluginModule;
import org.briarproject.bramble.properties.PropertiesModule; import org.briarproject.bramble.properties.PropertiesModule;
import org.briarproject.bramble.reporting.ReportingModule; import org.briarproject.bramble.reporting.ReportingModule;
import org.briarproject.bramble.sync.validation.ValidationModule; import org.briarproject.bramble.sync.SyncModule;
import org.briarproject.bramble.system.SystemModule; import org.briarproject.bramble.system.SystemModule;
import org.briarproject.bramble.transport.TransportModule; import org.briarproject.bramble.transport.TransportModule;
import org.briarproject.bramble.versioning.VersioningModule; import org.briarproject.bramble.versioning.VersioningModule;
@@ -31,11 +31,11 @@ public interface BrambleCoreEagerSingletons {
void inject(ReportingModule.EagerSingletons init); void inject(ReportingModule.EagerSingletons init);
void inject(SyncModule.EagerSingletons init);
void inject(SystemModule.EagerSingletons init); void inject(SystemModule.EagerSingletons init);
void inject(TransportModule.EagerSingletons init); void inject(TransportModule.EagerSingletons init);
void inject(ValidationModule.EagerSingletons init);
void inject(VersioningModule.EagerSingletons init); void inject(VersioningModule.EagerSingletons init);
} }

View File

@@ -19,7 +19,6 @@ import org.briarproject.bramble.reporting.ReportingModule;
import org.briarproject.bramble.settings.SettingsModule; import org.briarproject.bramble.settings.SettingsModule;
import org.briarproject.bramble.socks.SocksModule; import org.briarproject.bramble.socks.SocksModule;
import org.briarproject.bramble.sync.SyncModule; import org.briarproject.bramble.sync.SyncModule;
import org.briarproject.bramble.sync.validation.ValidationModule;
import org.briarproject.bramble.system.SystemModule; import org.briarproject.bramble.system.SystemModule;
import org.briarproject.bramble.transport.TransportModule; import org.briarproject.bramble.transport.TransportModule;
import org.briarproject.bramble.versioning.VersioningModule; import org.briarproject.bramble.versioning.VersioningModule;
@@ -48,7 +47,6 @@ import dagger.Module;
SyncModule.class, SyncModule.class,
SystemModule.class, SystemModule.class,
TransportModule.class, TransportModule.class,
ValidationModule.class,
VersioningModule.class VersioningModule.class
}) })
public class BrambleCoreModule { public class BrambleCoreModule {
@@ -62,9 +60,9 @@ public class BrambleCoreModule {
c.inject(new PluginModule.EagerSingletons()); c.inject(new PluginModule.EagerSingletons());
c.inject(new PropertiesModule.EagerSingletons()); c.inject(new PropertiesModule.EagerSingletons());
c.inject(new ReportingModule.EagerSingletons()); c.inject(new ReportingModule.EagerSingletons());
c.inject(new SyncModule.EagerSingletons());
c.inject(new SystemModule.EagerSingletons()); c.inject(new SystemModule.EagerSingletons());
c.inject(new TransportModule.EagerSingletons()); c.inject(new TransportModule.EagerSingletons());
c.inject(new ValidationModule.EagerSingletons());
c.inject(new VersioningModule.EagerSingletons()); c.inject(new VersioningModule.EagerSingletons());
} }
} }

View File

@@ -1,19 +0,0 @@
package org.briarproject.bramble.battery;
import org.briarproject.bramble.api.battery.BatteryManager;
import dagger.Module;
import dagger.Provides;
/**
* Provides a default implementation of {@link BatteryManager} for systems
* without batteries.
*/
@Module
public class DefaultBatteryManagerModule {
@Provides
BatteryManager provideBatteryManager() {
return () -> false;
}
}

View File

@@ -82,7 +82,13 @@ class ClientHelperImpl implements ClientHelper {
@Override @Override
public void addLocalMessage(Message m, BdfDictionary metadata, public void addLocalMessage(Message m, BdfDictionary metadata,
boolean shared) throws DbException, FormatException { boolean shared) throws DbException, FormatException {
db.transaction(false, txn -> addLocalMessage(txn, m, metadata, shared)); Transaction txn = db.startTransaction(false);
try {
addLocalMessage(txn, m, metadata, shared);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
} }
@Override @Override
@@ -107,7 +113,15 @@ class ClientHelperImpl implements ClientHelper {
@Override @Override
public Message getMessage(MessageId m) throws DbException { public Message getMessage(MessageId m) throws DbException {
return db.transactionWithResult(true, txn -> getMessage(txn, m)); Message message;
Transaction txn = db.startTransaction(true);
try {
message = getMessage(txn, m);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
return message;
} }
@Override @Override
@@ -118,7 +132,15 @@ class ClientHelperImpl implements ClientHelper {
@Override @Override
public BdfList getMessageAsList(MessageId m) throws DbException, public BdfList getMessageAsList(MessageId m) throws DbException,
FormatException { FormatException {
return db.transactionWithResult(true, txn -> getMessageAsList(txn, m)); BdfList list;
Transaction txn = db.startTransaction(true);
try {
list = getMessageAsList(txn, m);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
return list;
} }
@Override @Override
@@ -130,8 +152,15 @@ class ClientHelperImpl implements ClientHelper {
@Override @Override
public BdfDictionary getGroupMetadataAsDictionary(GroupId g) public BdfDictionary getGroupMetadataAsDictionary(GroupId g)
throws DbException, FormatException { throws DbException, FormatException {
return db.transactionWithResult(true, txn -> BdfDictionary dictionary;
getGroupMetadataAsDictionary(txn, g)); Transaction txn = db.startTransaction(true);
try {
dictionary = getGroupMetadataAsDictionary(txn, g);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
return dictionary;
} }
@Override @Override
@@ -144,8 +173,15 @@ class ClientHelperImpl implements ClientHelper {
@Override @Override
public BdfDictionary getMessageMetadataAsDictionary(MessageId m) public BdfDictionary getMessageMetadataAsDictionary(MessageId m)
throws DbException, FormatException { throws DbException, FormatException {
return db.transactionWithResult(true, txn -> BdfDictionary dictionary;
getMessageMetadataAsDictionary(txn, m)); Transaction txn = db.startTransaction(true);
try {
dictionary = getMessageMetadataAsDictionary(txn, m);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
return dictionary;
} }
@Override @Override
@@ -158,8 +194,15 @@ class ClientHelperImpl implements ClientHelper {
@Override @Override
public Map<MessageId, BdfDictionary> getMessageMetadataAsDictionary( public Map<MessageId, BdfDictionary> getMessageMetadataAsDictionary(
GroupId g) throws DbException, FormatException { GroupId g) throws DbException, FormatException {
return db.transactionWithResult(true, txn -> Map<MessageId, BdfDictionary> map;
getMessageMetadataAsDictionary(txn, g)); Transaction txn = db.startTransaction(true);
try {
map = getMessageMetadataAsDictionary(txn, g);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
return map;
} }
@Override @Override
@@ -176,8 +219,15 @@ class ClientHelperImpl implements ClientHelper {
public Map<MessageId, BdfDictionary> getMessageMetadataAsDictionary( public Map<MessageId, BdfDictionary> getMessageMetadataAsDictionary(
GroupId g, BdfDictionary query) throws DbException, GroupId g, BdfDictionary query) throws DbException,
FormatException { FormatException {
return db.transactionWithResult(true, txn -> Map<MessageId, BdfDictionary> map;
getMessageMetadataAsDictionary(txn, g, query)); Transaction txn = db.startTransaction(true);
try {
map = getMessageMetadataAsDictionary(txn, g, query);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
return map;
} }
@Override @Override
@@ -195,7 +245,13 @@ class ClientHelperImpl implements ClientHelper {
@Override @Override
public void mergeGroupMetadata(GroupId g, BdfDictionary metadata) public void mergeGroupMetadata(GroupId g, BdfDictionary metadata)
throws DbException, FormatException { throws DbException, FormatException {
db.transaction(false, txn -> mergeGroupMetadata(txn, g, metadata)); Transaction txn = db.startTransaction(false);
try {
mergeGroupMetadata(txn, g, metadata);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
} }
@Override @Override
@@ -207,7 +263,13 @@ class ClientHelperImpl implements ClientHelper {
@Override @Override
public void mergeMessageMetadata(MessageId m, BdfDictionary metadata) public void mergeMessageMetadata(MessageId m, BdfDictionary metadata)
throws DbException, FormatException { throws DbException, FormatException {
db.transaction(false, txn -> mergeMessageMetadata(txn, m, metadata)); Transaction txn = db.startTransaction(false);
try {
mergeMessageMetadata(txn, m, metadata);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
} }
@Override @Override

View File

@@ -13,6 +13,7 @@ import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.db.ContactExistsException; import org.briarproject.bramble.api.db.ContactExistsException;
import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DatabaseComponent;
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.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
@@ -157,8 +158,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
streamWriterFactory.createContactExchangeStreamWriter(out, streamWriterFactory.createContactExchangeStreamWriter(out,
alice ? aliceHeaderKey : bobHeaderKey); alice ? aliceHeaderKey : bobHeaderKey);
RecordWriter recordWriter = RecordWriter recordWriter =
recordWriterFactory recordWriterFactory.createRecordWriter(streamWriter.getOutputStream());
.createRecordWriter(streamWriter.getOutputStream());
// Derive the nonces to be signed // Derive the nonces to be signed
byte[] aliceNonce = crypto.mac(ALICE_NONCE_LABEL, masterSecret, byte[] aliceNonce = crypto.mac(ALICE_NONCE_LABEL, masterSecret,
@@ -287,14 +287,19 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
private ContactId addContact(Author remoteAuthor, long timestamp, private ContactId addContact(Author remoteAuthor, long timestamp,
Map<TransportId, TransportProperties> remoteProperties) Map<TransportId, TransportProperties> remoteProperties)
throws DbException { throws DbException {
return db.transactionWithResult(false, txn -> { ContactId contactId;
ContactId contactId = contactManager.addContact(txn, remoteAuthor, Transaction txn = db.startTransaction(false);
try {
contactId = contactManager.addContact(txn, remoteAuthor,
localAuthor.getId(), masterSecret, timestamp, alice, localAuthor.getId(), masterSecret, timestamp, alice,
true, true); true, true);
transportPropertyManager.addRemoteProperties(txn, contactId, transportPropertyManager.addRemoteProperties(txn, contactId,
remoteProperties); remoteProperties);
return contactId; db.commitTransaction(txn);
}); } finally {
db.endTransaction(txn);
}
return contactId;
} }
private void tryToClose(DuplexTransportConnection conn) { private void tryToClose(DuplexTransportConnection conn) {

View File

@@ -10,9 +10,6 @@ import org.briarproject.bramble.api.db.NoSuchContactException;
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.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.transport.KeyManager; import org.briarproject.bramble.api.transport.KeyManager;
@@ -21,32 +18,21 @@ import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe; import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject; import javax.inject.Inject;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.OURSELVES;
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.UNKNOWN;
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.UNVERIFIED;
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.VERIFIED;
import static org.briarproject.bramble.util.StringUtils.toUtf8;
@ThreadSafe @ThreadSafe
@NotNullByDefault @NotNullByDefault
class ContactManagerImpl implements ContactManager { class ContactManagerImpl implements ContactManager {
private final DatabaseComponent db; private final DatabaseComponent db;
private final KeyManager keyManager; private final KeyManager keyManager;
private final IdentityManager identityManager;
private final List<ContactHook> hooks; private final List<ContactHook> hooks;
@Inject @Inject
ContactManagerImpl(DatabaseComponent db, KeyManager keyManager, ContactManagerImpl(DatabaseComponent db, KeyManager keyManager) {
IdentityManager identityManager) {
this.db = db; this.db = db;
this.keyManager = keyManager; this.keyManager = keyManager;
this.identityManager = identityManager;
hooks = new CopyOnWriteArrayList<>(); hooks = new CopyOnWriteArrayList<>();
} }
@@ -79,21 +65,42 @@ class ContactManagerImpl implements ContactManager {
public ContactId addContact(Author remote, AuthorId local, SecretKey master, public ContactId addContact(Author remote, AuthorId local, SecretKey master,
long timestamp, boolean alice, boolean verified, boolean active) long timestamp, boolean alice, boolean verified, boolean active)
throws DbException { throws DbException {
return db.transactionWithResult(false, txn -> ContactId c;
addContact(txn, remote, local, master, timestamp, alice, Transaction txn = db.startTransaction(false);
verified, active)); try {
c = addContact(txn, remote, local, master, timestamp, alice,
verified, active);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
return c;
} }
@Override @Override
public Contact getContact(ContactId c) throws DbException { public Contact getContact(ContactId c) throws DbException {
return db.transactionWithResult(true, txn -> db.getContact(txn, c)); Contact contact;
Transaction txn = db.startTransaction(true);
try {
contact = db.getContact(txn, c);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
return contact;
} }
@Override @Override
public Contact getContact(AuthorId remoteAuthorId, AuthorId localAuthorId) public Contact getContact(AuthorId remoteAuthorId, AuthorId localAuthorId)
throws DbException { throws DbException {
return db.transactionWithResult(true, txn -> Transaction txn = db.startTransaction(true);
getContact(txn, remoteAuthorId, localAuthorId)); try {
Contact c = getContact(txn, remoteAuthorId, localAuthorId);
db.commitTransaction(txn);
return c;
} finally {
db.endTransaction(txn);
}
} }
@Override @Override
@@ -111,8 +118,14 @@ class ContactManagerImpl implements ContactManager {
@Override @Override
public Collection<Contact> getActiveContacts() throws DbException { public Collection<Contact> getActiveContacts() throws DbException {
Collection<Contact> contacts = Collection<Contact> contacts;
db.transactionWithResult(true, db::getContacts); Transaction txn = db.startTransaction(true);
try {
contacts = db.getContacts(txn);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
List<Contact> active = new ArrayList<>(contacts.size()); List<Contact> active = new ArrayList<>(contacts.size());
for (Contact c : contacts) if (c.isActive()) active.add(c); for (Contact c : contacts) if (c.isActive()) active.add(c);
return active; return active;
@@ -120,7 +133,13 @@ class ContactManagerImpl implements ContactManager {
@Override @Override
public void removeContact(ContactId c) throws DbException { public void removeContact(ContactId c) throws DbException {
db.transaction(false, txn -> removeContact(txn, c)); Transaction txn = db.startTransaction(false);
try {
removeContact(txn, c);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
} }
@Override @Override
@@ -129,23 +148,6 @@ class ContactManagerImpl implements ContactManager {
db.setContactActive(txn, c, active); db.setContactActive(txn, c, active);
} }
@Override
public void setContactAlias(Transaction txn, ContactId c,
@Nullable String alias) throws DbException {
if (alias != null) {
int aliasLength = toUtf8(alias).length;
if (aliasLength == 0 || aliasLength > MAX_AUTHOR_NAME_LENGTH)
throw new IllegalArgumentException();
}
db.setContactAlias(txn, c, alias);
}
@Override
public void setContactAlias(ContactId c, @Nullable String alias)
throws DbException {
db.transaction(false, txn -> setContactAlias(txn, c, alias));
}
@Override @Override
public boolean contactExists(Transaction txn, AuthorId remoteAuthorId, public boolean contactExists(Transaction txn, AuthorId remoteAuthorId,
AuthorId localAuthorId) throws DbException { AuthorId localAuthorId) throws DbException {
@@ -155,8 +157,15 @@ class ContactManagerImpl implements ContactManager {
@Override @Override
public boolean contactExists(AuthorId remoteAuthorId, public boolean contactExists(AuthorId remoteAuthorId,
AuthorId localAuthorId) throws DbException { AuthorId localAuthorId) throws DbException {
return db.transactionWithResult(true, txn -> boolean exists;
contactExists(txn, remoteAuthorId, localAuthorId)); Transaction txn = db.startTransaction(true);
try {
exists = contactExists(txn, remoteAuthorId, localAuthorId);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
return exists;
} }
@Override @Override
@@ -167,23 +176,4 @@ class ContactManagerImpl implements ContactManager {
db.removeContact(txn, c); db.removeContact(txn, c);
} }
@Override
public AuthorInfo getAuthorInfo(AuthorId a) throws DbException {
return db.transactionWithResult(true, txn -> getAuthorInfo(txn, a));
}
@Override
public AuthorInfo getAuthorInfo(Transaction txn, AuthorId authorId)
throws DbException {
LocalAuthor localAuthor = identityManager.getLocalAuthor(txn);
if (localAuthor.getId().equals(authorId))
return new AuthorInfo(OURSELVES);
Collection<Contact> contacts = db.getContactsByAuthorId(txn, authorId);
if (contacts.isEmpty()) return new AuthorInfo(UNKNOWN);
if (contacts.size() > 1) throw new AssertionError();
Contact c = contacts.iterator().next();
if (c.isVerified()) return new AuthorInfo(VERIFIED, c.getAlias());
else return new AuthorInfo(UNVERIFIED, c.getAlias());
}
} }

View File

@@ -29,7 +29,6 @@ import static org.briarproject.bramble.data.Types.STRING_16;
import static org.briarproject.bramble.data.Types.STRING_32; import static org.briarproject.bramble.data.Types.STRING_32;
import static org.briarproject.bramble.data.Types.STRING_8; import static org.briarproject.bramble.data.Types.STRING_8;
import static org.briarproject.bramble.data.Types.TRUE; import static org.briarproject.bramble.data.Types.TRUE;
import static org.briarproject.bramble.util.StringUtils.fromUtf8;
@NotThreadSafe @NotThreadSafe
@NotNullByDefault @NotNullByDefault
@@ -254,7 +253,7 @@ class BdfReaderImpl implements BdfReader {
if (length < 0 || length > maxBufferSize) throw new FormatException(); if (length < 0 || length > maxBufferSize) throw new FormatException();
if (length == 0) return ""; if (length == 0) return "";
readIntoBuffer(length); readIntoBuffer(length);
return fromUtf8(buf, 0, length); return new String(buf, 0, length, "UTF-8");
} }
private int readStringLength() throws IOException { private int readStringLength() throws IOException {

View File

@@ -22,7 +22,7 @@ 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.api.sync.MessageStatus; import org.briarproject.bramble.api.sync.MessageStatus;
import org.briarproject.bramble.api.sync.validation.MessageState; import org.briarproject.bramble.api.sync.ValidationManager.State;
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;
@@ -106,7 +106,7 @@ interface Database<T> {
* @param sender the contact from whom the message was received, or null * @param sender the contact from whom the message was received, or null
* if the message was created locally. * if the message was created locally.
*/ */
void addMessage(T txn, Message m, MessageState state, boolean shared, void addMessage(T txn, Message m, State state, boolean shared,
@Nullable ContactId sender) throws DbException; @Nullable ContactId sender) throws DbException;
/** /**
@@ -114,7 +114,7 @@ interface Database<T> {
* in the given state. * in the given state.
*/ */
void addMessageDependency(T txn, Message dependent, MessageId dependency, void addMessageDependency(T txn, Message dependent, MessageId dependency,
MessageState dependentState) throws DbException; State dependentState) throws DbException;
/** /**
* Records that a message has been offered by the given contact. * Records that a message has been offered by the given contact.
@@ -310,11 +310,11 @@ interface Database<T> {
/** /**
* 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(T txn, MessageId m) Map<MessageId, State> getMessageDependencies(T txn, MessageId m)
throws DbException; throws DbException;
/** /**
@@ -324,7 +324,7 @@ interface Database<T> {
* <p/> * <p/>
* Read-only. * Read-only.
*/ */
Map<MessageId, MessageState> getMessageDependents(T txn, MessageId m) Map<MessageId, State> getMessageDependents(T txn, MessageId m)
throws DbException; throws DbException;
/** /**
@@ -383,7 +383,7 @@ interface Database<T> {
* <p/> * <p/>
* Read-only. * Read-only.
*/ */
MessageState getMessageState(T txn, MessageId m) throws DbException; State getMessageState(T txn, MessageId m) throws DbException;
/** /**
* Returns the status of all delivered messages in the given group with * Returns the status of all delivered messages in the given group with
@@ -616,12 +616,6 @@ interface Database<T> {
void setContactActive(T txn, ContactId c, boolean active) void setContactActive(T txn, ContactId c, boolean active)
throws DbException; throws DbException;
/**
* Sets an alias name for a contact.
*/
void setContactAlias(T txn, ContactId c, @Nullable String alias)
throws DbException;
/** /**
* Sets the given group's visibility to the given contact to either * Sets the given group's visibility to the given contact to either
* {@link Visibility VISIBLE} or {@link Visibility SHARED}. * {@link Visibility VISIBLE} or {@link Visibility SHARED}.
@@ -637,8 +631,7 @@ interface Database<T> {
/** /**
* Sets the validation and delivery state of the given message. * Sets the validation and delivery state of the given message.
*/ */
void setMessageState(T txn, MessageId m, MessageState state) void setMessageState(T txn, MessageId m, State state) throws DbException;
throws DbException;
/** /**
* Sets the reordering window for the given key set and transport in the * Sets the reordering window for the given key set and transport in the

View File

@@ -9,9 +9,7 @@ import org.briarproject.bramble.api.contact.event.ContactVerifiedEvent;
import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.ContactExistsException; import org.briarproject.bramble.api.db.ContactExistsException;
import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbCallable;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.DbRunnable;
import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.db.MigrationListener; import org.briarproject.bramble.api.db.MigrationListener;
import org.briarproject.bramble.api.db.NoSuchContactException; import org.briarproject.bramble.api.db.NoSuchContactException;
@@ -19,7 +17,6 @@ import org.briarproject.bramble.api.db.NoSuchGroupException;
import org.briarproject.bramble.api.db.NoSuchLocalAuthorException; import org.briarproject.bramble.api.db.NoSuchLocalAuthorException;
import org.briarproject.bramble.api.db.NoSuchMessageException; import org.briarproject.bramble.api.db.NoSuchMessageException;
import org.briarproject.bramble.api.db.NoSuchTransportException; import org.briarproject.bramble.api.db.NoSuchTransportException;
import org.briarproject.bramble.api.db.NullableDbCallable;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.event.EventBus;
@@ -43,6 +40,7 @@ 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.ValidationManager.State;
import org.briarproject.bramble.api.sync.event.GroupAddedEvent; import org.briarproject.bramble.api.sync.event.GroupAddedEvent;
import org.briarproject.bramble.api.sync.event.GroupRemovedEvent; import org.briarproject.bramble.api.sync.event.GroupRemovedEvent;
import org.briarproject.bramble.api.sync.event.GroupVisibilityUpdatedEvent; import org.briarproject.bramble.api.sync.event.GroupVisibilityUpdatedEvent;
@@ -54,7 +52,6 @@ import org.briarproject.bramble.api.sync.event.MessageToAckEvent;
import org.briarproject.bramble.api.sync.event.MessageToRequestEvent; import org.briarproject.bramble.api.sync.event.MessageToRequestEvent;
import org.briarproject.bramble.api.sync.event.MessagesAckedEvent; import org.briarproject.bramble.api.sync.event.MessagesAckedEvent;
import org.briarproject.bramble.api.sync.event.MessagesSentEvent; import org.briarproject.bramble.api.sync.event.MessagesSentEvent;
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;
@@ -75,8 +72,8 @@ import javax.inject.Inject;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE; import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED; import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERED; import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED;
import static org.briarproject.bramble.api.sync.validation.MessageState.UNKNOWN; import static org.briarproject.bramble.api.sync.ValidationManager.State.UNKNOWN;
import static org.briarproject.bramble.db.DatabaseConstants.MAX_OFFERED_MESSAGES; import static org.briarproject.bramble.db.DatabaseConstants.MAX_OFFERED_MESSAGES;
import static org.briarproject.bramble.util.LogUtils.logDuration; import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.logException;
@@ -169,45 +166,6 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
for (Event e : transaction.getEvents()) eventBus.broadcast(e); for (Event e : transaction.getEvents()) eventBus.broadcast(e);
} }
@Override
public <E extends Exception> void transaction(boolean readOnly,
DbRunnable<E> task) throws DbException, E {
Transaction txn = startTransaction(readOnly);
try {
task.run(txn);
commitTransaction(txn);
} finally {
endTransaction(txn);
}
}
@Override
public <R, E extends Exception> R transactionWithResult(boolean readOnly,
DbCallable<R, E> task) throws DbException, E {
Transaction txn = startTransaction(readOnly);
try {
R result = task.call(txn);
commitTransaction(txn);
return result;
} finally {
endTransaction(txn);
}
}
@Override
public <R, E extends Exception> R transactionWithNullableResult(
boolean readOnly, NullableDbCallable<R, E> task)
throws DbException, E {
Transaction txn = startTransaction(readOnly);
try {
R result = task.call(txn);
commitTransaction(txn);
return result;
} finally {
endTransaction(txn);
}
}
private T unbox(Transaction transaction) { private T unbox(Transaction transaction) {
if (transaction.isCommitted()) throw new IllegalStateException(); if (transaction.isCommitted()) throw new IllegalStateException();
return txnClass.cast(transaction.unbox()); return txnClass.cast(transaction.unbox());
@@ -579,7 +537,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
} }
@Override @Override
public MessageState getMessageState(Transaction transaction, MessageId m) public State getMessageState(Transaction transaction, MessageId m)
throws DbException { throws DbException {
T txn = unbox(transaction); T txn = unbox(transaction);
if (!db.containsMessage(txn, m)) if (!db.containsMessage(txn, m))
@@ -619,8 +577,8 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
} }
@Override @Override
public Map<MessageId, MessageState> getMessageDependencies( public Map<MessageId, State> getMessageDependencies(Transaction transaction,
Transaction transaction, MessageId m) throws DbException { MessageId m) throws DbException {
T txn = unbox(transaction); T txn = unbox(transaction);
if (!db.containsMessage(txn, m)) if (!db.containsMessage(txn, m))
throw new NoSuchMessageException(); throw new NoSuchMessageException();
@@ -628,8 +586,8 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
} }
@Override @Override
public Map<MessageId, MessageState> getMessageDependents( public Map<MessageId, State> getMessageDependents(Transaction transaction,
Transaction transaction, MessageId m) throws DbException { MessageId m) throws DbException {
T txn = unbox(transaction); T txn = unbox(transaction);
if (!db.containsMessage(txn, m)) if (!db.containsMessage(txn, m))
throw new NoSuchMessageException(); throw new NoSuchMessageException();
@@ -874,16 +832,6 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
transaction.attach(new ContactStatusChangedEvent(c, active)); transaction.attach(new ContactStatusChangedEvent(c, active));
} }
@Override
public void setContactAlias(Transaction transaction, ContactId c,
@Nullable String alias) throws DbException {
if (transaction.isReadOnly()) throw new IllegalArgumentException();
T txn = unbox(transaction);
if (!db.containsContact(txn, c))
throw new NoSuchContactException();
db.setContactAlias(txn, c, alias);
}
@Override @Override
public void setGroupVisibility(Transaction transaction, ContactId c, public void setGroupVisibility(Transaction transaction, ContactId c,
GroupId g, Visibility v) throws DbException { GroupId g, Visibility v) throws DbException {
@@ -918,7 +866,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
@Override @Override
public void setMessageState(Transaction transaction, MessageId m, public void setMessageState(Transaction transaction, MessageId m,
MessageState state) throws DbException { State state) throws DbException {
if (transaction.isReadOnly()) throw new IllegalArgumentException(); if (transaction.isReadOnly()) throw new IllegalArgumentException();
T txn = unbox(transaction); T txn = unbox(transaction);
if (!db.containsMessage(txn, m)) if (!db.containsMessage(txn, m))
@@ -935,10 +883,10 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
T txn = unbox(transaction); T txn = unbox(transaction);
if (!db.containsMessage(txn, dependent.getId())) if (!db.containsMessage(txn, dependent.getId()))
throw new NoSuchMessageException(); throw new NoSuchMessageException();
MessageState dependentState = State dependentState = db.getMessageState(txn, dependent.getId());
db.getMessageState(txn, dependent.getId());
for (MessageId dependency : dependencies) { for (MessageId dependency : dependencies) {
db.addMessageDependency(txn, dependent, dependency, dependentState); db.addMessageDependency(txn, dependent, dependency,
dependentState);
} }
} }

View File

@@ -2,8 +2,6 @@ package org.briarproject.bramble.db;
import org.briarproject.bramble.api.settings.Settings; import org.briarproject.bramble.api.settings.Settings;
import static java.util.concurrent.TimeUnit.DAYS;
interface DatabaseConstants { interface DatabaseConstants {
/** /**
@@ -25,16 +23,4 @@ interface DatabaseConstants {
*/ */
String SCHEMA_VERSION_KEY = "schemaVersion"; String SCHEMA_VERSION_KEY = "schemaVersion";
/**
* The {@link Settings} key under which the time of the last database
* compaction is stored.
*/
String LAST_COMPACTED_KEY = "lastCompacted";
/**
* The maximum time between database compactions in milliseconds. When the
* database is opened it will be compacted if more than this amount of time
* has passed since the last compaction.
*/
long MAX_COMPACTION_INTERVAL_MS = DAYS.toMillis(30);
} }

View File

@@ -1,34 +0,0 @@
package org.briarproject.bramble.db;
class DatabaseTypes {
private final String hashType, secretType, binaryType;
private final String counterType, stringType;
public DatabaseTypes(String hashType, String secretType, String binaryType,
String counterType, String stringType) {
this.hashType = hashType;
this.secretType = secretType;
this.binaryType = binaryType;
this.counterType = counterType;
this.stringType = stringType;
}
/**
* Replaces database type placeholders in a statement with the actual types.
* These placeholders are currently supported:
* <li> _HASH
* <li> _SECRET
* <li> _BINARY
* <li> _COUNTER
* <li> _STRING
*/
String replaceTypes(String s) {
s = s.replaceAll("_HASH", hashType);
s = s.replaceAll("_SECRET", secretType);
s = s.replaceAll("_BINARY", binaryType);
s = s.replaceAll("_COUNTER", counterType);
s = s.replaceAll("_STRING", stringType);
return s;
}
}

View File

@@ -13,32 +13,22 @@ import java.io.File;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties; import java.util.Properties;
import java.util.logging.Logger;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
/** /**
* Contains all the H2-specific code for the database. * Contains all the H2-specific code for the database.
*/ */
@NotNullByDefault @NotNullByDefault
class H2Database extends JdbcDatabase { class H2Database extends JdbcDatabase {
private static final Logger LOG = getLogger(H2Database.class.getName());
private static final String HASH_TYPE = "BINARY(32)"; private static final String HASH_TYPE = "BINARY(32)";
private static final String SECRET_TYPE = "BINARY(32)"; private static final String SECRET_TYPE = "BINARY(32)";
private static final String BINARY_TYPE = "BINARY"; private static final String BINARY_TYPE = "BINARY";
private static final String COUNTER_TYPE = "INT NOT NULL AUTO_INCREMENT"; private static final String COUNTER_TYPE = "INT NOT NULL AUTO_INCREMENT";
private static final String STRING_TYPE = "VARCHAR"; private static final String STRING_TYPE = "VARCHAR";
private static final DatabaseTypes dbTypes = new DatabaseTypes(HASH_TYPE,
SECRET_TYPE, BINARY_TYPE, COUNTER_TYPE, STRING_TYPE);
private final DatabaseConfig config; private final DatabaseConfig config;
private final String url; private final String url;
@@ -49,7 +39,8 @@ class H2Database extends JdbcDatabase {
@Inject @Inject
H2Database(DatabaseConfig config, MessageFactory messageFactory, H2Database(DatabaseConfig config, MessageFactory messageFactory,
Clock clock) { Clock clock) {
super(dbTypes, messageFactory, clock); super(HASH_TYPE, SECRET_TYPE, BINARY_TYPE, COUNTER_TYPE, STRING_TYPE,
messageFactory, clock);
this.config = config; this.config = config;
File dir = config.getDatabaseDirectory(); File dir = config.getDatabaseDirectory();
String path = new File(dir, "db").getAbsolutePath(); String path = new File(dir, "db").getAbsolutePath();
@@ -115,22 +106,4 @@ class H2Database extends JdbcDatabase {
String getUrl() { String getUrl() {
return url; return url;
} }
@Override
protected void compactAndClose() throws DbException {
Connection c = null;
Statement s = null;
try {
c = createConnection();
closeAllConnections();
s = c.createStatement();
s.execute("SHUTDOWN COMPACT");
s.close();
c.close();
} catch (SQLException e) {
tryToClose(s, LOG, WARNING);
tryToClose(c, LOG, WARNING);
throw new DbException(e);
}
}
} }

View File

@@ -14,32 +14,22 @@ import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.logging.Logger;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
/** /**
* Contains all the HSQLDB-specific code for the database. * Contains all the HSQLDB-specific code for the database.
*/ */
@NotNullByDefault @NotNullByDefault
class HyperSqlDatabase extends JdbcDatabase { class HyperSqlDatabase extends JdbcDatabase {
private static final Logger LOG =
getLogger(HyperSqlDatabase.class.getName());
private static final String HASH_TYPE = "BINARY(32)"; private static final String HASH_TYPE = "BINARY(32)";
private static final String SECRET_TYPE = "BINARY(32)"; private static final String SECRET_TYPE = "BINARY(32)";
private static final String BINARY_TYPE = "BINARY"; private static final String BINARY_TYPE = "BINARY";
private static final String COUNTER_TYPE = private static final String COUNTER_TYPE =
"INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY(START WITH 1)"; "INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY(START WITH 1)";
private static final String STRING_TYPE = "VARCHAR"; private static final String STRING_TYPE = "VARCHAR";
private static final DatabaseTypes dbTypes = new DatabaseTypes(HASH_TYPE,
SECRET_TYPE, BINARY_TYPE, COUNTER_TYPE, STRING_TYPE);
private final DatabaseConfig config; private final DatabaseConfig config;
private final String url; private final String url;
@@ -50,7 +40,8 @@ class HyperSqlDatabase extends JdbcDatabase {
@Inject @Inject
HyperSqlDatabase(DatabaseConfig config, MessageFactory messageFactory, HyperSqlDatabase(DatabaseConfig config, MessageFactory messageFactory,
Clock clock) { Clock clock) {
super(dbTypes, messageFactory, clock); super(HASH_TYPE, SECRET_TYPE, BINARY_TYPE, COUNTER_TYPE, STRING_TYPE,
messageFactory, clock);
this.config = config; this.config = config;
File dir = config.getDatabaseDirectory(); File dir = config.getDatabaseDirectory();
String path = new File(dir, "db").getAbsolutePath(); String path = new File(dir, "db").getAbsolutePath();
@@ -70,24 +61,20 @@ class HyperSqlDatabase extends JdbcDatabase {
@Override @Override
public void close() throws DbException { public void close() throws DbException {
Connection c = null;
Statement s = null;
try { try {
super.closeAllConnections(); super.closeAllConnections();
c = createConnection(); Connection c = createConnection();
s = c.createStatement(); Statement s = c.createStatement();
s.executeQuery("SHUTDOWN"); s.executeQuery("SHUTDOWN");
s.close(); s.close();
c.close(); c.close();
} catch (SQLException e) { } catch (SQLException e) {
tryToClose(s, LOG, WARNING);
tryToClose(c, LOG, WARNING);
throw new DbException(e); throw new DbException(e);
} }
} }
@Override @Override
public long getFreeSpace() { public long getFreeSpace() throws DbException {
File dir = config.getDatabaseDirectory(); File dir = config.getDatabaseDirectory();
long maxSize = config.getMaxSize(); long maxSize = config.getMaxSize();
long free = dir.getFreeSpace(); long free = dir.getFreeSpace();
@@ -117,22 +104,4 @@ class HyperSqlDatabase extends JdbcDatabase {
String hex = StringUtils.toHexString(key.getBytes()); String hex = StringUtils.toHexString(key.getBytes());
return DriverManager.getConnection(url + ";crypt_key=" + hex); return DriverManager.getConnection(url + ";crypt_key=" + hex);
} }
@Override
protected void compactAndClose() throws DbException {
Connection c = null;
Statement s = null;
try {
super.closeAllConnections();
c = createConnection();
s = c.createStatement();
s.executeQuery("SHUTDOWN COMPACT");
s.close();
c.close();
} catch (SQLException e) {
tryToClose(s, LOG, WARNING);
tryToClose(c, LOG, WARNING);
throw new DbException(e);
}
}
} }

View File

@@ -1,42 +0,0 @@
package org.briarproject.bramble.db;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault
class JdbcUtils {
static void tryToClose(@Nullable ResultSet rs, Logger logger, Level level) {
try {
if (rs != null) rs.close();
} catch (SQLException e) {
logException(logger, level, e);
}
}
static void tryToClose(@Nullable Statement s, Logger logger, Level level) {
try {
if (s != null) s.close();
} catch (SQLException e) {
logException(logger, level, e);
}
}
static void tryToClose(@Nullable Connection c, Logger logger, Level level) {
try {
if (c != null) c.close();
} catch (SQLException e) {
logException(logger, level, e);
}
}
}

View File

@@ -7,8 +7,10 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.annotation.Nullable;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.db.JdbcUtils.tryToClose; import static org.briarproject.bramble.util.LogUtils.logException;
class Migration38_39 implements Migration<Connection> { class Migration38_39 implements Migration<Connection> {
@@ -38,8 +40,16 @@ class Migration38_39 implements Migration<Connection> {
+ " ALTER COLUMN contactId" + " ALTER COLUMN contactId"
+ " SET NOT NULL"); + " SET NOT NULL");
} catch (SQLException e) { } catch (SQLException e) {
tryToClose(s, LOG, WARNING); tryToClose(s);
throw new DbException(e); throw new DbException(e);
} }
} }
private void tryToClose(@Nullable Statement s) {
try {
if (s != null) s.close();
} catch (SQLException e) {
logException(LOG, WARNING, e);
}
}
} }

View File

@@ -7,8 +7,10 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.annotation.Nullable;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.db.JdbcUtils.tryToClose; import static org.briarproject.bramble.util.LogUtils.logException;
class Migration39_40 implements Migration<Connection> { class Migration39_40 implements Migration<Connection> {
@@ -37,8 +39,16 @@ class Migration39_40 implements Migration<Connection> {
+ " ALTER COLUMN eta" + " ALTER COLUMN eta"
+ " SET NOT NULL"); + " SET NOT NULL");
} catch (SQLException e) { } catch (SQLException e) {
tryToClose(s, LOG, WARNING); tryToClose(s);
throw new DbException(e); throw new DbException(e);
} }
} }
private void tryToClose(@Nullable Statement s) {
try {
if (s != null) s.close();
} catch (SQLException e) {
logException(LOG, WARNING, e);
}
}
} }

View File

@@ -1,46 +0,0 @@
package org.briarproject.bramble.db;
import org.briarproject.bramble.api.db.DbException;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Logger;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
class Migration40_41 implements Migration<Connection> {
private static final Logger LOG = getLogger(Migration40_41.class.getName());
private final DatabaseTypes dbTypes;
public Migration40_41(DatabaseTypes databaseTypes) {
this.dbTypes = databaseTypes;
}
@Override
public int getStartVersion() {
return 40;
}
@Override
public int getEndVersion() {
return 41;
}
@Override
public void migrate(Connection txn) throws DbException {
Statement s = null;
try {
s = txn.createStatement();
s.execute("ALTER TABLE contacts"
+ dbTypes.replaceTypes(" ADD alias _STRING"));
} catch (SQLException e) {
tryToClose(s, LOG, WARNING);
throw new DbException(e);
}
}
}

View File

@@ -1,21 +1,29 @@
package org.briarproject.bramble.identity; package org.briarproject.bramble.identity;
import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.crypto.CryptoComponent; import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.crypto.KeyPair; import org.briarproject.bramble.api.crypto.KeyPair;
import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DatabaseComponent;
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.identity.AuthorFactory; import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.util.Collection;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe; import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject; import javax.inject.Inject;
import static org.briarproject.bramble.api.identity.Author.Status.OURSELVES;
import static org.briarproject.bramble.api.identity.Author.Status.UNKNOWN;
import static org.briarproject.bramble.api.identity.Author.Status.UNVERIFIED;
import static org.briarproject.bramble.api.identity.Author.Status.VERIFIED;
import static org.briarproject.bramble.util.LogUtils.logDuration; import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.now; import static org.briarproject.bramble.util.LogUtils.now;
@@ -67,16 +75,27 @@ class IdentityManagerImpl implements IdentityManager {
LOG.info("No local author to store"); LOG.info("No local author to store");
return; return;
} }
db.transaction(false, txn -> db.addLocalAuthor(txn, cached)); Transaction txn = db.startTransaction(false);
LOG.info("Local author stored"); try {
db.addLocalAuthor(txn, cached);
db.commitTransaction(txn);
LOG.info("Local author stored");
} finally {
db.endTransaction(txn);
}
} }
@Override @Override
public LocalAuthor getLocalAuthor() throws DbException { public LocalAuthor getLocalAuthor() throws DbException {
if (cachedAuthor == null) { if (cachedAuthor == null) {
cachedAuthor = Transaction txn = db.startTransaction(true);
db.transactionWithResult(true, this::loadLocalAuthor); try {
LOG.info("Local author loaded"); cachedAuthor = loadLocalAuthor(txn);
LOG.info("Local author loaded");
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
} }
LocalAuthor cached = cachedAuthor; LocalAuthor cached = cachedAuthor;
if (cached == null) throw new AssertionError(); if (cached == null) throw new AssertionError();
@@ -99,4 +118,26 @@ class IdentityManagerImpl implements IdentityManager {
return db.getLocalAuthors(txn).iterator().next(); return db.getLocalAuthors(txn).iterator().next();
} }
@Override
public Status getAuthorStatus(AuthorId authorId) throws DbException {
Transaction txn = db.startTransaction(true);
try {
return getAuthorStatus(txn, authorId);
} finally {
db.endTransaction(txn);
}
}
@Override
public Status getAuthorStatus(Transaction txn, AuthorId authorId)
throws DbException {
if (getLocalAuthor(txn).getId().equals(authorId)) return OURSELVES;
Collection<Contact> contacts = db.getContactsByAuthorId(txn, authorId);
if (contacts.isEmpty()) return UNKNOWN;
for (Contact c : contacts) {
if (c.isVerified()) return VERIFIED;
}
return UNVERIFIED;
}
} }

View File

@@ -1,13 +1,13 @@
package org.briarproject.bramble.keyagreement; package org.briarproject.bramble.keyagreement;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.UnsupportedVersionException;
import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.data.BdfReader; import org.briarproject.bramble.api.data.BdfReader;
import org.briarproject.bramble.api.data.BdfReaderFactory; import org.briarproject.bramble.api.data.BdfReaderFactory;
import org.briarproject.bramble.api.keyagreement.Payload; import org.briarproject.bramble.api.keyagreement.Payload;
import org.briarproject.bramble.api.keyagreement.PayloadParser; import org.briarproject.bramble.api.keyagreement.PayloadParser;
import org.briarproject.bramble.api.keyagreement.TransportDescriptor; import org.briarproject.bramble.api.keyagreement.TransportDescriptor;
import org.briarproject.bramble.api.keyagreement.UnsupportedVersionException;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.BluetoothConstants; import org.briarproject.bramble.api.plugin.BluetoothConstants;
import org.briarproject.bramble.api.plugin.LanTcpConstants; import org.briarproject.bramble.api.plugin.LanTcpConstants;
@@ -21,7 +21,6 @@ import java.util.List;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import javax.inject.Inject; import javax.inject.Inject;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.BETA_PROTOCOL_VERSION;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH; import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION; import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_BLUETOOTH; import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_BLUETOOTH;
@@ -44,11 +43,8 @@ class PayloadParserImpl implements PayloadParser {
// First byte: the protocol version // First byte: the protocol version
int protocolVersion = in.read(); int protocolVersion = in.read();
if (protocolVersion == -1) throw new FormatException(); if (protocolVersion == -1) throw new FormatException();
if (protocolVersion != PROTOCOL_VERSION) { if (protocolVersion != PROTOCOL_VERSION)
boolean tooOld = protocolVersion < PROTOCOL_VERSION || throw new UnsupportedVersionException();
protocolVersion == BETA_PROTOCOL_VERSION;
throw new UnsupportedVersionException(tooOld);
}
// The rest of the payload is a BDF list with one or more elements // The rest of the payload is a BDF list with one or more elements
BdfReader r = bdfReaderFactory.createReader(in); BdfReader r = bdfReaderFactory.createReader(in);
BdfList payload = r.readList(); BdfList payload = r.readList();

View File

@@ -6,6 +6,7 @@ import org.briarproject.bramble.api.db.DataTooOldException;
import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.MigrationListener; import org.briarproject.bramble.api.db.MigrationListener;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.api.lifecycle.LifecycleManager;
@@ -28,7 +29,6 @@ import javax.inject.Inject;
import static java.util.logging.Level.FINE; import static java.util.logging.Level.FINE;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.COMPACTING_DATABASE;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.MIGRATING_DATABASE; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.MIGRATING_DATABASE;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RUNNING; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RUNNING;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.STARTING; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.STARTING;
@@ -114,16 +114,20 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
dbLatch.countDown(); dbLatch.countDown();
eventBus.broadcast(new LifecycleEvent(STARTING_SERVICES)); eventBus.broadcast(new LifecycleEvent(STARTING_SERVICES));
db.transaction(false, txn -> { Transaction txn = db.startTransaction(false);
try {
for (Client c : clients) { for (Client c : clients) {
long start1 = now(); start = now();
c.createLocalState(txn); c.createLocalState(txn);
if (LOG.isLoggable(FINE)) { if (LOG.isLoggable(FINE)) {
logDuration(LOG, "Starting client " logDuration(LOG, "Starting client "
+ c.getClass().getSimpleName(), start1); + c.getClass().getSimpleName(), start);
} }
} }
}); db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
for (Service s : services) { for (Service s : services) {
start = now(); start = now();
s.startService(); s.startService();
@@ -155,17 +159,11 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
} }
@Override @Override
public void onDatabaseMigration() { public void onMigrationRun() {
state = MIGRATING_DATABASE; state = MIGRATING_DATABASE;
eventBus.broadcast(new LifecycleEvent(MIGRATING_DATABASE)); eventBus.broadcast(new LifecycleEvent(MIGRATING_DATABASE));
} }
@Override
public void onDatabaseCompaction() {
state = COMPACTING_DATABASE;
eventBus.broadcast(new LifecycleEvent(COMPACTING_DATABASE));
}
@Override @Override
public void stopServices() { public void stopServices() {
try { try {

View File

@@ -23,6 +23,7 @@ import org.briarproject.bramble.api.plugin.event.EnableBluetoothEvent;
import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.properties.TransportProperties;
import org.briarproject.bramble.api.settings.Settings; import org.briarproject.bramble.api.settings.Settings;
import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent; import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent;
import org.briarproject.bramble.util.StringUtils;
import java.io.IOException; import java.io.IOException;
import java.security.SecureRandom; import java.security.SecureRandom;
@@ -45,9 +46,6 @@ import static org.briarproject.bramble.api.plugin.BluetoothConstants.PROP_UUID;
import static org.briarproject.bramble.api.plugin.BluetoothConstants.UUID_BYTES; import static org.briarproject.bramble.api.plugin.BluetoothConstants.UUID_BYTES;
import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress; import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress;
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
import static org.briarproject.bramble.util.StringUtils.macToBytes;
import static org.briarproject.bramble.util.StringUtils.macToString;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
@@ -98,9 +96,6 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
abstract DuplexTransportConnection connectTo(String address, String uuid) abstract DuplexTransportConnection connectTo(String address, String uuid)
throws IOException; throws IOException;
@Nullable
abstract DuplexTransportConnection discoverAndConnect(String uuid);
BluetoothPlugin(BluetoothConnectionLimiter connectionLimiter, BluetoothPlugin(BluetoothConnectionLimiter connectionLimiter,
Executor ioExecutor, SecureRandom secureRandom, Executor ioExecutor, SecureRandom secureRandom,
Backoff backoff, DuplexPluginCallback callback, int maxLatency) { Backoff backoff, DuplexPluginCallback callback, int maxLatency) {
@@ -198,7 +193,7 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
address = getBluetoothAddress(); address = getBluetoothAddress();
if (LOG.isLoggable(INFO)) if (LOG.isLoggable(INFO))
LOG.info("Local address " + scrubMacAddress(address)); LOG.info("Local address " + scrubMacAddress(address));
if (!isNullOrEmpty(address)) { if (!StringUtils.isNullOrEmpty(address)) {
p.put(PROP_ADDRESS, address); p.put(PROP_ADDRESS, address);
changed = true; changed = true;
} }
@@ -261,9 +256,9 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
// Try to connect to known devices in parallel // Try to connect to known devices in parallel
for (Entry<ContactId, TransportProperties> e : contacts.entrySet()) { for (Entry<ContactId, TransportProperties> e : contacts.entrySet()) {
String address = e.getValue().get(PROP_ADDRESS); String address = e.getValue().get(PROP_ADDRESS);
if (isNullOrEmpty(address)) continue; if (StringUtils.isNullOrEmpty(address)) continue;
String uuid = e.getValue().get(PROP_UUID); String uuid = e.getValue().get(PROP_UUID);
if (isNullOrEmpty(uuid)) continue; if (StringUtils.isNullOrEmpty(uuid)) continue;
ContactId c = e.getKey(); ContactId c = e.getKey();
ioExecutor.execute(() -> { ioExecutor.execute(() -> {
if (!isRunning() || !shouldAllowContactConnections()) return; if (!isRunning() || !shouldAllowContactConnections()) return;
@@ -314,9 +309,9 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
if (!isRunning() || !shouldAllowContactConnections()) return null; if (!isRunning() || !shouldAllowContactConnections()) return null;
if (!connectionLimiter.canOpenContactConnection()) return null; if (!connectionLimiter.canOpenContactConnection()) return null;
String address = p.get(PROP_ADDRESS); String address = p.get(PROP_ADDRESS);
if (isNullOrEmpty(address)) return null; if (StringUtils.isNullOrEmpty(address)) return null;
String uuid = p.get(PROP_UUID); String uuid = p.get(PROP_UUID);
if (isNullOrEmpty(uuid)) return null; if (StringUtils.isNullOrEmpty(uuid)) return null;
DuplexTransportConnection conn = connect(address, uuid); DuplexTransportConnection conn = connect(address, uuid);
if (conn == null) return null; if (conn == null) return null;
// TODO: Why don't we reset the backoff here? // TODO: Why don't we reset the backoff here?
@@ -331,6 +326,9 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
@Override @Override
public KeyAgreementListener createKeyAgreementListener(byte[] commitment) { public KeyAgreementListener createKeyAgreementListener(byte[] commitment) {
if (!isRunning()) return null; if (!isRunning()) return null;
// There's no point listening if we can't discover our own address
String address = getBluetoothAddress();
if (address == null) return null;
// No truncation necessary because COMMIT_LENGTH = 16 // No truncation necessary because COMMIT_LENGTH = 16
String uuid = UUID.nameUUIDFromBytes(commitment).toString(); String uuid = UUID.nameUUIDFromBytes(commitment).toString();
if (LOG.isLoggable(INFO)) LOG.info("Key agreement UUID " + uuid); if (LOG.isLoggable(INFO)) LOG.info("Key agreement UUID " + uuid);
@@ -348,8 +346,7 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
} }
BdfList descriptor = new BdfList(); BdfList descriptor = new BdfList();
descriptor.add(TRANSPORT_ID_BLUETOOTH); descriptor.add(TRANSPORT_ID_BLUETOOTH);
String address = getBluetoothAddress(); descriptor.add(StringUtils.macToBytes(address));
if (address != null) descriptor.add(macToBytes(address));
return new BluetoothKeyAgreementListener(descriptor, ss); return new BluetoothKeyAgreementListener(descriptor, ss);
} }
@@ -357,25 +354,18 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
public DuplexTransportConnection createKeyAgreementConnection( public DuplexTransportConnection createKeyAgreementConnection(
byte[] commitment, BdfList descriptor) { byte[] commitment, BdfList descriptor) {
if (!isRunning()) return null; if (!isRunning()) return null;
String address;
try {
address = parseAddress(descriptor);
} catch (FormatException e) {
LOG.info("Invalid address in key agreement descriptor");
return null;
}
// No truncation necessary because COMMIT_LENGTH = 16 // No truncation necessary because COMMIT_LENGTH = 16
String uuid = UUID.nameUUIDFromBytes(commitment).toString(); String uuid = UUID.nameUUIDFromBytes(commitment).toString();
DuplexTransportConnection conn; if (LOG.isLoggable(INFO))
if (descriptor.size() == 1) { LOG.info("Connecting to key agreement UUID " + uuid);
if (LOG.isLoggable(INFO)) DuplexTransportConnection conn = connect(address, uuid);
LOG.info("Discovering address for key agreement UUID " + uuid);
conn = discoverAndConnect(uuid);
} else {
String address;
try {
address = parseAddress(descriptor);
} catch (FormatException e) {
LOG.info("Invalid address in key agreement descriptor");
return null;
}
if (LOG.isLoggable(INFO))
LOG.info("Connecting to key agreement UUID " + uuid);
conn = connect(address, uuid);
}
if (conn != null) connectionLimiter.keyAgreementConnectionOpened(conn); if (conn != null) connectionLimiter.keyAgreementConnectionOpened(conn);
return conn; return conn;
} }
@@ -383,7 +373,7 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
private String parseAddress(BdfList descriptor) throws FormatException { private String parseAddress(BdfList descriptor) throws FormatException {
byte[] mac = descriptor.getRaw(1); byte[] mac = descriptor.getRaw(1);
if (mac.length != 6) throw new FormatException(); if (mac.length != 6) throw new FormatException();
return macToString(mac); return StringUtils.macToString(mac);
} }
@Override @Override

View File

@@ -4,11 +4,12 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.TransportConnectionReader; import org.briarproject.bramble.api.plugin.TransportConnectionReader;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.logging.Logger; import java.util.logging.Logger;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.IoUtils.tryToClose; import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault @NotNullByDefault
class FileTransportReader implements TransportConnectionReader { class FileTransportReader implements TransportConnectionReader {
@@ -33,7 +34,11 @@ class FileTransportReader implements TransportConnectionReader {
@Override @Override
public void dispose(boolean exception, boolean recognised) { public void dispose(boolean exception, boolean recognised) {
tryToClose(in, LOG, WARNING); try {
in.close();
} catch (IOException e) {
logException(LOG, WARNING, e);
}
plugin.readerFinished(file, exception, recognised); plugin.readerFinished(file, exception, recognised);
} }
} }

View File

@@ -4,11 +4,12 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.TransportConnectionWriter; import org.briarproject.bramble.api.plugin.TransportConnectionWriter;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.logging.Logger; import java.util.logging.Logger;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.IoUtils.tryToClose; import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault @NotNullByDefault
class FileTransportWriter implements TransportConnectionWriter { class FileTransportWriter implements TransportConnectionWriter {
@@ -43,7 +44,11 @@ class FileTransportWriter implements TransportConnectionWriter {
@Override @Override
public void dispose(boolean exception) { public void dispose(boolean exception) {
tryToClose(out, LOG, WARNING); try {
out.close();
} catch (IOException e) {
logException(LOG, WARNING, e);
}
plugin.writerFinished(file, exception); plugin.writerFinished(file, exception);
} }
} }

View File

@@ -11,7 +11,6 @@ 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.properties.TransportProperties; import org.briarproject.bramble.api.properties.TransportProperties;
import org.briarproject.bramble.api.settings.Settings; import org.briarproject.bramble.api.settings.Settings;
import org.briarproject.bramble.util.IoUtils;
import org.briarproject.bramble.util.StringUtils; import org.briarproject.bramble.util.StringUtils;
import java.io.IOException; import java.io.IOException;
@@ -36,6 +35,7 @@ import static org.briarproject.bramble.api.plugin.LanTcpConstants.ID;
import static org.briarproject.bramble.api.plugin.LanTcpConstants.PREF_LAN_IP_PORTS; import static org.briarproject.bramble.api.plugin.LanTcpConstants.PREF_LAN_IP_PORTS;
import static org.briarproject.bramble.api.plugin.LanTcpConstants.PROP_IP_PORTS; import static org.briarproject.bramble.api.plugin.LanTcpConstants.PROP_IP_PORTS;
import static org.briarproject.bramble.util.ByteUtils.MAX_16_BIT_UNSIGNED; import static org.briarproject.bramble.util.ByteUtils.MAX_16_BIT_UNSIGNED;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.PrivacyUtils.scrubSocketAddress; import static org.briarproject.bramble.util.PrivacyUtils.scrubSocketAddress;
@NotNullByDefault @NotNullByDefault
@@ -293,7 +293,11 @@ class LanTcpPlugin extends TcpPlugin {
@Override @Override
public void close() { public void close() {
IoUtils.tryToClose(ss, LOG, WARNING); try {
ss.close();
} catch (IOException e) {
logException(LOG, WARNING, e);
}
} }
} }

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.DuplexTransportConnection; import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.properties.TransportProperties;
import org.briarproject.bramble.util.IoUtils;
import org.briarproject.bramble.util.StringUtils; import org.briarproject.bramble.util.StringUtils;
import java.io.IOException; import java.io.IOException;
@@ -154,8 +153,13 @@ abstract class TcpPlugin implements DuplexPlugin {
} }
protected void tryToClose(@Nullable ServerSocket ss) { protected void tryToClose(@Nullable ServerSocket ss) {
IoUtils.tryToClose(ss, LOG, WARNING); try {
callback.transportDisabled(); if (ss != null) ss.close();
} catch (IOException e) {
logException(LOG, WARNING, e);
} finally {
callback.transportDisabled();
}
} }
String getIpPortString(InetSocketAddress a) { String getIpPortString(InetSocketAddress a) {

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