mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 02:39:05 +01:00
Compare commits
7 Commits
release-1.
...
41-alias-f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
68738a5a03 | ||
|
|
1a025d0f40 | ||
|
|
a3593ea8ca | ||
|
|
34eaedbd63 | ||
|
|
44e1ce32ce | ||
|
|
7af4b3d3ca | ||
|
|
1423ca7a15 |
@@ -3,7 +3,7 @@
|
||||
<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="PACKAGE_NAME" value="" />
|
||||
<option name="MAIN_CLASS_NAME" value="" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="TEST_OBJECT" value="package" />
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import com.android.build.gradle.tasks.MergeResources
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'witness'
|
||||
apply from: 'witness.gradle'
|
||||
@@ -11,8 +9,8 @@ android {
|
||||
defaultConfig {
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 26
|
||||
versionCode 10105
|
||||
versionName "1.1.5"
|
||||
versionCode 10103
|
||||
versionName "1.1.3"
|
||||
consumerProguardFiles 'proguard-rules.txt'
|
||||
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
@@ -31,9 +29,8 @@ configurations {
|
||||
dependencies {
|
||||
implementation project(path: ':bramble-core', configuration: 'default')
|
||||
tor 'org.briarproject:tor-android:0.3.4.8@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'
|
||||
|
||||
@@ -42,29 +39,13 @@ dependencies {
|
||||
testImplementation "org.jmock:jmock:2.8.2"
|
||||
testImplementation "org.jmock:jmock-junit4:2.8.2"
|
||||
testImplementation "org.jmock:jmock-legacy:2.8.2"
|
||||
testImplementation "org.hamcrest:hamcrest-library:1.3"
|
||||
testImplementation "org.hamcrest:hamcrest-core:1.3"
|
||||
}
|
||||
|
||||
def torBinariesDir = 'src/main/res/raw'
|
||||
|
||||
task cleanTorBinaries {
|
||||
doLast {
|
||||
delete fileTree(torBinariesDir) { include '*.zip' }
|
||||
project.afterEvaluate {
|
||||
copy {
|
||||
from configurations.tor.collect { zipTree(it) }
|
||||
into 'src/main/res/raw'
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.briarproject.bramble;
|
||||
|
||||
import org.briarproject.bramble.battery.AndroidBatteryModule;
|
||||
import org.briarproject.bramble.network.AndroidNetworkModule;
|
||||
import org.briarproject.bramble.plugin.tor.CircumventionModule;
|
||||
import org.briarproject.bramble.system.AndroidSystemModule;
|
||||
@@ -8,7 +7,6 @@ import org.briarproject.bramble.system.AndroidSystemModule;
|
||||
import dagger.Module;
|
||||
|
||||
@Module(includes = {
|
||||
AndroidBatteryModule.class,
|
||||
AndroidNetworkModule.class,
|
||||
AndroidSystemModule.class,
|
||||
CircumventionModule.class
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package org.briarproject.bramble.battery;
|
||||
|
||||
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
||||
@Module
|
||||
public class AndroidBatteryModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
BatteryManager provideBatteryManager(LifecycleManager lifecycleManager,
|
||||
AndroidBatteryManager batteryManager) {
|
||||
lifecycleManager.registerService(batteryManager);
|
||||
return batteryManager;
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.os.PowerManager;
|
||||
|
||||
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||
import org.briarproject.bramble.api.network.NetworkManager;
|
||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||
@@ -42,18 +41,17 @@ class AndroidTorPlugin extends TorPlugin {
|
||||
Context appContext, NetworkManager networkManager,
|
||||
LocationUtils locationUtils, SocketFactory torSocketFactory,
|
||||
Clock clock, ResourceProvider resourceProvider,
|
||||
CircumventionProvider circumventionProvider,
|
||||
BatteryManager batteryManager, Backoff backoff,
|
||||
CircumventionProvider circumventionProvider, Backoff backoff,
|
||||
DuplexPluginCallback callback, String architecture, int maxLatency,
|
||||
int maxIdleTime) {
|
||||
super(ioExecutor, networkManager, locationUtils, torSocketFactory,
|
||||
clock, resourceProvider, circumventionProvider, batteryManager,
|
||||
backoff, callback, architecture, maxLatency, maxIdleTime,
|
||||
clock, resourceProvider, circumventionProvider, backoff,
|
||||
callback, architecture, maxLatency, maxIdleTime,
|
||||
appContext.getDir("tor", MODE_PRIVATE));
|
||||
this.appContext = appContext;
|
||||
PowerManager pm = (PowerManager)
|
||||
appContext.getSystemService(POWER_SERVICE);
|
||||
if (pm == null) throw new AssertionError();
|
||||
assert pm != null;
|
||||
wakeLock = new RenewableWakeLock(pm, scheduler, PARTIAL_WAKE_LOCK,
|
||||
WAKE_LOCK_TAG, 1, MINUTES);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package org.briarproject.bramble.plugin.tor;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
|
||||
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.network.NetworkManager;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
@@ -49,7 +48,6 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
||||
private final BackoffFactory backoffFactory;
|
||||
private final ResourceProvider resourceProvider;
|
||||
private final CircumventionProvider circumventionProvider;
|
||||
private final BatteryManager batteryManager;
|
||||
private final Clock clock;
|
||||
|
||||
public AndroidTorPluginFactory(Executor ioExecutor,
|
||||
@@ -57,8 +55,7 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
||||
NetworkManager networkManager, LocationUtils locationUtils,
|
||||
EventBus eventBus, SocketFactory torSocketFactory,
|
||||
BackoffFactory backoffFactory, ResourceProvider resourceProvider,
|
||||
CircumventionProvider circumventionProvider,
|
||||
BatteryManager batteryManager, Clock clock) {
|
||||
CircumventionProvider circumventionProvider, Clock clock) {
|
||||
this.ioExecutor = ioExecutor;
|
||||
this.scheduler = scheduler;
|
||||
this.appContext = appContext;
|
||||
@@ -69,7 +66,6 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
||||
this.backoffFactory = backoffFactory;
|
||||
this.resourceProvider = resourceProvider;
|
||||
this.circumventionProvider = circumventionProvider;
|
||||
this.batteryManager = batteryManager;
|
||||
this.clock = clock;
|
||||
}
|
||||
|
||||
@@ -108,8 +104,8 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
||||
MAX_POLLING_INTERVAL, BACKOFF_BASE);
|
||||
AndroidTorPlugin plugin = new AndroidTorPlugin(ioExecutor, scheduler,
|
||||
appContext, networkManager, locationUtils, torSocketFactory,
|
||||
clock, resourceProvider, circumventionProvider, batteryManager,
|
||||
backoff, callback, architecture, MAX_LATENCY, MAX_IDLE_TIME);
|
||||
clock, resourceProvider, circumventionProvider, backoff,
|
||||
callback, architecture, MAX_LATENCY, MAX_IDLE_TIME);
|
||||
eventBus.addListener(plugin);
|
||||
return plugin;
|
||||
}
|
||||
|
||||
@@ -11,12 +11,15 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static android.content.Context.MODE_PRIVATE;
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
|
||||
public class AndroidUtils {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(AndroidUtils.class.getName());
|
||||
|
||||
// Fake Bluetooth address returned by BluetoothAdapter on API 23 and later
|
||||
private static final String FAKE_BLUETOOTH_ADDRESS = "02:00:00:00:00:00";
|
||||
|
||||
@@ -25,7 +28,7 @@ public class AndroidUtils {
|
||||
@SuppressWarnings("deprecation")
|
||||
public static Collection<String> getSupportedArchitectures() {
|
||||
List<String> abis = new ArrayList<>();
|
||||
if (SDK_INT >= 21) {
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
abis.addAll(Arrays.asList(Build.SUPPORTED_ABIS));
|
||||
} else {
|
||||
abis.add(Build.CPU_ABI);
|
||||
|
||||
@@ -31,21 +31,16 @@ dependencyVerification {
|
||||
'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.gson:gson:2.8.0:gson-2.8.0.jar:c6221763bd79c4f1c3dc7f750b5f29a0bb38b367b81314c4f71896e340c40825',
|
||||
'com.google.dagger:dagger-compiler:2.19:dagger-compiler-2.19.jar:27a4b202a2de908182edb261f8c0a264e08e5e4733d7514bc7fbf0d31da5c0fc',
|
||||
'com.google.dagger:dagger-producers:2.19:dagger-producers-2.19.jar:a17663abe0fc38b676026950907d4c5f5e2bf338375415861eaff6e3bdb0b768',
|
||||
'com.google.dagger:dagger-spi:2.19:dagger-spi-2.19.jar:e7a6379d82c841f6aac2866948ad1eed716528707814602842a8d844ce04e2e1',
|
||||
'com.google.dagger:dagger:2.19:dagger-2.19.jar:514b6f1e0727c6572e1d65cb27e4ae668b7aeaeb93a29515182965265b609939',
|
||||
'com.google.dagger:dagger-compiler:2.0.2:dagger-compiler-2.0.2.jar:b74bc9de063dd4c6400b232231f2ef5056145b8fbecbf5382012007dd1c071b3',
|
||||
'com.google.dagger:dagger-producers:2.0-beta:dagger-producers-2.0-beta.jar:99ec15e8a0507ba569e7655bc1165ee5e5ca5aa914b3c8f7e2c2458f724edd6b',
|
||||
'com.google.dagger:dagger:2.0.2:dagger-2.0.2.jar:84c0282ed8be73a29e0475d639da030b55dee72369e58dd35ae7d4fe6243dcf9',
|
||||
'com.google.errorprone:error_prone_annotations:2.0.18:error_prone_annotations-2.0.18.jar:cb4cfad870bf563a07199f3ebea5763f0dec440fcda0b318640b1feaa788656b',
|
||||
'com.google.errorprone:error_prone_annotations:2.1.3:error_prone_annotations-2.1.3.jar:03d0329547c13da9e17c634d1049ea2ead093925e290567e1a364fd6b1fc7ff8',
|
||||
'com.google.errorprone:javac-shaded:9-dev-r4023-3:javac-shaded-9-dev-r4023-3.jar:65bfccf60986c47fbc17c9ebab0be626afc41741e0a6ec7109e0768817a36f30',
|
||||
'com.google.googlejavaformat:google-java-format:1.5:google-java-format-1.5.jar:aa19ad7850fb85178aa22f2fddb163b84d6ce4d0035872f30d4408195ca1144e',
|
||||
'com.google.guava:guava:18.0:guava-18.0.jar:d664fbfc03d2e5ce9cab2a44fb01f1d0bf9dfebeccc1a473b1f9ea31f79f6f99',
|
||||
'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.jimfs:jimfs:1.1:jimfs-1.1.jar:c4828e28d7c0a930af9387510b3bada7daa5c04d7c25a75c7b8b081f1c257ddd',
|
||||
'com.google.protobuf:protobuf-java:3.4.0:protobuf-java-3.4.0.jar:dce7e66b32456a1b1198da0caff3a8acb71548658391e798c79369241e6490a4',
|
||||
'com.googlecode.json-simple:json-simple:1.1:json-simple-1.1.jar:2d9484f4c649f708f47f9a479465fc729770ee65617dca3011836602264f6439',
|
||||
'com.squareup:javapoet:1.11.1:javapoet-1.11.1.jar:9cbf2107be499ec6e95afd36b58e3ca122a24166cdd375732e51267d64058e90',
|
||||
'com.squareup:javawriter:2.5.0:javawriter-2.5.0.jar:fcfb09fb0ea0aa97d3cfe7ea792398081348e468f126b3603cb3803f240197f0',
|
||||
'com.sun.activation:javax.activation:1.2.0:javax.activation-1.2.0.jar:993302b16cd7056f21e779cc577d175a810bb4900ef73cd8fbf2b50f928ba9ce',
|
||||
'com.sun.istack:istack-commons-runtime:2.21:istack-commons-runtime-2.21.jar:c33e67a0807095f02a0e2da139412dd7c4f9cc1a4c054b3e434f96831ba950f4',
|
||||
@@ -68,9 +63,7 @@ dependencyVerification {
|
||||
'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8',
|
||||
'org.bouncycastle:bcpkix-jdk15on:1.56:bcpkix-jdk15on-1.56.jar:7043dee4e9e7175e93e0b36f45b1ec1ecb893c5f755667e8b916eb8dd201c6ca',
|
||||
'org.bouncycastle:bcprov-jdk15on:1.56:bcprov-jdk15on-1.56.jar:963e1ee14f808ffb99897d848ddcdb28fa91ddda867eb18d303e82728f878349',
|
||||
'org.briarproject:obfs4proxy-android:0.0.7:obfs4proxy-android-0.0.7.zip:abdfb5d889d848de9bf214f9276abbf454808a505b870819eccc9a9e985bf617',
|
||||
'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.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',
|
||||
|
||||
@@ -7,13 +7,15 @@ apply plugin: 'witness'
|
||||
apply from: 'witness.gradle'
|
||||
|
||||
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'
|
||||
|
||||
testImplementation 'junit:junit:4.12'
|
||||
testImplementation "org.jmock:jmock:2.8.2"
|
||||
testImplementation "org.jmock:jmock-junit4:2.8.2"
|
||||
testImplementation "org.jmock:jmock-legacy:2.8.2"
|
||||
testImplementation "org.hamcrest:hamcrest-library:1.3"
|
||||
testImplementation "org.hamcrest:hamcrest-core:1.3"
|
||||
|
||||
signature 'org.codehaus.mojo.signature:java16:1.1@signature'
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
package org.briarproject.bramble.api.battery;
|
||||
|
||||
public interface BatteryManager {
|
||||
|
||||
boolean isCharging();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -96,12 +96,6 @@ public interface ContactManager {
|
||||
void setContactActive(Transaction txn, ContactId c, boolean active)
|
||||
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.
|
||||
*/
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
@@ -89,14 +89,6 @@ public interface DatabaseComponent {
|
||||
<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,
|
||||
* and returns an ID for the contact.
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
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;
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -39,18 +39,4 @@ public class AuthorInfo {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public class StringUtils {
|
||||
try {
|
||||
return s.getBytes("UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new AssertionError(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public class StringUtils {
|
||||
try {
|
||||
return decoder.decode(buffer).toString();
|
||||
} catch (CharacterCodingException e) {
|
||||
throw new AssertionError(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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")
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,7 +2,7 @@ dependencyVerification {
|
||||
verify = [
|
||||
'cglib:cglib:3.2.0:cglib-3.2.0.jar:adb13bab79712ad6bdf1bd59f2a3918018a8016e722e8a357065afb9e6690861',
|
||||
'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
|
||||
'com.google.dagger:dagger:2.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',
|
||||
'junit:junit:4.12:junit-4.12.jar:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a',
|
||||
'org.apache.ant:ant-launcher:1.9.4:ant-launcher-1.9.4.jar:7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d',
|
||||
|
||||
@@ -3,10 +3,10 @@ sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
|
||||
apply plugin: 'ru.vyarus.animalsniffer'
|
||||
apply plugin: 'net.ltgt.apt'
|
||||
apply plugin: 'idea'
|
||||
apply plugin: 'witness'
|
||||
apply from: 'witness.gradle'
|
||||
apply from: '../dagger.gradle'
|
||||
|
||||
dependencies {
|
||||
implementation project(path: ':bramble-api', configuration: 'default')
|
||||
@@ -17,7 +17,7 @@ dependencies {
|
||||
implementation 'org.whispersystems:curve25519-java:0.5.0'
|
||||
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 '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-junit4:2.8.2"
|
||||
testImplementation "org.jmock:jmock-legacy:2.8.2"
|
||||
testImplementation "org.hamcrest:hamcrest-library:1.3"
|
||||
testImplementation "org.hamcrest:hamcrest-core:1.3"
|
||||
|
||||
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'
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -82,7 +82,13 @@ class ClientHelperImpl implements ClientHelper {
|
||||
@Override
|
||||
public void addLocalMessage(Message m, BdfDictionary metadata,
|
||||
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
|
||||
@@ -107,7 +113,15 @@ class ClientHelperImpl implements ClientHelper {
|
||||
|
||||
@Override
|
||||
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
|
||||
@@ -118,7 +132,15 @@ class ClientHelperImpl implements ClientHelper {
|
||||
@Override
|
||||
public BdfList getMessageAsList(MessageId m) throws DbException,
|
||||
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
|
||||
@@ -130,8 +152,15 @@ class ClientHelperImpl implements ClientHelper {
|
||||
@Override
|
||||
public BdfDictionary getGroupMetadataAsDictionary(GroupId g)
|
||||
throws DbException, FormatException {
|
||||
return db.transactionWithResult(true, txn ->
|
||||
getGroupMetadataAsDictionary(txn, g));
|
||||
BdfDictionary dictionary;
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
dictionary = getGroupMetadataAsDictionary(txn, g);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -144,8 +173,15 @@ class ClientHelperImpl implements ClientHelper {
|
||||
@Override
|
||||
public BdfDictionary getMessageMetadataAsDictionary(MessageId m)
|
||||
throws DbException, FormatException {
|
||||
return db.transactionWithResult(true, txn ->
|
||||
getMessageMetadataAsDictionary(txn, m));
|
||||
BdfDictionary dictionary;
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
dictionary = getMessageMetadataAsDictionary(txn, m);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -158,8 +194,15 @@ class ClientHelperImpl implements ClientHelper {
|
||||
@Override
|
||||
public Map<MessageId, BdfDictionary> getMessageMetadataAsDictionary(
|
||||
GroupId g) throws DbException, FormatException {
|
||||
return db.transactionWithResult(true, txn ->
|
||||
getMessageMetadataAsDictionary(txn, g));
|
||||
Map<MessageId, BdfDictionary> map;
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
map = getMessageMetadataAsDictionary(txn, g);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -176,8 +219,15 @@ class ClientHelperImpl implements ClientHelper {
|
||||
public Map<MessageId, BdfDictionary> getMessageMetadataAsDictionary(
|
||||
GroupId g, BdfDictionary query) throws DbException,
|
||||
FormatException {
|
||||
return db.transactionWithResult(true, txn ->
|
||||
getMessageMetadataAsDictionary(txn, g, query));
|
||||
Map<MessageId, BdfDictionary> map;
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
map = getMessageMetadataAsDictionary(txn, g, query);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -195,7 +245,13 @@ class ClientHelperImpl implements ClientHelper {
|
||||
@Override
|
||||
public void mergeGroupMetadata(GroupId g, BdfDictionary metadata)
|
||||
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
|
||||
@@ -207,7 +263,13 @@ class ClientHelperImpl implements ClientHelper {
|
||||
@Override
|
||||
public void mergeMessageMetadata(MessageId m, BdfDictionary metadata)
|
||||
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
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.db.ContactExistsException;
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
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.LocalAuthor;
|
||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||
@@ -157,8 +158,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
||||
streamWriterFactory.createContactExchangeStreamWriter(out,
|
||||
alice ? aliceHeaderKey : bobHeaderKey);
|
||||
RecordWriter recordWriter =
|
||||
recordWriterFactory
|
||||
.createRecordWriter(streamWriter.getOutputStream());
|
||||
recordWriterFactory.createRecordWriter(streamWriter.getOutputStream());
|
||||
|
||||
// Derive the nonces to be signed
|
||||
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,
|
||||
Map<TransportId, TransportProperties> remoteProperties)
|
||||
throws DbException {
|
||||
return db.transactionWithResult(false, txn -> {
|
||||
ContactId contactId = contactManager.addContact(txn, remoteAuthor,
|
||||
ContactId contactId;
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
contactId = contactManager.addContact(txn, remoteAuthor,
|
||||
localAuthor.getId(), masterSecret, timestamp, alice,
|
||||
true, true);
|
||||
transportPropertyManager.addRemoteProperties(txn, contactId,
|
||||
remoteProperties);
|
||||
return contactId;
|
||||
});
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
return contactId;
|
||||
}
|
||||
|
||||
private void tryToClose(DuplexTransportConnection conn) {
|
||||
|
||||
@@ -79,21 +79,42 @@ class ContactManagerImpl implements ContactManager {
|
||||
public ContactId addContact(Author remote, AuthorId local, SecretKey master,
|
||||
long timestamp, boolean alice, boolean verified, boolean active)
|
||||
throws DbException {
|
||||
return db.transactionWithResult(false, txn ->
|
||||
addContact(txn, remote, local, master, timestamp, alice,
|
||||
verified, active));
|
||||
ContactId c;
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
c = addContact(txn, remote, local, master, timestamp, alice,
|
||||
verified, active);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
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
|
||||
public Contact getContact(AuthorId remoteAuthorId, AuthorId localAuthorId)
|
||||
throws DbException {
|
||||
return db.transactionWithResult(true, txn ->
|
||||
getContact(txn, remoteAuthorId, localAuthorId));
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
Contact c = getContact(txn, remoteAuthorId, localAuthorId);
|
||||
db.commitTransaction(txn);
|
||||
return c;
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,8 +132,14 @@ class ContactManagerImpl implements ContactManager {
|
||||
|
||||
@Override
|
||||
public Collection<Contact> getActiveContacts() throws DbException {
|
||||
Collection<Contact> contacts =
|
||||
db.transactionWithResult(true, db::getContacts);
|
||||
Collection<Contact> contacts;
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
contacts = db.getContacts(txn);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
List<Contact> active = new ArrayList<>(contacts.size());
|
||||
for (Contact c : contacts) if (c.isActive()) active.add(c);
|
||||
return active;
|
||||
@@ -120,7 +147,13 @@ class ContactManagerImpl implements ContactManager {
|
||||
|
||||
@Override
|
||||
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
|
||||
@@ -130,20 +163,14 @@ class ContactManagerImpl implements ContactManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContactAlias(Transaction txn, ContactId c,
|
||||
@Nullable String alias) throws DbException {
|
||||
public void setContactAlias(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));
|
||||
db.transaction(false, txn -> db.setContactAlias(txn, c, alias));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -155,8 +182,15 @@ class ContactManagerImpl implements ContactManager {
|
||||
@Override
|
||||
public boolean contactExists(AuthorId remoteAuthorId,
|
||||
AuthorId localAuthorId) throws DbException {
|
||||
return db.transactionWithResult(true, txn ->
|
||||
contactExists(txn, remoteAuthorId, localAuthorId));
|
||||
boolean exists;
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
exists = contactExists(txn, remoteAuthorId, localAuthorId);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
return exists;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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_8;
|
||||
import static org.briarproject.bramble.data.Types.TRUE;
|
||||
import static org.briarproject.bramble.util.StringUtils.fromUtf8;
|
||||
|
||||
@NotThreadSafe
|
||||
@NotNullByDefault
|
||||
@@ -254,7 +253,7 @@ class BdfReaderImpl implements BdfReader {
|
||||
if (length < 0 || length > maxBufferSize) throw new FormatException();
|
||||
if (length == 0) return "";
|
||||
readIntoBuffer(length);
|
||||
return fromUtf8(buf, 0, length);
|
||||
return new String(buf, 0, length, "UTF-8");
|
||||
}
|
||||
|
||||
private int readStringLength() throws IOException {
|
||||
|
||||
@@ -19,7 +19,6 @@ import org.briarproject.bramble.api.db.NoSuchGroupException;
|
||||
import org.briarproject.bramble.api.db.NoSuchLocalAuthorException;
|
||||
import org.briarproject.bramble.api.db.NoSuchMessageException;
|
||||
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.event.Event;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
@@ -194,20 +193,6 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
}
|
||||
}
|
||||
|
||||
@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) {
|
||||
if (transaction.isCommitted()) throw new IllegalStateException();
|
||||
return txnClass.cast(transaction.unbox());
|
||||
@@ -876,7 +861,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
|
||||
@Override
|
||||
public void setContactAlias(Transaction transaction, ContactId c,
|
||||
@Nullable String alias) throws DbException {
|
||||
String alias) throws DbException {
|
||||
if (transaction.isReadOnly()) throw new IllegalArgumentException();
|
||||
T txn = unbox(transaction);
|
||||
if (!db.containsContact(txn, c))
|
||||
|
||||
@@ -3,7 +3,7 @@ package org.briarproject.bramble.db;
|
||||
class DatabaseTypes {
|
||||
|
||||
private final String hashType, secretType, binaryType;
|
||||
private final String counterType, stringType;
|
||||
private final String counterType, stringType;
|
||||
|
||||
public DatabaseTypes(String hashType, String secretType, String binaryType,
|
||||
String counterType, String stringType) {
|
||||
@@ -17,11 +17,11 @@ class DatabaseTypes {
|
||||
/**
|
||||
* 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
|
||||
* <li> _HASH
|
||||
* <li> _SECRET
|
||||
* <li> _BINARY
|
||||
* <li> _COUNTER
|
||||
* <li> _STRING
|
||||
*/
|
||||
String replaceTypes(String s) {
|
||||
s = s.replaceAll("_HASH", hashType);
|
||||
|
||||
@@ -39,7 +39,7 @@ class Migration40_41 implements Migration<Connection> {
|
||||
try {
|
||||
s = txn.createStatement();
|
||||
s.execute("ALTER TABLE contacts"
|
||||
+ dbTypes.replaceTypes(" ADD alias _STRING"));
|
||||
+ dbTypes.replaceTypes(" ADD alias VARCHAR"));
|
||||
} catch (SQLException e) {
|
||||
tryToClose(s);
|
||||
throw new DbException(e);
|
||||
|
||||
@@ -67,16 +67,27 @@ class IdentityManagerImpl implements IdentityManager {
|
||||
LOG.info("No local author to store");
|
||||
return;
|
||||
}
|
||||
db.transaction(false, txn -> db.addLocalAuthor(txn, cached));
|
||||
LOG.info("Local author stored");
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
db.addLocalAuthor(txn, cached);
|
||||
db.commitTransaction(txn);
|
||||
LOG.info("Local author stored");
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalAuthor getLocalAuthor() throws DbException {
|
||||
if (cachedAuthor == null) {
|
||||
cachedAuthor =
|
||||
db.transactionWithResult(true, this::loadLocalAuthor);
|
||||
LOG.info("Local author loaded");
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
cachedAuthor = loadLocalAuthor(txn);
|
||||
LOG.info("Local author loaded");
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
}
|
||||
LocalAuthor cached = cachedAuthor;
|
||||
if (cached == null) throw new AssertionError();
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.briarproject.bramble.api.db.DataTooOldException;
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
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.identity.IdentityManager;
|
||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||
@@ -114,16 +115,20 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
|
||||
dbLatch.countDown();
|
||||
eventBus.broadcast(new LifecycleEvent(STARTING_SERVICES));
|
||||
|
||||
db.transaction(false, txn -> {
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
for (Client c : clients) {
|
||||
long start1 = now();
|
||||
start = now();
|
||||
c.createLocalState(txn);
|
||||
if (LOG.isLoggable(FINE)) {
|
||||
logDuration(LOG, "Starting client "
|
||||
+ c.getClass().getSimpleName(), start1);
|
||||
+ c.getClass().getSimpleName(), start);
|
||||
}
|
||||
}
|
||||
});
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
for (Service s : services) {
|
||||
start = now();
|
||||
s.startService();
|
||||
|
||||
@@ -4,8 +4,6 @@ import net.freehaven.tor.control.EventHandler;
|
||||
import net.freehaven.tor.control.TorControlConnection;
|
||||
|
||||
import org.briarproject.bramble.PoliteExecutor;
|
||||
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||
import org.briarproject.bramble.api.battery.event.BatteryEvent;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
@@ -98,14 +96,13 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
private final LocationUtils locationUtils;
|
||||
private final SocketFactory torSocketFactory;
|
||||
private final Clock clock;
|
||||
private final BatteryManager batteryManager;
|
||||
private final Backoff backoff;
|
||||
private final DuplexPluginCallback callback;
|
||||
private final String architecture;
|
||||
private final CircumventionProvider circumventionProvider;
|
||||
private final ResourceProvider resourceProvider;
|
||||
private final int maxLatency, maxIdleTime, socketTimeout;
|
||||
private final File torDirectory, torFile, geoIpFile, obfs4File, configFile;
|
||||
private final File torDirectory, torFile, geoIpFile, configFile;
|
||||
private final File doneFile, cookieFile;
|
||||
private final ConnectionStatus connectionStatus;
|
||||
private final AtomicBoolean used = new AtomicBoolean(false);
|
||||
@@ -124,8 +121,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
TorPlugin(Executor ioExecutor, NetworkManager networkManager,
|
||||
LocationUtils locationUtils, SocketFactory torSocketFactory,
|
||||
Clock clock, ResourceProvider resourceProvider,
|
||||
CircumventionProvider circumventionProvider,
|
||||
BatteryManager batteryManager, Backoff backoff,
|
||||
CircumventionProvider circumventionProvider, Backoff backoff,
|
||||
DuplexPluginCallback callback, String architecture, int maxLatency,
|
||||
int maxIdleTime, File torDirectory) {
|
||||
this.ioExecutor = ioExecutor;
|
||||
@@ -135,7 +131,6 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
this.clock = clock;
|
||||
this.resourceProvider = resourceProvider;
|
||||
this.circumventionProvider = circumventionProvider;
|
||||
this.batteryManager = batteryManager;
|
||||
this.backoff = backoff;
|
||||
this.callback = callback;
|
||||
this.architecture = architecture;
|
||||
@@ -147,7 +142,6 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
this.torDirectory = torDirectory;
|
||||
torFile = new File(torDirectory, "tor");
|
||||
geoIpFile = new File(torDirectory, "geoip");
|
||||
obfs4File = new File(torDirectory, "obfs4proxy");
|
||||
configFile = new File(torDirectory, "torrc");
|
||||
doneFile = new File(torDirectory, "done");
|
||||
cookieFile = new File(torDirectory, ".tor/control_auth_cookie");
|
||||
@@ -266,8 +260,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
throw new PluginException(e);
|
||||
}
|
||||
// Check whether we're online
|
||||
updateConnectionStatus(networkManager.getNetworkStatus(),
|
||||
batteryManager.isCharging());
|
||||
updateConnectionStatus(networkManager.getNetworkStatus());
|
||||
// Bind a server socket to receive incoming hidden service connections
|
||||
bind();
|
||||
}
|
||||
@@ -291,12 +284,6 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
in = getGeoIpInputStream();
|
||||
out = new FileOutputStream(geoIpFile);
|
||||
IoUtils.copyAndClose(in, out);
|
||||
// Unzip the Obfs4 proxy to the filesystem
|
||||
in = getObfs4InputStream();
|
||||
out = new FileOutputStream(obfs4File);
|
||||
IoUtils.copyAndClose(in, out);
|
||||
// Make the Obfs4 proxy executable
|
||||
if (!obfs4File.setExecutable(true, true)) throw new IOException();
|
||||
// Copy the config file to the filesystem
|
||||
in = getConfigInputStream();
|
||||
out = new FileOutputStream(configFile);
|
||||
@@ -327,16 +314,6 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
return zin;
|
||||
}
|
||||
|
||||
private InputStream getObfs4InputStream() throws IOException {
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Installing obfs4proxy binary for " + architecture);
|
||||
InputStream in = resourceProvider
|
||||
.getResourceInputStream("obfs4proxy_" + architecture, ".zip");
|
||||
ZipInputStream zin = new ZipInputStream(in);
|
||||
if (zin.getNextEntry() == null) throw new IOException();
|
||||
return zin;
|
||||
}
|
||||
|
||||
private InputStream getConfigInputStream() {
|
||||
return getClass().getClassLoader().getResourceAsStream("torrc");
|
||||
}
|
||||
@@ -495,8 +472,6 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
if (enable) {
|
||||
Collection<String> conf = new ArrayList<>();
|
||||
conf.add("UseBridges 1");
|
||||
conf.add("ClientTransportPlugin obfs4 exec " +
|
||||
obfs4File.getAbsolutePath());
|
||||
conf.addAll(circumventionProvider.getBridges());
|
||||
controlConnection.setConf(conf);
|
||||
} else {
|
||||
@@ -634,8 +609,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
LOG.info("OR connection " + status + " " + orName);
|
||||
if (status.equals("CLOSED") || status.equals("FAILED")) {
|
||||
// Check whether we've lost connectivity
|
||||
updateConnectionStatus(networkManager.getNetworkStatus(),
|
||||
batteryManager.isCharging());
|
||||
updateConnectionStatus(networkManager.getNetworkStatus());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -673,15 +647,10 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
// Works around a bug introduced in Tor 0.3.4.8. Could be
|
||||
// replaced with callback.transportDisabled() when fixed.
|
||||
disableNetwork();
|
||||
updateConnectionStatus(networkManager.getNetworkStatus(),
|
||||
batteryManager.isCharging());
|
||||
updateConnectionStatus(networkManager.getNetworkStatus());
|
||||
}
|
||||
} else if (e instanceof NetworkStatusEvent) {
|
||||
updateConnectionStatus(((NetworkStatusEvent) e).getStatus(),
|
||||
batteryManager.isCharging());
|
||||
} else if (e instanceof BatteryEvent) {
|
||||
updateConnectionStatus(networkManager.getNetworkStatus(),
|
||||
((BatteryEvent) e).isCharging());
|
||||
updateConnectionStatus(((NetworkStatusEvent) e).getStatus());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -695,8 +664,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
});
|
||||
}
|
||||
|
||||
private void updateConnectionStatus(NetworkStatus status,
|
||||
boolean charging) {
|
||||
private void updateConnectionStatus(NetworkStatus status) {
|
||||
connectionStatusExecutor.execute(() -> {
|
||||
if (!running) return;
|
||||
boolean online = status.isConnected();
|
||||
@@ -714,7 +682,6 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
LOG.info("Online: " + online + ", wifi: " + wifi);
|
||||
if ("".equals(country)) LOG.info("Country code unknown");
|
||||
else LOG.info("Country code: " + country);
|
||||
LOG.info("Charging: " + charging);
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -738,24 +705,12 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
enableBridges(false);
|
||||
enableNetwork(true);
|
||||
}
|
||||
if (online && wifi && charging) {
|
||||
LOG.info("Enabling connection padding");
|
||||
enableConnectionPadding(true);
|
||||
} else {
|
||||
LOG.info("Disabling connection padding");
|
||||
enableConnectionPadding(false);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void enableConnectionPadding(boolean enable) throws IOException {
|
||||
if (!running) return;
|
||||
controlConnection.setConf("ConnectionPadding", enable ? "1" : "0");
|
||||
}
|
||||
|
||||
// TODO remove when sufficient time has passed. Added 2018-08-15
|
||||
private void migrateSettings() {
|
||||
Settings sOld = callback.getSettings();
|
||||
|
||||
@@ -142,7 +142,15 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||
@Override
|
||||
public Map<TransportId, TransportProperties> getLocalProperties()
|
||||
throws DbException {
|
||||
return db.transactionWithResult(true, this::getLocalProperties);
|
||||
Map<TransportId, TransportProperties> local;
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
local = getLocalProperties(txn);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
return local;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -168,8 +176,9 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||
public TransportProperties getLocalProperties(TransportId t)
|
||||
throws DbException {
|
||||
try {
|
||||
return db.transactionWithResult(true, txn -> {
|
||||
TransportProperties p = null;
|
||||
TransportProperties p = null;
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
// Find the latest local update
|
||||
LatestUpdate latest = findLatest(txn, localGroup.getId(), t,
|
||||
true);
|
||||
@@ -179,8 +188,11 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||
latest.messageId);
|
||||
p = parseProperties(message);
|
||||
}
|
||||
return p == null ? new TransportProperties() : p;
|
||||
});
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
return p == null ? new TransportProperties() : p;
|
||||
} catch (FormatException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
@@ -189,12 +201,16 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||
@Override
|
||||
public Map<ContactId, TransportProperties> getRemoteProperties(
|
||||
TransportId t) throws DbException {
|
||||
return db.transactionWithResult(true, txn -> {
|
||||
Map<ContactId, TransportProperties> remote = new HashMap<>();
|
||||
Map<ContactId, TransportProperties> remote = new HashMap<>();
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
for (Contact c : db.getContacts(txn))
|
||||
remote.put(c.getId(), getRemoteProperties(txn, c, t));
|
||||
return remote;
|
||||
});
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
return remote;
|
||||
}
|
||||
|
||||
private TransportProperties getRemoteProperties(Transaction txn, Contact c,
|
||||
@@ -218,15 +234,23 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||
@Override
|
||||
public TransportProperties getRemoteProperties(ContactId c, TransportId t)
|
||||
throws DbException {
|
||||
return db.transactionWithResult(true, txn ->
|
||||
getRemoteProperties(txn, db.getContact(txn, c), t));
|
||||
TransportProperties p;
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
p = getRemoteProperties(txn, db.getContact(txn, c), t);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mergeLocalProperties(TransportId t, TransportProperties p)
|
||||
throws DbException {
|
||||
try {
|
||||
db.transaction(false, txn -> {
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
// Merge the new properties with any existing properties
|
||||
TransportProperties merged;
|
||||
boolean changed;
|
||||
@@ -263,7 +287,10 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||
db.removeMessage(txn, latest.messageId);
|
||||
}
|
||||
}
|
||||
});
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
} catch (FormatException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
|
||||
@@ -23,8 +23,15 @@ class SettingsManagerImpl implements SettingsManager {
|
||||
|
||||
@Override
|
||||
public Settings getSettings(String namespace) throws DbException {
|
||||
return db.transactionWithResult(true, txn ->
|
||||
db.getSettings(txn, namespace));
|
||||
Settings s;
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
s = db.getSettings(txn, namespace);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -35,6 +42,12 @@ class SettingsManagerImpl implements SettingsManager {
|
||||
|
||||
@Override
|
||||
public void mergeSettings(Settings s, String namespace) throws DbException {
|
||||
db.transaction(false, txn -> db.mergeSettings(txn, s, namespace));
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
db.mergeSettings(txn, s, namespace);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.briarproject.bramble.api.contact.event.ContactRemovedEvent;
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.db.Transaction;
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.event.EventListener;
|
||||
@@ -229,8 +230,14 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
||||
if (interrupted) return;
|
||||
if (!generateAckQueued.getAndSet(false)) throw new AssertionError();
|
||||
try {
|
||||
Ack a = db.transactionWithNullableResult(false, txn ->
|
||||
db.generateAck(txn, contactId, MAX_MESSAGE_IDS));
|
||||
Ack a;
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
a = db.generateAck(txn, contactId, MAX_MESSAGE_IDS);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated ack: " + (a != null));
|
||||
if (a != null) writerTasks.add(new WriteAck(a));
|
||||
@@ -268,15 +275,16 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
||||
if (!generateBatchQueued.getAndSet(false))
|
||||
throw new AssertionError();
|
||||
try {
|
||||
Collection<Message> b =
|
||||
db.transactionWithNullableResult(false, txn -> {
|
||||
Collection<Message> batch =
|
||||
db.generateRequestedBatch(txn, contactId,
|
||||
MAX_RECORD_PAYLOAD_BYTES,
|
||||
maxLatency);
|
||||
setNextSendTime(db.getNextSendTime(txn, contactId));
|
||||
return batch;
|
||||
});
|
||||
Collection<Message> b;
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
b = db.generateRequestedBatch(txn, contactId,
|
||||
MAX_RECORD_PAYLOAD_BYTES, maxLatency);
|
||||
setNextSendTime(db.getNextSendTime(txn, contactId));
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated batch: " + (b != null));
|
||||
if (b != null) writerTasks.add(new WriteBatch(b));
|
||||
@@ -314,12 +322,16 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
||||
if (!generateOfferQueued.getAndSet(false))
|
||||
throw new AssertionError();
|
||||
try {
|
||||
Offer o = db.transactionWithNullableResult(false, txn -> {
|
||||
Offer offer = db.generateOffer(txn, contactId,
|
||||
MAX_MESSAGE_IDS, maxLatency);
|
||||
Offer o;
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
o = db.generateOffer(txn, contactId, MAX_MESSAGE_IDS,
|
||||
maxLatency);
|
||||
setNextSendTime(db.getNextSendTime(txn, contactId));
|
||||
return offer;
|
||||
});
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated offer: " + (o != null));
|
||||
if (o != null) writerTasks.add(new WriteOffer(o));
|
||||
@@ -357,8 +369,14 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
||||
if (!generateRequestQueued.getAndSet(false))
|
||||
throw new AssertionError();
|
||||
try {
|
||||
Request r = db.transactionWithNullableResult(false, txn ->
|
||||
db.generateRequest(txn, contactId, MAX_MESSAGE_IDS));
|
||||
Request r;
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
r = db.generateRequest(txn, contactId, MAX_MESSAGE_IDS);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated request: " + (r != null));
|
||||
if (r != null) writerTasks.add(new WriteRequest(r));
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.briarproject.bramble.api.contact.event.ContactRemovedEvent;
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.db.Transaction;
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.event.EventListener;
|
||||
@@ -119,8 +120,13 @@ class IncomingSession implements SyncSession, EventListener {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
db.transaction(false, txn ->
|
||||
db.receiveAck(txn, contactId, ack));
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
db.receiveAck(txn, contactId, ack);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
interrupt();
|
||||
@@ -140,8 +146,13 @@ class IncomingSession implements SyncSession, EventListener {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
db.transaction(false, txn ->
|
||||
db.receiveMessage(txn, contactId, message));
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
db.receiveMessage(txn, contactId, message);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
interrupt();
|
||||
@@ -161,8 +172,13 @@ class IncomingSession implements SyncSession, EventListener {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
db.transaction(false, txn ->
|
||||
db.receiveOffer(txn, contactId, offer));
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
db.receiveOffer(txn, contactId, offer);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
interrupt();
|
||||
@@ -182,8 +198,13 @@ class IncomingSession implements SyncSession, EventListener {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
db.transaction(false, txn ->
|
||||
db.receiveRequest(txn, contactId, request));
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
db.receiveRequest(txn, contactId, request);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
interrupt();
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.briarproject.bramble.api.contact.event.ContactRemovedEvent;
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.db.Transaction;
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.event.EventListener;
|
||||
@@ -46,8 +47,7 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(SimplexOutgoingSession.class.getName());
|
||||
|
||||
private static final ThrowingRunnable<IOException> CLOSE = () -> {
|
||||
};
|
||||
private static final ThrowingRunnable<IOException> CLOSE = () -> {};
|
||||
|
||||
private final DatabaseComponent db;
|
||||
private final Executor dbExecutor;
|
||||
@@ -128,8 +128,14 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
|
||||
public void run() {
|
||||
if (interrupted) return;
|
||||
try {
|
||||
Ack a = db.transactionWithNullableResult(false, txn ->
|
||||
db.generateAck(txn, contactId, MAX_MESSAGE_IDS));
|
||||
Ack a;
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
a = db.generateAck(txn, contactId, MAX_MESSAGE_IDS);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated ack: " + (a != null));
|
||||
if (a == null) decrementOutstandingQueries();
|
||||
@@ -166,10 +172,15 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
|
||||
public void run() {
|
||||
if (interrupted) return;
|
||||
try {
|
||||
Collection<Message> b =
|
||||
db.transactionWithNullableResult(false, txn ->
|
||||
db.generateBatch(txn, contactId,
|
||||
MAX_RECORD_PAYLOAD_BYTES, maxLatency));
|
||||
Collection<Message> b;
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
b = db.generateBatch(txn, contactId,
|
||||
MAX_RECORD_PAYLOAD_BYTES, maxLatency);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated batch: " + (b != null));
|
||||
if (b == null) decrementOutstandingQueries();
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.briarproject.bramble.sync;
|
||||
|
||||
import org.briarproject.bramble.api.Pair;
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
@@ -98,8 +97,14 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
@DatabaseExecutor
|
||||
private void validateOutstandingMessages() {
|
||||
try {
|
||||
Queue<MessageId> unvalidated = new LinkedList<>(
|
||||
db.transactionWithResult(true, db::getMessagesToValidate));
|
||||
Queue<MessageId> unvalidated = new LinkedList<>();
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
unvalidated.addAll(db.getMessagesToValidate(txn));
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
validateNextMessageAsync(unvalidated);
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
@@ -114,14 +119,18 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
@DatabaseExecutor
|
||||
private void validateNextMessage(Queue<MessageId> unvalidated) {
|
||||
try {
|
||||
Pair<Message, Group> mg = db.transactionWithResult(true, txn -> {
|
||||
Message m;
|
||||
Group g;
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
MessageId id = unvalidated.poll();
|
||||
if (id == null) throw new AssertionError();
|
||||
Message m = db.getMessage(txn, id);
|
||||
Group g = db.getGroup(txn, m.getGroupId());
|
||||
return new Pair<>(m, g);
|
||||
});
|
||||
validateMessageAsync(mg.getFirst(), mg.getSecond());
|
||||
m = db.getMessage(txn, id);
|
||||
g = db.getGroup(txn, m.getGroupId());
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
validateMessageAsync(m, g);
|
||||
validateNextMessageAsync(unvalidated);
|
||||
} catch (NoSuchMessageException e) {
|
||||
LOG.info("Message removed before validation");
|
||||
@@ -141,8 +150,14 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
@DatabaseExecutor
|
||||
private void deliverOutstandingMessages() {
|
||||
try {
|
||||
Queue<MessageId> pending = new LinkedList<>(
|
||||
db.transactionWithResult(true, db::getPendingMessages));
|
||||
Queue<MessageId> pending = new LinkedList<>();
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
pending.addAll(db.getPendingMessages(txn));
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
deliverNextPendingMessageAsync(pending);
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
@@ -157,12 +172,12 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
@DatabaseExecutor
|
||||
private void deliverNextPendingMessage(Queue<MessageId> pending) {
|
||||
try {
|
||||
Queue<MessageId> toShare = new LinkedList<>();
|
||||
Queue<MessageId> invalidate = new LinkedList<>();
|
||||
db.transaction(false, txn -> {
|
||||
boolean anyInvalid = false, allDelivered = true;
|
||||
boolean anyInvalid = false, allDelivered = true;
|
||||
Queue<MessageId> toShare = null;
|
||||
Queue<MessageId> invalidate = null;
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
MessageId id = pending.poll();
|
||||
if (id == null) throw new AssertionError();
|
||||
// Check if message is still pending
|
||||
if (db.getMessageState(txn, id) == PENDING) {
|
||||
// Check if dependencies are valid and delivered
|
||||
@@ -174,7 +189,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
}
|
||||
if (anyInvalid) {
|
||||
invalidateMessage(txn, id);
|
||||
addDependentsToInvalidate(txn, id, invalidate);
|
||||
invalidate = getDependentsToInvalidate(txn, id);
|
||||
} else if (allDelivered) {
|
||||
Message m = db.getMessage(txn, id);
|
||||
Group g = db.getGroup(txn, m.getGroupId());
|
||||
@@ -185,19 +200,22 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
DeliveryResult result =
|
||||
deliverMessage(txn, m, c, majorVersion, meta);
|
||||
if (result.valid) {
|
||||
addPendingDependents(txn, id, pending);
|
||||
pending.addAll(getPendingDependents(txn, id));
|
||||
if (result.share) {
|
||||
db.setMessageShared(txn, id);
|
||||
toShare.addAll(states.keySet());
|
||||
toShare = new LinkedList<>(states.keySet());
|
||||
}
|
||||
} else {
|
||||
addDependentsToInvalidate(txn, id, invalidate);
|
||||
invalidate = getDependentsToInvalidate(txn, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!invalidate.isEmpty()) invalidateNextMessageAsync(invalidate);
|
||||
if (!toShare.isEmpty()) shareNextMessageAsync(toShare);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
if (invalidate != null) invalidateNextMessageAsync(invalidate);
|
||||
if (toShare != null) shareNextMessageAsync(toShare);
|
||||
deliverNextPendingMessageAsync(pending);
|
||||
} catch (NoSuchMessageException e) {
|
||||
LOG.info("Message removed before delivery");
|
||||
@@ -246,11 +264,12 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
MessageContext context) {
|
||||
try {
|
||||
MessageId id = m.getId();
|
||||
Queue<MessageId> invalidate = new LinkedList<>();
|
||||
Queue<MessageId> pending = new LinkedList<>();
|
||||
Queue<MessageId> toShare = new LinkedList<>();
|
||||
db.transaction(false, txn -> {
|
||||
boolean anyInvalid = false, allDelivered = true;
|
||||
boolean anyInvalid = false, allDelivered = true;
|
||||
Queue<MessageId> invalidate = null;
|
||||
Queue<MessageId> pending = null;
|
||||
Queue<MessageId> toShare = null;
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
// Check if message has any dependencies
|
||||
Collection<MessageId> dependencies = context.getDependencies();
|
||||
if (!dependencies.isEmpty()) {
|
||||
@@ -266,7 +285,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
if (anyInvalid) {
|
||||
if (db.getMessageState(txn, id) != INVALID) {
|
||||
invalidateMessage(txn, id);
|
||||
addDependentsToInvalidate(txn, id, invalidate);
|
||||
invalidate = getDependentsToInvalidate(txn, id);
|
||||
}
|
||||
} else {
|
||||
Metadata meta = context.getMetadata();
|
||||
@@ -275,22 +294,25 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
DeliveryResult result =
|
||||
deliverMessage(txn, m, c, majorVersion, meta);
|
||||
if (result.valid) {
|
||||
addPendingDependents(txn, id, pending);
|
||||
pending = getPendingDependents(txn, id);
|
||||
if (result.share) {
|
||||
db.setMessageShared(txn, id);
|
||||
toShare.addAll(dependencies);
|
||||
toShare = new LinkedList<>(dependencies);
|
||||
}
|
||||
} else {
|
||||
addDependentsToInvalidate(txn, id, invalidate);
|
||||
invalidate = getDependentsToInvalidate(txn, id);
|
||||
}
|
||||
} else {
|
||||
db.setMessageState(txn, id, PENDING);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!invalidate.isEmpty()) invalidateNextMessageAsync(invalidate);
|
||||
if (!pending.isEmpty()) deliverNextPendingMessageAsync(pending);
|
||||
if (!toShare.isEmpty()) shareNextMessageAsync(toShare);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
if (invalidate != null) invalidateNextMessageAsync(invalidate);
|
||||
if (pending != null) deliverNextPendingMessageAsync(pending);
|
||||
if (toShare != null) shareNextMessageAsync(toShare);
|
||||
} catch (NoSuchMessageException e) {
|
||||
LOG.info("Message removed during validation");
|
||||
} catch (NoSuchGroupException e) {
|
||||
@@ -320,12 +342,14 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
}
|
||||
|
||||
@DatabaseExecutor
|
||||
private void addPendingDependents(Transaction txn, MessageId m,
|
||||
Queue<MessageId> pending) throws DbException {
|
||||
private Queue<MessageId> getPendingDependents(Transaction txn, MessageId m)
|
||||
throws DbException {
|
||||
Queue<MessageId> pending = new LinkedList<>();
|
||||
Map<MessageId, State> states = db.getMessageDependents(txn, m);
|
||||
for (Entry<MessageId, State> e : states.entrySet()) {
|
||||
if (e.getValue() == PENDING) pending.add(e.getKey());
|
||||
}
|
||||
return pending;
|
||||
}
|
||||
|
||||
private void shareOutstandingMessagesAsync() {
|
||||
@@ -335,8 +359,14 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
@DatabaseExecutor
|
||||
private void shareOutstandingMessages() {
|
||||
try {
|
||||
Queue<MessageId> toShare = new LinkedList<>(
|
||||
db.transactionWithResult(true, db::getMessagesToShare));
|
||||
Queue<MessageId> toShare = new LinkedList<>();
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
toShare.addAll(db.getMessagesToShare(txn));
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
shareNextMessageAsync(toShare);
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
@@ -357,12 +387,15 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
@DatabaseExecutor
|
||||
private void shareNextMessage(Queue<MessageId> toShare) {
|
||||
try {
|
||||
db.transaction(false, txn -> {
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
MessageId id = toShare.poll();
|
||||
if (id == null) throw new AssertionError();
|
||||
db.setMessageShared(txn, id);
|
||||
toShare.addAll(db.getMessageDependencies(txn, id).keySet());
|
||||
});
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
shareNextMessageAsync(toShare);
|
||||
} catch (NoSuchMessageException e) {
|
||||
LOG.info("Message removed before sharing");
|
||||
@@ -383,14 +416,17 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
@DatabaseExecutor
|
||||
private void invalidateNextMessage(Queue<MessageId> invalidate) {
|
||||
try {
|
||||
db.transaction(false, txn -> {
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
MessageId id = invalidate.poll();
|
||||
if (id == null) throw new AssertionError();
|
||||
if (db.getMessageState(txn, id) != INVALID) {
|
||||
invalidateMessage(txn, id);
|
||||
addDependentsToInvalidate(txn, id, invalidate);
|
||||
invalidate.addAll(getDependentsToInvalidate(txn, id));
|
||||
}
|
||||
});
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
invalidateNextMessageAsync(invalidate);
|
||||
} catch (NoSuchMessageException e) {
|
||||
LOG.info("Message removed before invalidation");
|
||||
@@ -409,12 +445,14 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
}
|
||||
|
||||
@DatabaseExecutor
|
||||
private void addDependentsToInvalidate(Transaction txn,
|
||||
MessageId m, Queue<MessageId> invalidate) throws DbException {
|
||||
private Queue<MessageId> getDependentsToInvalidate(Transaction txn,
|
||||
MessageId m) throws DbException {
|
||||
Queue<MessageId> invalidate = new LinkedList<>();
|
||||
Map<MessageId, State> states = db.getMessageDependents(txn, m);
|
||||
for (Entry<MessageId, State> e : states.entrySet()) {
|
||||
if (e.getValue() != INVALID) invalidate.add(e.getKey());
|
||||
}
|
||||
return invalidate;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -434,8 +472,14 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
@DatabaseExecutor
|
||||
private void loadGroupAndValidate(Message m) {
|
||||
try {
|
||||
Group g = db.transactionWithResult(true, txn ->
|
||||
db.getGroup(txn, m.getGroupId()));
|
||||
Group g;
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
g = db.getGroup(txn, m.getGroupId());
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
validateMessageAsync(m, g);
|
||||
} catch (NoSuchGroupException e) {
|
||||
LOG.info("Group removed before validation");
|
||||
|
||||
@@ -72,7 +72,8 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
|
||||
for (DuplexPluginFactory f : pluginConfig.getDuplexFactories())
|
||||
transports.put(f.getId(), f.getMaxLatency());
|
||||
try {
|
||||
db.transaction(false, txn -> {
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
for (Contact c : db.getContacts(txn))
|
||||
if (c.isActive()) activeContacts.put(c.getId(), true);
|
||||
for (Entry<TransportId, Integer> e : transports.entrySet())
|
||||
@@ -84,7 +85,10 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
|
||||
managers.put(e.getKey(), m);
|
||||
m.start(txn);
|
||||
}
|
||||
});
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
} catch (DbException e) {
|
||||
throw new ServiceException(e);
|
||||
}
|
||||
@@ -137,8 +141,15 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
|
||||
if (LOG.isLoggable(INFO)) LOG.info("No key manager for " + t);
|
||||
return null;
|
||||
}
|
||||
return db.transactionWithNullableResult(false, txn ->
|
||||
m.getStreamContext(txn, c));
|
||||
StreamContext ctx;
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
ctx = m.getStreamContext(txn, c);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -149,8 +160,15 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
|
||||
if (LOG.isLoggable(INFO)) LOG.info("No key manager for " + t);
|
||||
return null;
|
||||
}
|
||||
return db.transactionWithNullableResult(false, txn ->
|
||||
m.getStreamContext(txn, tag));
|
||||
StreamContext ctx;
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
ctx = m.getStreamContext(txn, tag);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -162,7 +162,13 @@ class TransportKeyManagerImpl implements TransportKeyManager {
|
||||
private void rotateKeys() {
|
||||
dbExecutor.execute(() -> {
|
||||
try {
|
||||
db.transaction(false, this::rotateKeys);
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
rotateKeys(txn);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
}
|
||||
|
||||
@@ -123,12 +123,16 @@ class ClientVersioningManagerImpl implements ClientVersioningManager, Client,
|
||||
List<ClientVersion> versions = new ArrayList<>(clients);
|
||||
Collections.sort(versions);
|
||||
try {
|
||||
db.transaction(false, txn -> {
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
if (updateClientVersions(txn, versions)) {
|
||||
for (Contact c : db.getContacts(txn))
|
||||
clientVersionsUpdated(txn, c, versions);
|
||||
}
|
||||
});
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
} catch (DbException e) {
|
||||
throw new ServiceException(e);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
Bridge obfs4 78.46.188.239:37356 5A2D2F4158D0453E00C7C176978D3F41D69C45DB cert=3c0SwxpOisbohNxEc4tb875RVW8eOu1opRTVXJhafaKA/PNNtI7ElQIVOVZg1AdL5bxGCw iat-mode=0
|
||||
Bridge obfs4 52.15.78.72:9443 02069A3C5362476936B62BA6F5ACC41ABD573A9B cert=ijYG/OKc7kqu2YzKNFfeXN7/BG2BOgfEP2KyYEiGDQthnHbsOiTWHeIG0WJVW+BckzDgKw iat-mode=0
|
||||
Bridge obfs4 13.58.29.242:9443 0C58939A77DA6B6B29D4B5236A75865659607AE0 cert=OylWIEHb/ezpq1zWxW0sgKRn+9ARH2eOcQOZ8/Gew+4l+oKOhQ2jUX/Y+FSl61JorXZUWA iat-mode=0
|
||||
Bridge obfs4 45.33.37.112:9443 60A609BB4ABE8D46E634AE81ED29ADAB7776B399 cert=t5v19WmNv5Sc2YPNr8RQids365W7MY8zJwQVkOxBjUMFomMWARDzsbYpcWLLcw0J9Gm+BQ iat-mode=0
|
||||
Bridge 131.252.210.150:8081 0E858AC201BF0F3FA3C462F64844CBFFC7297A42
|
||||
Bridge 67.205.189.122:8443 12D64D5D44E20169585E7378580C0D33A872AD98
|
||||
Bridge 45.32.148.146:8443 0CE016FB2462D8BF179AE71F7D702D09DEAC3F1D
|
||||
Bridge 148.251.90.59:7510 019F727CA6DCA6CA5C90B55E477B7D87981E75BC
|
||||
Bridge 45.55.1.74:8443 6F18FEFBB0CAECD5ABA755312FCCB34FC11A7AB8
|
||||
Bridge 85.229.131.78:444 50E433CCC5FEC11CC34CB4D92033561E065EA106
|
||||
Bridge 178.62.62.193:8443 391B1F9B6A28A1C5FAE1872283985F975E5DB029
|
||||
Bridge 45.76.29.92:8443 ECF1DD51A46FDEF2C50CED992EEEAE8DED18DA0C
|
||||
@@ -22,7 +22,6 @@ import org.briarproject.bramble.api.sync.Message;
|
||||
import org.briarproject.bramble.api.sync.MessageFactory;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.test.BrambleTestCase;
|
||||
import org.briarproject.bramble.test.DbExpectations;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.jmock.Expectations;
|
||||
import org.jmock.Mockery;
|
||||
@@ -86,11 +85,14 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
boolean shared = new Random().nextBoolean();
|
||||
Transaction txn = new Transaction(null, false);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn));
|
||||
oneOf(metadataEncoder).encode(dictionary);
|
||||
will(returnValue(metadata));
|
||||
oneOf(db).addLocalMessage(txn, message, metadata, shared);
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
clientHelper.addLocalMessage(message, dictionary, shared);
|
||||
@@ -114,10 +116,13 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
|
||||
expectToList(true);
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getMessage(txn, messageId);
|
||||
will(returnValue(message));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
clientHelper.getMessageAsList(messageId);
|
||||
@@ -128,12 +133,15 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
public void testGetGroupMetadataAsDictionary() throws Exception {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getGroupMetadata(txn, groupId);
|
||||
will(returnValue(metadata));
|
||||
oneOf(metadataParser).parse(metadata);
|
||||
will(returnValue(dictionary));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
assertEquals(dictionary,
|
||||
@@ -145,12 +153,15 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
public void testGetMessageMetadataAsDictionary() throws Exception {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getMessageMetadata(txn, messageId);
|
||||
will(returnValue(metadata));
|
||||
oneOf(metadataParser).parse(metadata);
|
||||
will(returnValue(dictionary));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
assertEquals(dictionary,
|
||||
@@ -164,12 +175,15 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
map.put(messageId, dictionary);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getMessageMetadata(txn, groupId);
|
||||
will(returnValue(Collections.singletonMap(messageId, metadata)));
|
||||
oneOf(metadataParser).parse(metadata);
|
||||
will(returnValue(dictionary));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
assertEquals(map, clientHelper.getMessageMetadataAsDictionary(groupId));
|
||||
@@ -186,14 +200,17 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
queryMetadata.put("query", getRandomBytes(42));
|
||||
Transaction txn = new Transaction(null, true);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(metadataEncoder).encode(query);
|
||||
will(returnValue(queryMetadata));
|
||||
oneOf(db).getMessageMetadata(txn, groupId, queryMetadata);
|
||||
will(returnValue(Collections.singletonMap(messageId, metadata)));
|
||||
oneOf(metadataParser).parse(metadata);
|
||||
will(returnValue(dictionary));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
assertEquals(map,
|
||||
@@ -205,11 +222,14 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
public void testMergeGroupMetadata() throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn));
|
||||
oneOf(metadataEncoder).encode(dictionary);
|
||||
will(returnValue(metadata));
|
||||
oneOf(db).mergeGroupMetadata(txn, groupId, metadata);
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
clientHelper.mergeGroupMetadata(groupId, dictionary);
|
||||
@@ -220,11 +240,14 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
public void testMergeMessageMetadata() throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn));
|
||||
oneOf(metadataEncoder).encode(dictionary);
|
||||
will(returnValue(metadata));
|
||||
oneOf(db).mergeMessageMetadata(txn, messageId, metadata);
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
clientHelper.mergeMessageMetadata(messageId, dictionary);
|
||||
|
||||
@@ -69,14 +69,17 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
boolean alice = new Random().nextBoolean();
|
||||
Transaction txn = new Transaction(null, false);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transactionWithResult(with(false), withDbCallable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).addContact(txn, remote, local, verified, active);
|
||||
will(returnValue(contactId));
|
||||
oneOf(keyManager).addContact(txn, contactId, master, timestamp,
|
||||
alice, active);
|
||||
oneOf(db).getContact(txn, contactId);
|
||||
will(returnValue(contact));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
assertEquals(contactId, contactManager.addContact(remote, local,
|
||||
@@ -86,10 +89,13 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
@Test
|
||||
public void testGetContact() throws Exception {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getContact(txn, contactId);
|
||||
will(returnValue(contact));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
assertEquals(contact, contactManager.getContact(contactId));
|
||||
@@ -99,10 +105,13 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
public void testGetContactByAuthor() throws Exception {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Collection<Contact> contacts = Collections.singleton(contact);
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getContactsByAuthorId(txn, remote.getId());
|
||||
will(returnValue(contacts));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
assertEquals(contact, contactManager.getContact(remote.getId(), local));
|
||||
@@ -111,10 +120,12 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
@Test(expected = NoSuchContactException.class)
|
||||
public void testGetContactByUnknownAuthor() throws Exception {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getContactsByAuthorId(txn, remote.getId());
|
||||
will(returnValue(emptyList()));
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
contactManager.getContact(remote.getId(), local);
|
||||
@@ -124,26 +135,31 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
public void testGetContactByUnknownLocalAuthor() throws Exception {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Collection<Contact> contacts = Collections.singleton(contact);
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getContactsByAuthorId(txn, remote.getId());
|
||||
will(returnValue(contacts));
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
contactManager.getContact(remote.getId(), new AuthorId(getRandomId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetActiveContacts() throws Exception {
|
||||
public void testActiveContacts() throws Exception {
|
||||
Collection<Contact> activeContacts = Collections.singletonList(contact);
|
||||
Collection<Contact> contacts = new ArrayList<>(activeContacts);
|
||||
contacts.add(new Contact(new ContactId(3), remote, local, alias, true,
|
||||
false));
|
||||
Transaction txn = new Transaction(null, true);
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getContacts(txn);
|
||||
will(returnValue(contacts));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
assertEquals(activeContacts, contactManager.getActiveContacts());
|
||||
@@ -152,11 +168,14 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
@Test
|
||||
public void testRemoveContact() throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getContact(txn, contactId);
|
||||
will(returnValue(contact));
|
||||
oneOf(db).removeContact(txn, contactId);
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
contactManager.removeContact(contactId);
|
||||
@@ -176,7 +195,7 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
public void testSetContactAlias() throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||
oneOf(db).transaction(with(equal(false)), withDbRunnable(txn));
|
||||
oneOf(db).setContactAlias(txn, contactId, alias);
|
||||
}});
|
||||
|
||||
@@ -185,32 +204,35 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testSetContactAliasTooLong() throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
contactManager.setContactAlias(txn, contactId,
|
||||
contactManager.setContactAlias(contactId,
|
||||
getRandomString(MAX_AUTHOR_NAME_LENGTH + 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContactExists() throws Exception {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).containsContact(txn, remote.getId(), local);
|
||||
will(returnValue(true));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
assertTrue(contactManager.contactExists(remote.getId(), local));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAuthorInfo() throws Exception {
|
||||
public void testGetAuthorStatus() throws Exception {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Collection<Contact> contacts = singletonList(
|
||||
new Contact(new ContactId(1), remote, localAuthor.getId(),
|
||||
alias, false, true));
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
oneOf(db).transactionWithResult(with(equal(true)),
|
||||
withDbCallable(txn));
|
||||
oneOf(identityManager).getLocalAuthor(txn);
|
||||
will(returnValue(localAuthor));
|
||||
oneOf(db).getContactsByAuthorId(txn, remote.getId());
|
||||
@@ -223,7 +245,7 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAuthorInfoTransaction() throws DbException {
|
||||
public void testGetAuthorStatusTransaction() throws DbException {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
|
||||
// check unknown author
|
||||
@@ -242,7 +264,7 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
Collection<Contact> contacts = singletonList(
|
||||
new Contact(new ContactId(1), remote, localAuthor.getId(),
|
||||
alias, false, true));
|
||||
checkAuthorInfoContext(txn, remote.getId(), contacts);
|
||||
checkAuthorStatusContext(txn, remote.getId(), contacts);
|
||||
authorInfo = contactManager.getAuthorInfo(txn, remote.getId());
|
||||
assertEquals(UNVERIFIED, authorInfo.getStatus());
|
||||
assertEquals(alias, contact.getAlias());
|
||||
@@ -250,7 +272,7 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
// check verified contact
|
||||
contacts = singletonList(new Contact(new ContactId(1), remote,
|
||||
localAuthor.getId(), alias, true, true));
|
||||
checkAuthorInfoContext(txn, remote.getId(), contacts);
|
||||
checkAuthorStatusContext(txn, remote.getId(), contacts);
|
||||
authorInfo = contactManager.getAuthorInfo(txn, remote.getId());
|
||||
assertEquals(VERIFIED, authorInfo.getStatus());
|
||||
assertEquals(alias, contact.getAlias());
|
||||
@@ -266,7 +288,7 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
assertNull(authorInfo.getAlias());
|
||||
}
|
||||
|
||||
private void checkAuthorInfoContext(Transaction txn, AuthorId authorId,
|
||||
private void checkAuthorStatusContext(Transaction txn, AuthorId authorId,
|
||||
Collection<Contact> contacts) throws DbException {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(identityManager).getLocalAuthor(txn);
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
package org.briarproject.bramble.data;
|
||||
|
||||
import org.briarproject.bramble.test.BrambleTestCase;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.briarproject.bramble.api.data.BdfReader.DEFAULT_MAX_BUFFER_SIZE;
|
||||
import static org.briarproject.bramble.api.data.BdfReader.DEFAULT_NESTED_LIMIT;
|
||||
import static org.briarproject.bramble.test.TestUtils.isOptionalTestEnabled;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
|
||||
public class BdfReaderImplFuzzingTest extends BrambleTestCase {
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
assumeTrue(isOptionalTestEnabled(BdfReaderImplFuzzingTest.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringFuzzing() throws Exception {
|
||||
Random random = new Random();
|
||||
byte[] buf = new byte[22];
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(buf);
|
||||
for (int i = 0; i < 100_000_000; i++) {
|
||||
random.nextBytes(buf);
|
||||
buf[0] = 0x41; // String with 1-byte length
|
||||
buf[1] = 0x14; // Length 20 bytes
|
||||
in.reset();
|
||||
BdfReaderImpl r = new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT,
|
||||
DEFAULT_MAX_BUFFER_SIZE);
|
||||
int length = r.readString().length();
|
||||
assertTrue(length >= 0);
|
||||
assertTrue(length <= 20);
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,7 +11,6 @@ import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.briarproject.bramble.test.DbExpectations;
|
||||
import org.jmock.Expectations;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -65,10 +64,13 @@ public class IdentityManagerImplTest extends BrambleMockTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegisterAndStoreLocalAuthor() throws Exception {
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||
public void testRegisterAndStoreLocalAuthor() throws DbException {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).addLocalAuthor(txn, localAuthor);
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
identityManager.registerLocalAuthor(localAuthor);
|
||||
@@ -77,11 +79,14 @@ public class IdentityManagerImplTest extends BrambleMockTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLocalAuthor() throws Exception {
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
public void testGetLocalAuthor() throws DbException {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getLocalAuthors(txn);
|
||||
will(returnValue(localAuthors));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
assertEquals(localAuthor, identityManager.getLocalAuthor());
|
||||
}
|
||||
|
||||
@@ -21,18 +21,16 @@ import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.api.versioning.ClientVersioningManager;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.briarproject.bramble.test.DbExpectations;
|
||||
import org.jmock.Expectations;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static org.briarproject.bramble.api.properties.TransportPropertyManager.CLIENT_ID;
|
||||
import static org.briarproject.bramble.api.properties.TransportPropertyManager.MAJOR_VERSION;
|
||||
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
||||
@@ -353,11 +351,14 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
||||
new BdfEntry("local", true)
|
||||
));
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
localGroup.getId());
|
||||
will(returnValue(messageMetadata));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
TransportPropertyManagerImpl t = createInstance();
|
||||
@@ -385,8 +386,9 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
||||
));
|
||||
BdfList fooUpdate = BdfList.of("foo", 1, fooPropertiesDict);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
localGroup.getId());
|
||||
will(returnValue(messageMetadata));
|
||||
@@ -395,6 +397,8 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
||||
oneOf(clientHelper).parseAndValidateTransportProperties(
|
||||
fooPropertiesDict);
|
||||
will(returnValue(fooProperties));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
TransportPropertyManagerImpl t = createInstance();
|
||||
@@ -409,7 +413,8 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
||||
Contact contact1 = getContact(false);
|
||||
Contact contact2 = getContact(true);
|
||||
Contact contact3 = getContact(true);
|
||||
List<Contact> contacts = asList(contact1, contact2, contact3);
|
||||
List<Contact> contacts =
|
||||
Arrays.asList(contact1, contact2, contact3);
|
||||
Group contactGroup2 = getGroup(CLIENT_ID, MAJOR_VERSION);
|
||||
Group contactGroup3 = getGroup(CLIENT_ID, MAJOR_VERSION);
|
||||
Map<MessageId, BdfDictionary> messageMetadata3 =
|
||||
@@ -437,8 +442,9 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
||||
));
|
||||
BdfList fooUpdate = BdfList.of("foo", 1, fooPropertiesDict);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getContacts(txn);
|
||||
will(returnValue(contacts));
|
||||
// First contact: skipped because not active
|
||||
@@ -461,6 +467,8 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
||||
oneOf(clientHelper).parseAndValidateTransportProperties(
|
||||
fooPropertiesDict);
|
||||
will(returnValue(fooProperties));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
TransportPropertyManagerImpl t = createInstance();
|
||||
@@ -477,16 +485,17 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
||||
throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
MessageId updateId = new MessageId(getRandomId());
|
||||
Map<MessageId, BdfDictionary> messageMetadata = singletonMap(updateId,
|
||||
BdfDictionary.of(
|
||||
Map<MessageId, BdfDictionary> messageMetadata =
|
||||
Collections.singletonMap(updateId, BdfDictionary.of(
|
||||
new BdfEntry("transportId", "foo"),
|
||||
new BdfEntry("version", 1),
|
||||
new BdfEntry("local", true)
|
||||
));
|
||||
BdfList update = BdfList.of("foo", 1, fooPropertiesDict);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn));
|
||||
// Merge the new properties with the existing properties
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
localGroup.getId());
|
||||
@@ -497,6 +506,8 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
||||
fooPropertiesDict);
|
||||
will(returnValue(fooProperties));
|
||||
// Properties are unchanged so we're done
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
TransportPropertyManagerImpl t = createInstance();
|
||||
@@ -509,8 +520,9 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
||||
Contact contact = getContact(true);
|
||||
Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn));
|
||||
// There are no existing properties to merge with
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
localGroup.getId());
|
||||
@@ -529,6 +541,8 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
||||
will(returnValue(Collections.emptyMap()));
|
||||
expectStoreMessage(txn, contactGroup.getId(), "foo",
|
||||
fooPropertiesDict, 1, true, true);
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
TransportPropertyManagerImpl t = createInstance();
|
||||
@@ -547,10 +561,10 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
||||
);
|
||||
MessageId localGroupUpdateId = new MessageId(getRandomId());
|
||||
Map<MessageId, BdfDictionary> localGroupMessageMetadata =
|
||||
singletonMap(localGroupUpdateId, oldMetadata);
|
||||
Collections.singletonMap(localGroupUpdateId, oldMetadata);
|
||||
MessageId contactGroupUpdateId = new MessageId(getRandomId());
|
||||
Map<MessageId, BdfDictionary> contactGroupMessageMetadata =
|
||||
singletonMap(contactGroupUpdateId, oldMetadata);
|
||||
Collections.singletonMap(contactGroupUpdateId, oldMetadata);
|
||||
TransportProperties oldProperties = new TransportProperties();
|
||||
oldProperties.put("fooKey1", "oldFooValue1");
|
||||
BdfDictionary oldPropertiesDict = BdfDictionary.of(
|
||||
@@ -558,8 +572,9 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
||||
);
|
||||
BdfList oldUpdate = BdfList.of("foo", 1, oldPropertiesDict);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn));
|
||||
// Merge the new properties with the existing properties
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
localGroup.getId());
|
||||
@@ -587,6 +602,8 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
||||
fooPropertiesDict, 2, true, true);
|
||||
// Delete the previous update
|
||||
oneOf(db).removeMessage(txn, contactGroupUpdateId);
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
TransportPropertyManagerImpl t = createInstance();
|
||||
|
||||
@@ -11,8 +11,8 @@ import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.sync.SyncRecordWriter;
|
||||
import org.briarproject.bramble.api.transport.StreamWriter;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.briarproject.bramble.test.DbExpectations;
|
||||
import org.briarproject.bramble.test.ImmediateExecutor;
|
||||
import org.jmock.Expectations;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
@@ -45,20 +45,24 @@ public class SimplexOutgoingSessionTest extends BrambleMockTestCase {
|
||||
Transaction noAckTxn = new Transaction(null, false);
|
||||
Transaction noMsgTxn = new Transaction(null, false);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
context.checking(new Expectations() {{
|
||||
// Add listener
|
||||
oneOf(eventBus).addListener(session);
|
||||
// No acks to send
|
||||
oneOf(db).transactionWithNullableResult(with(false),
|
||||
withNullableDbCallable(noAckTxn));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(noAckTxn));
|
||||
oneOf(db).generateAck(noAckTxn, contactId, MAX_MESSAGE_IDS);
|
||||
will(returnValue(null));
|
||||
oneOf(db).commitTransaction(noAckTxn);
|
||||
oneOf(db).endTransaction(noAckTxn);
|
||||
// No messages to send
|
||||
oneOf(db).transactionWithNullableResult(with(false),
|
||||
withNullableDbCallable(noMsgTxn));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(noMsgTxn));
|
||||
oneOf(db).generateBatch(with(noMsgTxn), with(contactId),
|
||||
with(any(int.class)), with(MAX_LATENCY));
|
||||
will(returnValue(null));
|
||||
oneOf(db).commitTransaction(noMsgTxn);
|
||||
oneOf(db).endTransaction(noMsgTxn);
|
||||
// Send the end of stream marker
|
||||
oneOf(streamWriter).sendEndOfStream();
|
||||
// Remove listener
|
||||
@@ -79,33 +83,41 @@ public class SimplexOutgoingSessionTest extends BrambleMockTestCase {
|
||||
Transaction msgTxn = new Transaction(null, false);
|
||||
Transaction noMsgTxn = new Transaction(null, false);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
context.checking(new Expectations() {{
|
||||
// Add listener
|
||||
oneOf(eventBus).addListener(session);
|
||||
// One ack to send
|
||||
oneOf(db).transactionWithNullableResult(with(false),
|
||||
withNullableDbCallable(ackTxn));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(ackTxn));
|
||||
oneOf(db).generateAck(ackTxn, contactId, MAX_MESSAGE_IDS);
|
||||
will(returnValue(ack));
|
||||
oneOf(db).commitTransaction(ackTxn);
|
||||
oneOf(db).endTransaction(ackTxn);
|
||||
oneOf(recordWriter).writeAck(ack);
|
||||
// One message to send
|
||||
oneOf(db).transactionWithNullableResult(with(false),
|
||||
withNullableDbCallable(msgTxn));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(msgTxn));
|
||||
oneOf(db).generateBatch(with(msgTxn), with(contactId),
|
||||
with(any(int.class)), with(MAX_LATENCY));
|
||||
will(returnValue(singletonList(message)));
|
||||
oneOf(db).commitTransaction(msgTxn);
|
||||
oneOf(db).endTransaction(msgTxn);
|
||||
oneOf(recordWriter).writeMessage(message);
|
||||
// No more acks
|
||||
oneOf(db).transactionWithNullableResult(with(false),
|
||||
withNullableDbCallable(noAckTxn));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(noAckTxn));
|
||||
oneOf(db).generateAck(noAckTxn, contactId, MAX_MESSAGE_IDS);
|
||||
will(returnValue(null));
|
||||
oneOf(db).commitTransaction(noAckTxn);
|
||||
oneOf(db).endTransaction(noAckTxn);
|
||||
// No more messages
|
||||
oneOf(db).transactionWithNullableResult(with(false),
|
||||
withNullableDbCallable(noMsgTxn));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(noMsgTxn));
|
||||
oneOf(db).generateBatch(with(noMsgTxn), with(contactId),
|
||||
with(any(int.class)), with(MAX_LATENCY));
|
||||
will(returnValue(null));
|
||||
oneOf(db).commitTransaction(noMsgTxn);
|
||||
oneOf(db).endTransaction(noMsgTxn);
|
||||
// Send the end of stream marker
|
||||
oneOf(streamWriter).sendEndOfStream();
|
||||
// Remove listener
|
||||
|
||||
@@ -18,16 +18,16 @@ import org.briarproject.bramble.api.sync.ValidationManager.MessageValidator;
|
||||
import org.briarproject.bramble.api.sync.ValidationManager.State;
|
||||
import org.briarproject.bramble.api.sync.event.MessageAddedEvent;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.briarproject.bramble.test.DbExpectations;
|
||||
import org.briarproject.bramble.test.ImmediateExecutor;
|
||||
import org.jmock.Expectations;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static java.util.Collections.singletonList;
|
||||
@@ -83,19 +83,28 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
Transaction txn1 = new Transaction(null, true);
|
||||
Transaction txn2 = new Transaction(null, true);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
context.checking(new Expectations() {{
|
||||
// validateOutstandingMessages()
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getMessagesToValidate(txn);
|
||||
will(returnValue(emptyList()));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
// deliverOutstandingMessages()
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn1));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn1));
|
||||
oneOf(db).getPendingMessages(txn1);
|
||||
will(returnValue(emptyList()));
|
||||
oneOf(db).commitTransaction(txn1);
|
||||
oneOf(db).endTransaction(txn1);
|
||||
// shareOutstandingMessages()
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn2));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn2));
|
||||
oneOf(db).getMessagesToShare(txn2);
|
||||
will(returnValue(emptyList()));
|
||||
oneOf(db).commitTransaction(txn2);
|
||||
oneOf(db).endTransaction(txn2);
|
||||
}});
|
||||
|
||||
vm.startService();
|
||||
@@ -112,22 +121,29 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
Transaction txn5 = new Transaction(null, true);
|
||||
Transaction txn6 = new Transaction(null, true);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
context.checking(new Expectations() {{
|
||||
// Get messages to validate
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getMessagesToValidate(txn);
|
||||
will(returnValue(asList(messageId, messageId1)));
|
||||
will(returnValue(Arrays.asList(messageId, messageId1)));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
// Load the first raw message and group
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn1));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn1));
|
||||
oneOf(db).getMessage(txn1, messageId);
|
||||
will(returnValue(message));
|
||||
oneOf(db).getGroup(txn1, groupId);
|
||||
will(returnValue(group));
|
||||
oneOf(db).commitTransaction(txn1);
|
||||
oneOf(db).endTransaction(txn1);
|
||||
// Validate the first message: valid
|
||||
oneOf(validator).validateMessage(message, group);
|
||||
will(returnValue(validResult));
|
||||
// Store the validation result for the first message
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn2));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn2));
|
||||
oneOf(db).mergeMessageMetadata(txn2, messageId, metadata);
|
||||
// Deliver the first message
|
||||
oneOf(hook).incomingMessage(txn2, message, metadata);
|
||||
@@ -136,17 +152,23 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
// Get any pending dependents
|
||||
oneOf(db).getMessageDependents(txn2, messageId);
|
||||
will(returnValue(emptyMap()));
|
||||
oneOf(db).commitTransaction(txn2);
|
||||
oneOf(db).endTransaction(txn2);
|
||||
// Load the second raw message and group
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn3));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn3));
|
||||
oneOf(db).getMessage(txn3, messageId1);
|
||||
will(returnValue(message1));
|
||||
oneOf(db).getGroup(txn3, groupId);
|
||||
will(returnValue(group));
|
||||
oneOf(db).commitTransaction(txn3);
|
||||
oneOf(db).endTransaction(txn3);
|
||||
// Validate the second message: invalid
|
||||
oneOf(validator).validateMessage(message1, group);
|
||||
will(throwException(new InvalidMessageException()));
|
||||
// Store the validation result for the second message
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn4));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn4));
|
||||
oneOf(db).getMessageState(txn4, messageId1);
|
||||
will(returnValue(UNKNOWN));
|
||||
oneOf(db).setMessageState(txn4, messageId1, INVALID);
|
||||
@@ -155,14 +177,22 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
// Recursively invalidate any dependents
|
||||
oneOf(db).getMessageDependents(txn4, messageId1);
|
||||
will(returnValue(emptyMap()));
|
||||
oneOf(db).commitTransaction(txn4);
|
||||
oneOf(db).endTransaction(txn4);
|
||||
// Get pending messages to deliver
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn5));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn5));
|
||||
oneOf(db).getPendingMessages(txn5);
|
||||
will(returnValue(emptyList()));
|
||||
oneOf(db).commitTransaction(txn5);
|
||||
oneOf(db).endTransaction(txn5);
|
||||
// Get messages to share
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn6));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn6));
|
||||
oneOf(db).getMessagesToShare(txn6);
|
||||
will(returnValue(emptyList()));
|
||||
oneOf(db).commitTransaction(txn6);
|
||||
oneOf(db).endTransaction(txn6);
|
||||
}});
|
||||
|
||||
vm.startService();
|
||||
@@ -176,17 +206,24 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
Transaction txn3 = new Transaction(null, false);
|
||||
Transaction txn4 = new Transaction(null, true);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
context.checking(new Expectations() {{
|
||||
// Get messages to validate
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getMessagesToValidate(txn);
|
||||
will(returnValue(emptyList()));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
// Get pending messages to deliver
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn1));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn1));
|
||||
oneOf(db).getPendingMessages(txn1);
|
||||
will(returnValue(singletonList(messageId)));
|
||||
oneOf(db).commitTransaction(txn1);
|
||||
oneOf(db).endTransaction(txn1);
|
||||
// Check whether the message is ready to deliver
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn2));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn2));
|
||||
oneOf(db).getMessageState(txn2, messageId);
|
||||
will(returnValue(PENDING));
|
||||
oneOf(db).getMessageDependencies(txn2, messageId);
|
||||
@@ -205,8 +242,11 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
// Get any pending dependents
|
||||
oneOf(db).getMessageDependents(txn2, messageId);
|
||||
will(returnValue(singletonMap(messageId2, PENDING)));
|
||||
oneOf(db).commitTransaction(txn2);
|
||||
oneOf(db).endTransaction(txn2);
|
||||
// Check whether the dependent is ready to deliver
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn3));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn3));
|
||||
oneOf(db).getMessageState(txn3, messageId2);
|
||||
will(returnValue(PENDING));
|
||||
oneOf(db).getMessageDependencies(txn3, messageId2);
|
||||
@@ -225,11 +265,16 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
// Get any pending dependents
|
||||
oneOf(db).getMessageDependents(txn3, messageId2);
|
||||
will(returnValue(emptyMap()));
|
||||
oneOf(db).commitTransaction(txn3);
|
||||
oneOf(db).endTransaction(txn3);
|
||||
|
||||
// Get messages to share
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn4));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn4));
|
||||
oneOf(db).getMessagesToShare(txn4);
|
||||
will(returnValue(emptyList()));
|
||||
oneOf(db).commitTransaction(txn4);
|
||||
oneOf(db).endTransaction(txn4);
|
||||
}});
|
||||
|
||||
vm.startService();
|
||||
@@ -243,30 +288,45 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
Transaction txn3 = new Transaction(null, false);
|
||||
Transaction txn4 = new Transaction(null, false);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
context.checking(new Expectations() {{
|
||||
// No messages to validate
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getMessagesToValidate(txn);
|
||||
will(returnValue(emptyList()));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
// No pending messages to deliver
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn1));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn1));
|
||||
oneOf(db).getPendingMessages(txn1);
|
||||
will(returnValue(emptyList()));
|
||||
oneOf(db).commitTransaction(txn1);
|
||||
oneOf(db).endTransaction(txn1);
|
||||
|
||||
// Get messages to share
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn2));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn2));
|
||||
oneOf(db).getMessagesToShare(txn2);
|
||||
will(returnValue(singletonList(messageId)));
|
||||
oneOf(db).commitTransaction(txn2);
|
||||
oneOf(db).endTransaction(txn2);
|
||||
// Share message and get dependencies
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn3));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn3));
|
||||
oneOf(db).setMessageShared(txn3, messageId);
|
||||
oneOf(db).getMessageDependencies(txn3, messageId);
|
||||
will(returnValue(singletonMap(messageId2, DELIVERED)));
|
||||
oneOf(db).commitTransaction(txn3);
|
||||
oneOf(db).endTransaction(txn3);
|
||||
// Share dependency
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn4));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn4));
|
||||
oneOf(db).setMessageShared(txn4, messageId2);
|
||||
oneOf(db).getMessageDependencies(txn4, messageId2);
|
||||
will(returnValue(emptyMap()));
|
||||
oneOf(db).commitTransaction(txn4);
|
||||
oneOf(db).endTransaction(txn4);
|
||||
}});
|
||||
|
||||
vm.startService();
|
||||
@@ -278,16 +338,20 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
Transaction txn1 = new Transaction(null, false);
|
||||
Transaction txn2 = new Transaction(null, false);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
context.checking(new Expectations() {{
|
||||
// Load the group
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getGroup(txn, groupId);
|
||||
will(returnValue(group));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
// Validate the message: valid
|
||||
oneOf(validator).validateMessage(message, group);
|
||||
will(returnValue(validResultWithDependencies));
|
||||
// Store the validation result
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn1));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn1));
|
||||
oneOf(db).addMessageDependencies(txn1, message,
|
||||
validResultWithDependencies.getDependencies());
|
||||
oneOf(db).getMessageDependencies(txn1, messageId);
|
||||
@@ -302,11 +366,16 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
will(returnValue(emptyMap()));
|
||||
// Share message
|
||||
oneOf(db).setMessageShared(txn1, messageId);
|
||||
oneOf(db).commitTransaction(txn1);
|
||||
oneOf(db).endTransaction(txn1);
|
||||
// Share dependencies
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn2));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn2));
|
||||
oneOf(db).setMessageShared(txn2, messageId1);
|
||||
oneOf(db).getMessageDependencies(txn2, messageId1);
|
||||
will(returnValue(emptyMap()));
|
||||
oneOf(db).commitTransaction(txn2);
|
||||
oneOf(db).endTransaction(txn2);
|
||||
}});
|
||||
|
||||
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
||||
@@ -322,26 +391,36 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
Transaction txn4 = new Transaction(null, true);
|
||||
Transaction txn5 = new Transaction(null, true);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
context.checking(new Expectations() {{
|
||||
// Get messages to validate
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getMessagesToValidate(txn);
|
||||
will(returnValue(asList(messageId, messageId1)));
|
||||
will(returnValue(Arrays.asList(messageId, messageId1)));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
// Load the first raw message - *gasp* it's gone!
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn1));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn1));
|
||||
oneOf(db).getMessage(txn1, messageId);
|
||||
will(throwException(new NoSuchMessageException()));
|
||||
never(db).commitTransaction(txn1);
|
||||
oneOf(db).endTransaction(txn1);
|
||||
// Load the second raw message and group
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn2));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn2));
|
||||
oneOf(db).getMessage(txn2, messageId1);
|
||||
will(returnValue(message1));
|
||||
oneOf(db).getGroup(txn2, groupId);
|
||||
will(returnValue(group));
|
||||
oneOf(db).commitTransaction(txn2);
|
||||
oneOf(db).endTransaction(txn2);
|
||||
// Validate the second message: invalid
|
||||
oneOf(validator).validateMessage(message1, group);
|
||||
will(throwException(new InvalidMessageException()));
|
||||
// Invalidate the second message
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn3));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn3));
|
||||
oneOf(db).getMessageState(txn3, messageId1);
|
||||
will(returnValue(UNKNOWN));
|
||||
oneOf(db).setMessageState(txn3, messageId1, INVALID);
|
||||
@@ -350,14 +429,22 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
// Recursively invalidate dependents
|
||||
oneOf(db).getMessageDependents(txn3, messageId1);
|
||||
will(returnValue(emptyMap()));
|
||||
oneOf(db).commitTransaction(txn3);
|
||||
oneOf(db).endTransaction(txn3);
|
||||
// Get pending messages to deliver
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn4));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn4));
|
||||
oneOf(db).getPendingMessages(txn4);
|
||||
will(returnValue(emptyList()));
|
||||
oneOf(db).commitTransaction(txn4);
|
||||
oneOf(db).endTransaction(txn4);
|
||||
// Get messages to share
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn5));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn5));
|
||||
oneOf(db).getMessagesToShare(txn5);
|
||||
will(returnValue(emptyList()));
|
||||
oneOf(db).commitTransaction(txn5);
|
||||
oneOf(db).endTransaction(txn5);
|
||||
}});
|
||||
|
||||
vm.startService();
|
||||
@@ -373,29 +460,39 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
Transaction txn4 = new Transaction(null, true);
|
||||
Transaction txn5 = new Transaction(null, true);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
context.checking(new Expectations() {{
|
||||
// Get messages to validate
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getMessagesToValidate(txn);
|
||||
will(returnValue(asList(messageId, messageId1)));
|
||||
will(returnValue(Arrays.asList(messageId, messageId1)));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
// Load the first raw message
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn1));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn1));
|
||||
oneOf(db).getMessage(txn1, messageId);
|
||||
will(returnValue(message));
|
||||
// Load the group - *gasp* it's gone!
|
||||
oneOf(db).getGroup(txn1, groupId);
|
||||
will(throwException(new NoSuchGroupException()));
|
||||
never(db).commitTransaction(txn1);
|
||||
oneOf(db).endTransaction(txn1);
|
||||
// Load the second raw message and group
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn2));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn2));
|
||||
oneOf(db).getMessage(txn2, messageId1);
|
||||
will(returnValue(message1));
|
||||
oneOf(db).getGroup(txn2, groupId);
|
||||
will(returnValue(group));
|
||||
oneOf(db).commitTransaction(txn2);
|
||||
oneOf(db).endTransaction(txn2);
|
||||
// Validate the second message: invalid
|
||||
oneOf(validator).validateMessage(message1, group);
|
||||
will(throwException(new InvalidMessageException()));
|
||||
// Store the validation result for the second message
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn3));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn3));
|
||||
oneOf(db).getMessageState(txn3, messageId1);
|
||||
will(returnValue(UNKNOWN));
|
||||
oneOf(db).setMessageState(txn3, messageId1, INVALID);
|
||||
@@ -404,14 +501,22 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
// Recursively invalidate dependents
|
||||
oneOf(db).getMessageDependents(txn3, messageId1);
|
||||
will(returnValue(emptyMap()));
|
||||
oneOf(db).commitTransaction(txn3);
|
||||
oneOf(db).endTransaction(txn3);
|
||||
// Get pending messages to deliver
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn4));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn4));
|
||||
oneOf(db).getPendingMessages(txn4);
|
||||
will(returnValue(emptyList()));
|
||||
oneOf(db).commitTransaction(txn4);
|
||||
oneOf(db).endTransaction(txn4);
|
||||
// Get messages to share
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn5));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn5));
|
||||
oneOf(db).getMessagesToShare(txn5);
|
||||
will(returnValue(emptyList()));
|
||||
oneOf(db).commitTransaction(txn5);
|
||||
oneOf(db).endTransaction(txn5);
|
||||
}});
|
||||
|
||||
vm.startService();
|
||||
@@ -422,16 +527,20 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Transaction txn1 = new Transaction(null, false);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
context.checking(new Expectations() {{
|
||||
// Load the group
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getGroup(txn, groupId);
|
||||
will(returnValue(group));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
// Validate the message: valid
|
||||
oneOf(validator).validateMessage(message, group);
|
||||
will(returnValue(validResult));
|
||||
// Store the validation result
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn1));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn1));
|
||||
oneOf(db).mergeMessageMetadata(txn1, messageId, metadata);
|
||||
// Deliver the message
|
||||
oneOf(hook).incomingMessage(txn1, message, metadata);
|
||||
@@ -440,6 +549,8 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
// Get any pending dependents
|
||||
oneOf(db).getMessageDependents(txn1, messageId);
|
||||
will(returnValue(emptyMap()));
|
||||
oneOf(db).commitTransaction(txn1);
|
||||
oneOf(db).endTransaction(txn1);
|
||||
}});
|
||||
|
||||
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
||||
@@ -456,22 +567,28 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Transaction txn1 = new Transaction(null, false);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
context.checking(new Expectations() {{
|
||||
// Load the group
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getGroup(txn, groupId);
|
||||
will(returnValue(group));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
// Validate the message: valid
|
||||
oneOf(validator).validateMessage(message, group);
|
||||
will(returnValue(validResultWithDependencies));
|
||||
// Store the validation result
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn1));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn1));
|
||||
oneOf(db).addMessageDependencies(txn1, message,
|
||||
validResultWithDependencies.getDependencies());
|
||||
oneOf(db).getMessageDependencies(txn1, messageId);
|
||||
will(returnValue(singletonMap(messageId1, UNKNOWN)));
|
||||
oneOf(db).mergeMessageMetadata(txn1, messageId, metadata);
|
||||
oneOf(db).setMessageState(txn1, messageId, PENDING);
|
||||
oneOf(db).commitTransaction(txn1);
|
||||
oneOf(db).endTransaction(txn1);
|
||||
}});
|
||||
|
||||
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
||||
@@ -483,16 +600,20 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Transaction txn1 = new Transaction(null, false);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
context.checking(new Expectations() {{
|
||||
// Load the group
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getGroup(txn, groupId);
|
||||
will(returnValue(group));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
// Validate the message: valid
|
||||
oneOf(validator).validateMessage(message, group);
|
||||
will(returnValue(validResultWithDependencies));
|
||||
// Store the validation result
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn1));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn1));
|
||||
oneOf(db).addMessageDependencies(txn1, message,
|
||||
validResultWithDependencies.getDependencies());
|
||||
oneOf(db).getMessageDependencies(txn1, messageId);
|
||||
@@ -505,6 +626,8 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
// Get any pending dependents
|
||||
oneOf(db).getMessageDependents(txn1, messageId);
|
||||
will(returnValue(emptyMap()));
|
||||
oneOf(db).commitTransaction(txn1);
|
||||
oneOf(db).endTransaction(txn1);
|
||||
}});
|
||||
|
||||
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
||||
@@ -517,16 +640,20 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
Transaction txn1 = new Transaction(null, false);
|
||||
Transaction txn2 = new Transaction(null, false);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
context.checking(new Expectations() {{
|
||||
// Load the group
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getGroup(txn, groupId);
|
||||
will(returnValue(group));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
// Validate the message: valid
|
||||
oneOf(validator).validateMessage(message, group);
|
||||
will(returnValue(validResultWithDependencies));
|
||||
// Store the validation result
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn1));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn1));
|
||||
oneOf(db).addMessageDependencies(txn1, message,
|
||||
validResultWithDependencies.getDependencies());
|
||||
// Check for invalid dependencies
|
||||
@@ -541,8 +668,11 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
// Recursively invalidate dependents
|
||||
oneOf(db).getMessageDependents(txn1, messageId);
|
||||
will(returnValue(singletonMap(messageId2, UNKNOWN)));
|
||||
oneOf(db).commitTransaction(txn1);
|
||||
oneOf(db).endTransaction(txn1);
|
||||
// Invalidate dependent in a new transaction
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn2));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn2));
|
||||
oneOf(db).getMessageState(txn2, messageId2);
|
||||
will(returnValue(UNKNOWN));
|
||||
oneOf(db).setMessageState(txn2, messageId2, INVALID);
|
||||
@@ -550,6 +680,8 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
oneOf(db).deleteMessageMetadata(txn2, messageId2);
|
||||
oneOf(db).getMessageDependents(txn2, messageId2);
|
||||
will(returnValue(emptyMap()));
|
||||
oneOf(db).commitTransaction(txn2);
|
||||
oneOf(db).endTransaction(txn2);
|
||||
}});
|
||||
|
||||
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
||||
@@ -570,16 +702,20 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
Transaction txn5 = new Transaction(null, false);
|
||||
Transaction txn6 = new Transaction(null, false);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
context.checking(new Expectations() {{
|
||||
// Load the group
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getGroup(txn, groupId);
|
||||
will(returnValue(group));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
// Validate the message: invalid
|
||||
oneOf(validator).validateMessage(message, group);
|
||||
will(throwException(new InvalidMessageException()));
|
||||
// Invalidate the message
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn1));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn1));
|
||||
oneOf(db).getMessageState(txn1, messageId);
|
||||
will(returnValue(UNKNOWN));
|
||||
oneOf(db).setMessageState(txn1, messageId, INVALID);
|
||||
@@ -588,8 +724,11 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
// The message has two dependents: 1 and 2
|
||||
oneOf(db).getMessageDependents(txn1, messageId);
|
||||
will(returnValue(twoDependents));
|
||||
oneOf(db).commitTransaction(txn1);
|
||||
oneOf(db).endTransaction(txn1);
|
||||
// Invalidate message 1
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn2));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn2));
|
||||
oneOf(db).getMessageState(txn2, messageId1);
|
||||
will(returnValue(PENDING));
|
||||
oneOf(db).setMessageState(txn2, messageId1, INVALID);
|
||||
@@ -598,8 +737,11 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
// Message 1 has one dependent: 3
|
||||
oneOf(db).getMessageDependents(txn2, messageId1);
|
||||
will(returnValue(singletonMap(messageId3, PENDING)));
|
||||
oneOf(db).commitTransaction(txn2);
|
||||
oneOf(db).endTransaction(txn2);
|
||||
// Invalidate message 2
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn3));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn3));
|
||||
oneOf(db).getMessageState(txn3, messageId2);
|
||||
will(returnValue(PENDING));
|
||||
oneOf(db).setMessageState(txn3, messageId2, INVALID);
|
||||
@@ -608,8 +750,11 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
// Message 2 has one dependent: 3 (same dependent as 1)
|
||||
oneOf(db).getMessageDependents(txn3, messageId2);
|
||||
will(returnValue(singletonMap(messageId3, PENDING)));
|
||||
oneOf(db).commitTransaction(txn3);
|
||||
oneOf(db).endTransaction(txn3);
|
||||
// Invalidate message 3 (via 1)
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn4));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn4));
|
||||
oneOf(db).getMessageState(txn4, messageId3);
|
||||
will(returnValue(PENDING));
|
||||
oneOf(db).setMessageState(txn4, messageId3, INVALID);
|
||||
@@ -618,12 +763,18 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
// Message 3 has one dependent: 4
|
||||
oneOf(db).getMessageDependents(txn4, messageId3);
|
||||
will(returnValue(singletonMap(messageId4, PENDING)));
|
||||
oneOf(db).commitTransaction(txn4);
|
||||
oneOf(db).endTransaction(txn4);
|
||||
// Invalidate message 3 (again, via 2)
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn5));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn5));
|
||||
oneOf(db).getMessageState(txn5, messageId3);
|
||||
will(returnValue(INVALID)); // Already invalidated
|
||||
oneOf(db).commitTransaction(txn5);
|
||||
oneOf(db).endTransaction(txn5);
|
||||
// Invalidate message 4 (via 1 and 3)
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn6));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn6));
|
||||
oneOf(db).getMessageState(txn6, messageId4);
|
||||
will(returnValue(PENDING));
|
||||
oneOf(db).setMessageState(txn6, messageId4, INVALID);
|
||||
@@ -632,6 +783,8 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
// Message 4 has no dependents
|
||||
oneOf(db).getMessageDependents(txn6, messageId4);
|
||||
will(returnValue(emptyMap()));
|
||||
oneOf(db).commitTransaction(txn6);
|
||||
oneOf(db).endTransaction(txn6);
|
||||
}});
|
||||
|
||||
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
||||
@@ -657,16 +810,20 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
Transaction txn5 = new Transaction(null, false);
|
||||
Transaction txn6 = new Transaction(null, false);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
context.checking(new Expectations() {{
|
||||
// Load the group
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getGroup(txn, groupId);
|
||||
will(returnValue(group));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
// Validate the message: valid
|
||||
oneOf(validator).validateMessage(message, group);
|
||||
will(returnValue(validResult));
|
||||
// Store the validation result
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn1));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn1));
|
||||
oneOf(db).mergeMessageMetadata(txn1, messageId, metadata);
|
||||
// Deliver the message
|
||||
oneOf(hook).incomingMessage(txn1, message, metadata);
|
||||
@@ -675,8 +832,11 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
// The message has two pending dependents: 1 and 2
|
||||
oneOf(db).getMessageDependents(txn1, messageId);
|
||||
will(returnValue(twoDependents));
|
||||
oneOf(db).commitTransaction(txn1);
|
||||
oneOf(db).endTransaction(txn1);
|
||||
// Check whether message 1 is ready to be delivered
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn2));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn2));
|
||||
oneOf(db).getMessageState(txn2, messageId1);
|
||||
will(returnValue(PENDING));
|
||||
oneOf(db).getMessageDependencies(txn2, messageId1);
|
||||
@@ -695,8 +855,11 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
// Message 1 has one pending dependent: 3
|
||||
oneOf(db).getMessageDependents(txn2, messageId1);
|
||||
will(returnValue(singletonMap(messageId3, PENDING)));
|
||||
oneOf(db).commitTransaction(txn2);
|
||||
oneOf(db).endTransaction(txn2);
|
||||
// Check whether message 2 is ready to be delivered
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn3));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn3));
|
||||
oneOf(db).getMessageState(txn3, messageId2);
|
||||
will(returnValue(PENDING));
|
||||
oneOf(db).getMessageDependencies(txn3, messageId2);
|
||||
@@ -715,8 +878,11 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
// Message 2 has one pending dependent: 3 (same dependent as 1)
|
||||
oneOf(db).getMessageDependents(txn3, messageId2);
|
||||
will(returnValue(singletonMap(messageId3, PENDING)));
|
||||
oneOf(db).commitTransaction(txn3);
|
||||
oneOf(db).endTransaction(txn3);
|
||||
// Check whether message 3 is ready to be delivered (via 1)
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn4));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn4));
|
||||
oneOf(db).getMessageState(txn4, messageId3);
|
||||
will(returnValue(PENDING));
|
||||
oneOf(db).getMessageDependencies(txn4, messageId3);
|
||||
@@ -734,12 +900,18 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
// Message 3 has one pending dependent: 4
|
||||
oneOf(db).getMessageDependents(txn4, messageId3);
|
||||
will(returnValue(singletonMap(messageId4, PENDING)));
|
||||
oneOf(db).commitTransaction(txn4);
|
||||
oneOf(db).endTransaction(txn4);
|
||||
// Check whether message 3 is ready to be delivered (again, via 2)
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn5));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn5));
|
||||
oneOf(db).getMessageState(txn5, messageId3);
|
||||
will(returnValue(DELIVERED)); // Already delivered
|
||||
oneOf(db).commitTransaction(txn5);
|
||||
oneOf(db).endTransaction(txn5);
|
||||
// Check whether message 4 is ready to be delivered (via 1 and 3)
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn6));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn6));
|
||||
oneOf(db).getMessageState(txn6, messageId4);
|
||||
will(returnValue(PENDING));
|
||||
oneOf(db).getMessageDependencies(txn6, messageId4);
|
||||
@@ -758,6 +930,8 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
// Message 4 has no pending dependents
|
||||
oneOf(db).getMessageDependents(txn6, messageId4);
|
||||
will(returnValue(emptyMap()));
|
||||
oneOf(db).commitTransaction(txn6);
|
||||
oneOf(db).endTransaction(txn6);
|
||||
}});
|
||||
|
||||
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
||||
@@ -772,16 +946,20 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
Transaction txn1 = new Transaction(null, false);
|
||||
Transaction txn2 = new Transaction(null, false);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
context.checking(new Expectations() {{
|
||||
// Load the group
|
||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getGroup(txn, groupId);
|
||||
will(returnValue(group));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
// Validate the message: valid
|
||||
oneOf(validator).validateMessage(message, group);
|
||||
will(returnValue(validResult));
|
||||
// Store the validation result
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn1));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn1));
|
||||
oneOf(db).mergeMessageMetadata(txn1, messageId, metadata);
|
||||
// Deliver the message
|
||||
oneOf(hook).incomingMessage(txn1, message, metadata);
|
||||
@@ -790,12 +968,17 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
// Get any pending dependents
|
||||
oneOf(db).getMessageDependents(txn1, messageId);
|
||||
will(returnValue(singletonMap(messageId1, PENDING)));
|
||||
oneOf(db).commitTransaction(txn1);
|
||||
oneOf(db).endTransaction(txn1);
|
||||
// Check whether the pending dependent is ready to be delivered
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn2));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn2));
|
||||
oneOf(db).getMessageState(txn2, messageId1);
|
||||
will(returnValue(PENDING));
|
||||
oneOf(db).getMessageDependencies(txn2, messageId1);
|
||||
will(returnValue(twoDependencies));
|
||||
oneOf(db).commitTransaction(txn2);
|
||||
oneOf(db).endTransaction(txn2);
|
||||
}});
|
||||
|
||||
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.briarproject.bramble.test;
|
||||
|
||||
import org.briarproject.bramble.api.db.DbCallable;
|
||||
import org.briarproject.bramble.api.db.DbRunnable;
|
||||
import org.briarproject.bramble.api.db.NullableDbCallable;
|
||||
import org.briarproject.bramble.api.db.Transaction;
|
||||
import org.jmock.Expectations;
|
||||
|
||||
@@ -22,12 +21,4 @@ public class DbExpectations extends Expectations {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected <R, E extends Exception> NullableDbCallable<R, E> withNullableDbCallable(
|
||||
Transaction txn) {
|
||||
addParameterMatcher(any(NullableDbCallable.class));
|
||||
currentBuilder().setAction(
|
||||
new RunTransactionWithNullableResultAction(txn));
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
package org.briarproject.bramble.test;
|
||||
|
||||
import org.briarproject.bramble.api.db.NullableDbCallable;
|
||||
import org.briarproject.bramble.api.db.Transaction;
|
||||
import org.hamcrest.Description;
|
||||
import org.jmock.api.Action;
|
||||
import org.jmock.api.Invocation;
|
||||
|
||||
public class RunTransactionWithNullableResultAction implements Action {
|
||||
|
||||
private final Transaction txn;
|
||||
|
||||
public RunTransactionWithNullableResultAction(Transaction txn) {
|
||||
this.txn = txn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Invocation invocation) throws Throwable {
|
||||
NullableDbCallable task =
|
||||
(NullableDbCallable) invocation.getParameter(1);
|
||||
return task.call(txn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendText("runs a task inside a database transaction");
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,6 @@ import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory;
|
||||
import org.briarproject.bramble.api.transport.KeySetId;
|
||||
import org.briarproject.bramble.api.transport.StreamContext;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.briarproject.bramble.test.DbExpectations;
|
||||
import org.jmock.Expectations;
|
||||
import org.jmock.lib.concurrent.DeterministicExecutor;
|
||||
import org.junit.Before;
|
||||
@@ -36,7 +35,6 @@ import static org.briarproject.bramble.test.TestUtils.getSecretKey;
|
||||
import static org.briarproject.bramble.test.TestUtils.getTransportId;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
public class KeyManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
@@ -79,7 +77,7 @@ public class KeyManagerImplTest extends BrambleMockTestCase {
|
||||
singletonList(pluginFactory);
|
||||
int maxLatency = 1337;
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(pluginConfig).getSimplexFactories();
|
||||
will(returnValue(factories));
|
||||
oneOf(pluginFactory).getId();
|
||||
@@ -91,10 +89,13 @@ public class KeyManagerImplTest extends BrambleMockTestCase {
|
||||
.createTransportKeyManager(transportId, maxLatency);
|
||||
will(returnValue(transportKeyManager));
|
||||
oneOf(pluginConfig).getDuplexFactories();
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getContacts(txn);
|
||||
will(returnValue(contacts));
|
||||
oneOf(transportKeyManager).start(txn);
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
keyManager.startService();
|
||||
@@ -120,21 +121,25 @@ public class KeyManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test
|
||||
public void testGetStreamContextForInactiveContact() throws Exception {
|
||||
assertNull(keyManager.getStreamContext(inactiveContactId, transportId));
|
||||
assertEquals(null,
|
||||
keyManager.getStreamContext(inactiveContactId, transportId));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStreamContextForUnknownTransport() throws Exception {
|
||||
assertNull(keyManager.getStreamContext(contactId, unknownTransportId));
|
||||
assertEquals(null,
|
||||
keyManager.getStreamContext(contactId, unknownTransportId));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStreamContextForContact() throws Exception {
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transactionWithNullableResult(with(false),
|
||||
withNullableDbCallable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn));
|
||||
oneOf(transportKeyManager).getStreamContext(txn, contactId);
|
||||
will(returnValue(streamContext));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
assertEquals(streamContext,
|
||||
@@ -144,16 +149,19 @@ public class KeyManagerImplTest extends BrambleMockTestCase {
|
||||
@Test
|
||||
public void testGetStreamContextForTagAndUnknownTransport()
|
||||
throws Exception {
|
||||
assertNull(keyManager.getStreamContext(unknownTransportId, tag));
|
||||
assertEquals(null,
|
||||
keyManager.getStreamContext(unknownTransportId, tag));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStreamContextForTag() throws Exception {
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transactionWithNullableResult(with(false),
|
||||
withNullableDbCallable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn));
|
||||
oneOf(transportKeyManager).getStreamContext(txn, tag);
|
||||
will(returnValue(streamContext));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
assertEquals(streamContext,
|
||||
@@ -170,7 +178,7 @@ public class KeyManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
keyManager.eventOccurred(event);
|
||||
executor.runUntilIdle();
|
||||
assertNull(keyManager.getStreamContext(contactId, transportId));
|
||||
assertEquals(null, keyManager.getStreamContext(contactId, transportId));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -178,11 +186,13 @@ public class KeyManagerImplTest extends BrambleMockTestCase {
|
||||
ContactStatusChangedEvent event =
|
||||
new ContactStatusChangedEvent(inactiveContactId, true);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transactionWithNullableResult(with(false),
|
||||
withNullableDbCallable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn));
|
||||
oneOf(transportKeyManager).getStreamContext(txn, inactiveContactId);
|
||||
will(returnValue(streamContext));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
keyManager.eventOccurred(event);
|
||||
|
||||
@@ -14,7 +14,6 @@ import org.briarproject.bramble.api.transport.OutgoingKeys;
|
||||
import org.briarproject.bramble.api.transport.StreamContext;
|
||||
import org.briarproject.bramble.api.transport.TransportKeys;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.briarproject.bramble.test.DbExpectations;
|
||||
import org.briarproject.bramble.test.RunAction;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.hamcrest.Description;
|
||||
@@ -319,7 +318,7 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
Transaction txn1 = new Transaction(null, false);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
context.checking(new Expectations() {{
|
||||
// Get the current time (the start of rotation period 1000)
|
||||
oneOf(clock).currentTimeMillis();
|
||||
will(returnValue(rotationPeriodLength * 1000));
|
||||
@@ -343,7 +342,8 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
||||
oneOf(dbExecutor).execute(with(any(Runnable.class)));
|
||||
will(new RunAction());
|
||||
// Start a transaction for key rotation
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn1));
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn1));
|
||||
// Get the current time (the start of rotation period 1001)
|
||||
oneOf(clock).currentTimeMillis();
|
||||
will(returnValue(rotationPeriodLength * 1001));
|
||||
@@ -364,6 +364,9 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
||||
// Schedule key rotation at the start of the next rotation period
|
||||
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
||||
with(rotationPeriodLength), with(MILLISECONDS));
|
||||
// Commit the key rotation transaction
|
||||
oneOf(db).commitTransaction(txn1);
|
||||
oneOf(db).endTransaction(txn1);
|
||||
}});
|
||||
|
||||
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
|
||||
@@ -536,7 +539,7 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Invocation invocation) {
|
||||
public Object invoke(Invocation invocation) throws Throwable {
|
||||
byte[] tag = (byte[]) invocation.getParameter(0);
|
||||
random.nextBytes(tag);
|
||||
if (tags != null) tags.add(tag);
|
||||
|
||||
@@ -18,7 +18,6 @@ import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.api.versioning.ClientVersioningManager.ClientVersioningHook;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.briarproject.bramble.test.DbExpectations;
|
||||
import org.jmock.Expectations;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -64,7 +63,7 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
|
||||
private final long now = System.currentTimeMillis();
|
||||
private final Transaction txn = new Transaction(null, false);
|
||||
|
||||
private ClientVersioningManagerImpl createInstance() {
|
||||
private ClientVersioningManagerImpl createInstance() throws Exception {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(contactGroupFactory).createLocalGroup(CLIENT_ID,
|
||||
MAJOR_VERSION);
|
||||
@@ -163,8 +162,9 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
|
||||
BdfList localUpdateBody = BdfList.of(BdfList.of(
|
||||
BdfList.of(clientId.getString(), 123, 234, false)), 1L);
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn));
|
||||
// No client versions have been stored yet
|
||||
oneOf(db).getMessageIds(txn, localGroup.getId());
|
||||
will(returnValue(emptyList()));
|
||||
@@ -190,6 +190,8 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
|
||||
oneOf(clientHelper).getMessageAsList(txn, localUpdateId);
|
||||
will(returnValue(localUpdateBody));
|
||||
// Latest local update is up-to-date, no visibilities have changed
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
ClientVersioningManagerImpl c = createInstance();
|
||||
@@ -204,14 +206,17 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
|
||||
BdfList localVersionsBody =
|
||||
BdfList.of(BdfList.of(clientId.getString(), 123, 234));
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn));
|
||||
// Load the old client versions
|
||||
oneOf(db).getMessageIds(txn, localGroup.getId());
|
||||
will(returnValue(singletonList(localVersionsId)));
|
||||
oneOf(clientHelper).getMessageAsList(txn, localVersionsId);
|
||||
will(returnValue(localVersionsBody));
|
||||
// Client versions are up-to-date
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
ClientVersioningManagerImpl c = createInstance();
|
||||
@@ -246,8 +251,9 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
|
||||
new BdfEntry(MSG_KEY_UPDATE_VERSION, 2L),
|
||||
new BdfEntry(MSG_KEY_LOCAL, true));
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn));
|
||||
// Load the old client versions
|
||||
oneOf(db).getMessageIds(txn, localGroup.getId());
|
||||
will(returnValue(singletonList(oldLocalVersionsId)));
|
||||
@@ -289,6 +295,8 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
|
||||
oneOf(clientHelper).addLocalMessage(txn, newLocalUpdate,
|
||||
newLocalUpdateMeta, true);
|
||||
// No visibilities have changed
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
ClientVersioningManagerImpl c = createInstance();
|
||||
@@ -342,8 +350,9 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
|
||||
new BdfEntry(MSG_KEY_UPDATE_VERSION, 2L),
|
||||
new BdfEntry(MSG_KEY_LOCAL, true));
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn));
|
||||
// Load the old client versions
|
||||
oneOf(db).getMessageIds(txn, localGroup.getId());
|
||||
will(returnValue(singletonList(oldLocalVersionsId)));
|
||||
@@ -388,6 +397,8 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
|
||||
newLocalUpdateMeta, true);
|
||||
// The client's visibility has changed
|
||||
oneOf(hook).onClientVisibilityChanging(txn, contact, visibility);
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
ClientVersioningManagerImpl c = createInstance();
|
||||
|
||||
@@ -1,20 +1,12 @@
|
||||
dependencyVerification {
|
||||
verify = [
|
||||
'cglib:cglib:3.2.0:cglib-3.2.0.jar:adb13bab79712ad6bdf1bd59f2a3918018a8016e722e8a357065afb9e6690861',
|
||||
'com.google.code.findbugs:jsr305:1.3.9:jsr305-1.3.9.jar:905721a0eea90a81534abb7ee6ef4ea2e5e645fa1def0a5cd88402df1b46c9ed',
|
||||
'com.google.dagger:dagger-compiler:2.19:dagger-compiler-2.19.jar:27a4b202a2de908182edb261f8c0a264e08e5e4733d7514bc7fbf0d31da5c0fc',
|
||||
'com.google.dagger:dagger-producers:2.19:dagger-producers-2.19.jar:a17663abe0fc38b676026950907d4c5f5e2bf338375415861eaff6e3bdb0b768',
|
||||
'com.google.dagger:dagger-spi:2.19:dagger-spi-2.19.jar:e7a6379d82c841f6aac2866948ad1eed716528707814602842a8d844ce04e2e1',
|
||||
'com.google.dagger:dagger:2.19:dagger-2.19.jar:514b6f1e0727c6572e1d65cb27e4ae668b7aeaeb93a29515182965265b609939',
|
||||
'com.google.errorprone:error_prone_annotations:2.1.3:error_prone_annotations-2.1.3.jar:03d0329547c13da9e17c634d1049ea2ead093925e290567e1a364fd6b1fc7ff8',
|
||||
'com.google.errorprone:javac-shaded:9-dev-r4023-3:javac-shaded-9-dev-r4023-3.jar:65bfccf60986c47fbc17c9ebab0be626afc41741e0a6ec7109e0768817a36f30',
|
||||
'com.google.googlejavaformat:google-java-format:1.5:google-java-format-1.5.jar:aa19ad7850fb85178aa22f2fddb163b84d6ce4d0035872f30d4408195ca1144e',
|
||||
'com.google.guava: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.dagger:dagger-compiler:2.0.2:dagger-compiler-2.0.2.jar:b74bc9de063dd4c6400b232231f2ef5056145b8fbecbf5382012007dd1c071b3',
|
||||
'com.google.dagger:dagger-producers:2.0-beta:dagger-producers-2.0-beta.jar:99ec15e8a0507ba569e7655bc1165ee5e5ca5aa914b3c8f7e2c2458f724edd6b',
|
||||
'com.google.dagger:dagger:2.0.2:dagger-2.0.2.jar:84c0282ed8be73a29e0475d639da030b55dee72369e58dd35ae7d4fe6243dcf9',
|
||||
'com.google.guava:guava:18.0:guava-18.0.jar:d664fbfc03d2e5ce9cab2a44fb01f1d0bf9dfebeccc1a473b1f9ea31f79f6f99',
|
||||
'com.h2database:h2:1.4.192:h2-1.4.192.jar:225b22e9857235c46c93861410b60b8c81c10dc8985f4faf188985ba5445126c',
|
||||
'com.madgag.spongycastle:core:1.58.0.0:core-1.58.0.0.jar:199617dd5698c5a9312b898c0a4cec7ce9dd8649d07f65d91629f58229d72728',
|
||||
'com.squareup:javapoet:1.11.1:javapoet-1.11.1.jar:9cbf2107be499ec6e95afd36b58e3ca122a24166cdd375732e51267d64058e90',
|
||||
'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f',
|
||||
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||
'junit:junit:4.12:junit-4.12.jar:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a',
|
||||
'net.i2p.crypto:eddsa:0.2.0:eddsa-0.2.0.jar:a7cb1b85c16e2f0730b9204106929a1d9aaae1df728adc7041a8b8b605692140',
|
||||
@@ -23,9 +15,7 @@ dependencyVerification {
|
||||
'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8',
|
||||
'org.bitlet:weupnp:0.1.4:weupnp-0.1.4.jar:88df7e6504929d00bdb832863761385c68ab92af945b04f0770b126270a444fb',
|
||||
'org.briarproject:jtorctl:0.3:jtorctl-0.3.jar:f2939238a097898998432effe93b0334d97a787972ab3a91a8973a1d309fc864',
|
||||
'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d',
|
||||
'org.codehaus.mojo.signature:java16:1.1:java16-1.1.signature:53799223a2c98dba2d0add810bed76315460df285c69e4f397ae6098f87dd619',
|
||||
'org.codehaus.mojo:animal-sniffer-annotations:1.14:animal-sniffer-annotations-1.14.jar:2068320bd6bad744c3673ab048f67e30bef8f518996fa380033556600669905d',
|
||||
'org.codehaus.mojo:animal-sniffer-ant-tasks:1.16:animal-sniffer-ant-tasks-1.16.jar:890040976fbe2d584619a6a61b1fd2e925b3b5eb342a85eb2762c467c0d64e90',
|
||||
'org.codehaus.mojo:animal-sniffer:1.16:animal-sniffer-1.16.jar:72be8bcc226ba43b937c722a08a07852bfa1b11400089265d5df0ee7b38b1d52',
|
||||
'org.hamcrest:hamcrest-core:1.3:hamcrest-core-1.3.jar:66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9',
|
||||
|
||||
@@ -2,10 +2,10 @@ apply plugin: 'java-library'
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
|
||||
apply plugin: 'net.ltgt.apt'
|
||||
apply plugin: 'idea'
|
||||
apply plugin: 'witness'
|
||||
apply from: 'witness.gradle'
|
||||
apply from: '../dagger.gradle'
|
||||
|
||||
configurations {
|
||||
tor
|
||||
@@ -17,9 +17,8 @@ dependencies {
|
||||
implementation 'net.java.dev.jna:jna:4.5.2'
|
||||
implementation 'net.java.dev.jna:jna-platform:4.5.2'
|
||||
tor 'org.briarproject:tor:0.3.4.8@zip'
|
||||
tor 'org.briarproject:obfs4proxy:0.0.7@zip'
|
||||
|
||||
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-core', configuration: 'testOutput')
|
||||
@@ -27,35 +26,19 @@ dependencies {
|
||||
testImplementation "org.jmock:jmock:2.8.2"
|
||||
testImplementation "org.jmock:jmock-junit4:2.8.2"
|
||||
testImplementation "org.jmock:jmock-legacy:2.8.2"
|
||||
testImplementation "org.hamcrest:hamcrest-library:1.3"
|
||||
testImplementation "org.hamcrest:hamcrest-core:1.3"
|
||||
|
||||
testAnnotationProcessor 'com.google.dagger:dagger-compiler:2.19'
|
||||
testApt 'com.google.dagger:dagger-compiler:2.0.2'
|
||||
}
|
||||
|
||||
def torBinariesDir = 'src/main/resources'
|
||||
|
||||
task cleanTorBinaries {
|
||||
doLast {
|
||||
delete fileTree(torBinariesDir) { include '*.zip' }
|
||||
project.afterEvaluate {
|
||||
copy {
|
||||
from configurations.tor.collect { zipTree(it) }
|
||||
into 'src/main/resources'
|
||||
}
|
||||
}
|
||||
|
||||
clean.dependsOn cleanTorBinaries
|
||||
|
||||
task unpackTorBinaries {
|
||||
doLast {
|
||||
copy {
|
||||
from configurations.tor.collect { zipTree(it) }
|
||||
into torBinariesDir
|
||||
}
|
||||
}
|
||||
dependsOn cleanTorBinaries
|
||||
}
|
||||
|
||||
processResources {
|
||||
inputs.dir torBinariesDir
|
||||
dependsOn unpackTorBinaries
|
||||
}
|
||||
|
||||
tasks.withType(Test) {
|
||||
systemProperty 'java.library.path', 'libs'
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package org.briarproject.bramble.network;
|
||||
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.lifecycle.Service;
|
||||
import org.briarproject.bramble.api.network.NetworkManager;
|
||||
import org.briarproject.bramble.api.network.NetworkStatus;
|
||||
import org.briarproject.bramble.api.network.event.NetworkStatusEvent;
|
||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||
|
||||
@@ -20,13 +23,25 @@ import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
class JavaNetworkManager implements NetworkManager {
|
||||
class JavaNetworkManager implements NetworkManager, Service {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(JavaNetworkManager.class.getName());
|
||||
|
||||
private final EventBus eventBus;
|
||||
|
||||
@Inject
|
||||
JavaNetworkManager() {
|
||||
JavaNetworkManager(EventBus eventBus) {
|
||||
this.eventBus = eventBus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startService() {
|
||||
eventBus.broadcast(new NetworkStatusEvent(getNetworkStatus()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopService() {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.briarproject.bramble.network;
|
||||
|
||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.bramble.api.network.NetworkManager;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
@@ -12,7 +13,9 @@ public class JavaNetworkModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
NetworkManager provideNetworkManager(JavaNetworkManager networkManager) {
|
||||
NetworkManager provideNetworkManager(LifecycleManager lifecycleManager,
|
||||
JavaNetworkManager networkManager) {
|
||||
lifecycleManager.registerService(networkManager);
|
||||
return networkManager;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,10 +10,6 @@ import org.briarproject.bramble.api.system.Clock;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.CharacterCodingException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
@@ -26,7 +22,6 @@ import javax.annotation.Nullable;
|
||||
import jssc.SerialPortEvent;
|
||||
import jssc.SerialPortEventListener;
|
||||
|
||||
import static java.nio.charset.CodingErrorAction.IGNORE;
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
@@ -40,8 +35,6 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(ModemImpl.class.getName());
|
||||
|
||||
private static final Charset US_ASCII = Charset.forName("US-ASCII");
|
||||
private static final int MAX_LINE_LENGTH = 256;
|
||||
private static final int[] BAUD_RATES = {
|
||||
256000, 128000, 115200, 57600, 38400, 19200, 14400, 9600, 4800, 1200
|
||||
@@ -113,7 +106,7 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
|
||||
throw e;
|
||||
}
|
||||
// Wait for the event thread to receive "OK"
|
||||
boolean success;
|
||||
boolean success = false;
|
||||
try {
|
||||
lock.lock();
|
||||
try {
|
||||
@@ -360,7 +353,8 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
|
||||
for (int i = 0; i < b.length; i++) {
|
||||
line[lineLen] = b[i];
|
||||
if (b[i] == '\n') {
|
||||
String s = toAscii(line, lineLen).trim();
|
||||
// FIXME: Use CharsetDecoder to catch invalid ASCII
|
||||
String s = new String(line, 0, lineLen, "US-ASCII").trim();
|
||||
lineLen = 0;
|
||||
if (LOG.isLoggable(INFO)) LOG.info("Modem status: " + s);
|
||||
if (s.startsWith("CONNECT")) {
|
||||
@@ -442,7 +436,7 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
|
||||
throw e;
|
||||
}
|
||||
// Wait for the event thread to receive "CONNECT"
|
||||
boolean success;
|
||||
boolean success = false;
|
||||
try {
|
||||
lock.lock();
|
||||
try {
|
||||
@@ -467,16 +461,4 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
|
||||
stateChange.release();
|
||||
}
|
||||
}
|
||||
|
||||
private String toAscii(byte[] bytes, int len) {
|
||||
CharsetDecoder decoder = US_ASCII.newDecoder();
|
||||
decoder.onMalformedInput(IGNORE);
|
||||
decoder.onUnmappableCharacter(IGNORE);
|
||||
ByteBuffer buffer = ByteBuffer.wrap(bytes, 0, len);
|
||||
try {
|
||||
return decoder.decode(buffer).toString();
|
||||
} catch (CharacterCodingException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.briarproject.bramble.plugin.tor;
|
||||
|
||||
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||
import org.briarproject.bramble.api.network.NetworkManager;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.plugin.Backoff;
|
||||
@@ -24,14 +23,12 @@ class LinuxTorPlugin extends TorPlugin {
|
||||
LinuxTorPlugin(Executor ioExecutor, NetworkManager networkManager,
|
||||
LocationUtils locationUtils, SocketFactory torSocketFactory,
|
||||
Clock clock, ResourceProvider resourceProvider,
|
||||
CircumventionProvider circumventionProvider,
|
||||
BatteryManager batteryManager, Backoff backoff,
|
||||
CircumventionProvider circumventionProvider, Backoff backoff,
|
||||
DuplexPluginCallback callback, String architecture, int maxLatency,
|
||||
int maxIdleTime, File torDirectory) {
|
||||
super(ioExecutor, networkManager, locationUtils, torSocketFactory,
|
||||
clock, resourceProvider, circumventionProvider, batteryManager,
|
||||
backoff, callback, architecture, maxLatency, maxIdleTime,
|
||||
torDirectory);
|
||||
clock, resourceProvider, circumventionProvider, backoff,
|
||||
callback, architecture, maxLatency, maxIdleTime, torDirectory);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.briarproject.bramble.plugin.tor;
|
||||
|
||||
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.network.NetworkManager;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
@@ -45,7 +44,6 @@ public class LinuxTorPluginFactory implements DuplexPluginFactory {
|
||||
private final BackoffFactory backoffFactory;
|
||||
private final ResourceProvider resourceProvider;
|
||||
private final CircumventionProvider circumventionProvider;
|
||||
private final BatteryManager batteryManager;
|
||||
private final Clock clock;
|
||||
private final File torDirectory;
|
||||
|
||||
@@ -53,8 +51,8 @@ public class LinuxTorPluginFactory implements DuplexPluginFactory {
|
||||
NetworkManager networkManager, LocationUtils locationUtils,
|
||||
EventBus eventBus, SocketFactory torSocketFactory,
|
||||
BackoffFactory backoffFactory, ResourceProvider resourceProvider,
|
||||
CircumventionProvider circumventionProvider,
|
||||
BatteryManager batteryManager, Clock clock, File torDirectory) {
|
||||
CircumventionProvider circumventionProvider, Clock clock,
|
||||
File torDirectory) {
|
||||
this.ioExecutor = ioExecutor;
|
||||
this.networkManager = networkManager;
|
||||
this.locationUtils = locationUtils;
|
||||
@@ -63,7 +61,6 @@ public class LinuxTorPluginFactory implements DuplexPluginFactory {
|
||||
this.backoffFactory = backoffFactory;
|
||||
this.resourceProvider = resourceProvider;
|
||||
this.circumventionProvider = circumventionProvider;
|
||||
this.batteryManager = batteryManager;
|
||||
this.clock = clock;
|
||||
this.torDirectory = torDirectory;
|
||||
}
|
||||
@@ -95,10 +92,11 @@ public class LinuxTorPluginFactory implements DuplexPluginFactory {
|
||||
|
||||
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
|
||||
MAX_POLLING_INTERVAL, BACKOFF_BASE);
|
||||
LinuxTorPlugin plugin = new LinuxTorPlugin(ioExecutor, networkManager,
|
||||
locationUtils, torSocketFactory, clock, resourceProvider,
|
||||
circumventionProvider, batteryManager, backoff, callback,
|
||||
architecture, MAX_LATENCY, MAX_IDLE_TIME, torDirectory);
|
||||
LinuxTorPlugin plugin =
|
||||
new LinuxTorPlugin(ioExecutor, networkManager, locationUtils,
|
||||
torSocketFactory, clock, resourceProvider,
|
||||
circumventionProvider, backoff, callback, architecture,
|
||||
MAX_LATENCY, MAX_IDLE_TIME, torDirectory);
|
||||
eventBus.addListener(plugin);
|
||||
return plugin;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.briarproject.bramble.plugin.tor;
|
||||
|
||||
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.network.NetworkManager;
|
||||
import org.briarproject.bramble.api.plugin.BackoffFactory;
|
||||
@@ -59,8 +58,6 @@ public class BridgeTest extends BrambleTestCase {
|
||||
@Inject
|
||||
CircumventionProvider circumventionProvider;
|
||||
@Inject
|
||||
BatteryManager batteryManager;
|
||||
@Inject
|
||||
EventBus eventBus;
|
||||
@Inject
|
||||
BackoffFactory backoffFactory;
|
||||
@@ -110,8 +107,7 @@ public class BridgeTest extends BrambleTestCase {
|
||||
};
|
||||
factory = new LinuxTorPluginFactory(ioExecutor, networkManager,
|
||||
locationUtils, eventBus, torSocketFactory, backoffFactory,
|
||||
resourceProvider, bridgeProvider, batteryManager, clock,
|
||||
torDir);
|
||||
resourceProvider, bridgeProvider, clock, torDir);
|
||||
}
|
||||
|
||||
@After
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.briarproject.bramble.test;
|
||||
|
||||
import org.briarproject.bramble.BrambleJavaModule;
|
||||
import org.briarproject.bramble.battery.DefaultBatteryManagerModule;
|
||||
import org.briarproject.bramble.event.EventModule;
|
||||
import org.briarproject.bramble.plugin.PluginModule;
|
||||
import org.briarproject.bramble.plugin.tor.BridgeTest;
|
||||
@@ -16,7 +15,6 @@ import dagger.Component;
|
||||
@Component(modules = {
|
||||
BrambleJavaModule.class,
|
||||
TestLifecycleModule.class,
|
||||
DefaultBatteryManagerModule.class,
|
||||
PluginModule.class, // needed for BackoffFactory
|
||||
EventModule.class,
|
||||
SystemModule.class,
|
||||
|
||||
@@ -1,18 +1,10 @@
|
||||
dependencyVerification {
|
||||
verify = [
|
||||
'cglib:cglib:3.2.0:cglib-3.2.0.jar:adb13bab79712ad6bdf1bd59f2a3918018a8016e722e8a357065afb9e6690861',
|
||||
'com.google.code.findbugs:jsr305:1.3.9:jsr305-1.3.9.jar:905721a0eea90a81534abb7ee6ef4ea2e5e645fa1def0a5cd88402df1b46c9ed',
|
||||
'com.google.dagger:dagger-compiler:2.19:dagger-compiler-2.19.jar:27a4b202a2de908182edb261f8c0a264e08e5e4733d7514bc7fbf0d31da5c0fc',
|
||||
'com.google.dagger:dagger-producers:2.19:dagger-producers-2.19.jar:a17663abe0fc38b676026950907d4c5f5e2bf338375415861eaff6e3bdb0b768',
|
||||
'com.google.dagger:dagger-spi:2.19:dagger-spi-2.19.jar:e7a6379d82c841f6aac2866948ad1eed716528707814602842a8d844ce04e2e1',
|
||||
'com.google.dagger:dagger:2.19:dagger-2.19.jar:514b6f1e0727c6572e1d65cb27e4ae668b7aeaeb93a29515182965265b609939',
|
||||
'com.google.errorprone:error_prone_annotations:2.1.3:error_prone_annotations-2.1.3.jar:03d0329547c13da9e17c634d1049ea2ead093925e290567e1a364fd6b1fc7ff8',
|
||||
'com.google.errorprone:javac-shaded:9-dev-r4023-3:javac-shaded-9-dev-r4023-3.jar:65bfccf60986c47fbc17c9ebab0be626afc41741e0a6ec7109e0768817a36f30',
|
||||
'com.google.googlejavaformat:google-java-format:1.5:google-java-format-1.5.jar:aa19ad7850fb85178aa22f2fddb163b84d6ce4d0035872f30d4408195ca1144e',
|
||||
'com.google.guava:guava:25.0-jre:guava-25.0-jre.jar:3fd4341776428c7e0e5c18a7c10de129475b69ab9d30aeafbb5c277bb6074fa9',
|
||||
'com.google.j2objc:j2objc-annotations:1.1:j2objc-annotations-1.1.jar:40ceb7157feb263949e0f503fe5f71689333a621021aa20ce0d0acee3badaa0f',
|
||||
'com.squareup:javapoet:1.11.1:javapoet-1.11.1.jar:9cbf2107be499ec6e95afd36b58e3ca122a24166cdd375732e51267d64058e90',
|
||||
'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f',
|
||||
'com.google.dagger:dagger-compiler:2.0.2:dagger-compiler-2.0.2.jar:b74bc9de063dd4c6400b232231f2ef5056145b8fbecbf5382012007dd1c071b3',
|
||||
'com.google.dagger:dagger-producers:2.0-beta:dagger-producers-2.0-beta.jar:99ec15e8a0507ba569e7655bc1165ee5e5ca5aa914b3c8f7e2c2458f724edd6b',
|
||||
'com.google.dagger:dagger:2.0.2:dagger-2.0.2.jar:84c0282ed8be73a29e0475d639da030b55dee72369e58dd35ae7d4fe6243dcf9',
|
||||
'com.google.guava:guava:18.0:guava-18.0.jar:d664fbfc03d2e5ce9cab2a44fb01f1d0bf9dfebeccc1a473b1f9ea31f79f6f99',
|
||||
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||
'junit:junit:4.12:junit-4.12.jar:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a',
|
||||
'net.java.dev.jna:jna-platform:4.5.2:jna-platform-4.5.2.jar:f1d00c167d8921c6e23c626ef9f1c3ae0be473c95c68ffa012bc7ae55a87e2d6',
|
||||
@@ -20,10 +12,7 @@ dependencyVerification {
|
||||
'org.apache.ant:ant-launcher:1.9.4:ant-launcher-1.9.4.jar:7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d',
|
||||
'org.apache.ant:ant:1.9.4:ant-1.9.4.jar:649ae0730251de07b8913f49286d46bba7b92d47c5f332610aa426c4f02161d8',
|
||||
'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8',
|
||||
'org.briarproject:obfs4proxy:0.0.7:obfs4proxy-0.0.7.zip:5b2f693262ce43a7e130f7cc7d5d1617925330640a2eb6d71085e95df8ee0642',
|
||||
'org.briarproject:tor:0.3.4.8:tor-0.3.4.8.zip:bc0158c34002f471a4fe14a6a481816c918eb520a220bb027f64be902beb757f',
|
||||
'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d',
|
||||
'org.codehaus.mojo:animal-sniffer-annotations:1.14:animal-sniffer-annotations-1.14.jar:2068320bd6bad744c3673ab048f67e30bef8f518996fa380033556600669905d',
|
||||
'org.hamcrest:hamcrest-core:1.3:hamcrest-core-1.3.jar:66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9',
|
||||
'org.hamcrest:hamcrest-library:1.3:hamcrest-library-1.3.jar:711d64522f9ec410983bd310934296da134be4254a125080a0416ec178dfad1c',
|
||||
'org.jmock:jmock-junit4:2.8.2:jmock-junit4-2.8.2.jar:f7ee4df4f7bd7b7f1cafad3b99eb74d579f109d5992ff625347352edb55e674c',
|
||||
|
||||
@@ -22,8 +22,8 @@ android {
|
||||
defaultConfig {
|
||||
minSdkVersion 15
|
||||
targetSdkVersion 26
|
||||
versionCode 10105
|
||||
versionName "1.1.5"
|
||||
versionCode 10103
|
||||
versionName "1.1.3"
|
||||
applicationId "org.briarproject.briar.android"
|
||||
buildConfigField "String", "GitHash",
|
||||
"\"${getStdout(['git', 'rev-parse', '--short=7', 'HEAD'], 'No commit hash')}\""
|
||||
@@ -118,25 +118,27 @@ dependencies {
|
||||
implementation 'uk.co.samuelwall:material-tap-target-prompt:2.12.4'
|
||||
implementation 'com.vanniktech:emoji-google:0.5.1'
|
||||
|
||||
annotationProcessor 'com.google.dagger:dagger-compiler:2.19'
|
||||
annotationProcessor 'com.google.dagger:dagger-compiler:2.0.2'
|
||||
|
||||
compileOnly 'javax.annotation:jsr250-api:1.0'
|
||||
|
||||
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
|
||||
testImplementation project(path: ':bramble-core', configuration: 'testOutput')
|
||||
testImplementation 'org.robolectric:robolectric:4.0.1'
|
||||
testImplementation 'org.robolectric:robolectric:3.8'
|
||||
testImplementation 'org.robolectric:shadows-support-v4:3.3.2'
|
||||
testImplementation 'org.mockito:mockito-core:2.13.0'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
testImplementation "org.jmock:jmock:2.8.2"
|
||||
testImplementation "org.jmock:jmock-junit4:2.8.2"
|
||||
testImplementation "org.jmock:jmock-legacy:2.8.2"
|
||||
testImplementation "org.hamcrest:hamcrest-library:1.3"
|
||||
testImplementation "org.hamcrest:hamcrest-core:1.3"
|
||||
|
||||
def espressoVersion = '3.0.2'
|
||||
androidTestImplementation "com.android.support.test.espresso:espresso-core:$espressoVersion"
|
||||
androidTestImplementation "com.android.support.test.espresso:espresso-contrib:$espressoVersion"
|
||||
androidTestImplementation "com.android.support.test.espresso:espresso-intents:$espressoVersion"
|
||||
androidTestAnnotationProcessor "com.google.dagger:dagger-compiler:2.19"
|
||||
androidTestAnnotationProcessor "com.google.dagger:dagger-compiler:2.0.2"
|
||||
androidTestCompileOnly 'javax.annotation:jsr250-api:1.0'
|
||||
androidTestImplementation 'junit:junit:4.12'
|
||||
androidTestScreenshotImplementation "tools.fastlane:screengrab:1.2.0"
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.conversation.ConversationActivity"
|
||||
android:name="org.briarproject.briar.android.contact.ConversationActivity"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/BriarTheme.NoActionBar"
|
||||
android:parentActivityName="org.briarproject.briar.android.navdrawer.NavDrawerActivity"
|
||||
@@ -190,10 +190,10 @@
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.sharing.BlogInvitationActivity"
|
||||
android:label="@string/blogs_sharing_invitations_title"
|
||||
android:parentActivityName="org.briarproject.briar.android.conversation.ConversationActivity">
|
||||
android:parentActivityName="org.briarproject.briar.android.contact.ConversationActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.conversation.ConversationActivity"
|
||||
android:value="org.briarproject.briar.android.contact.ConversationActivity"
|
||||
/>
|
||||
</activity>
|
||||
|
||||
@@ -327,11 +327,11 @@
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.introduction.IntroductionActivity"
|
||||
android:label="@string/introduction_activity_title"
|
||||
android:parentActivityName="org.briarproject.briar.android.conversation.ConversationActivity"
|
||||
android:parentActivityName="org.briarproject.briar.android.contact.ConversationActivity"
|
||||
android:windowSoftInputMode="stateHidden|adjustResize">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.conversation.ConversationActivity"
|
||||
android:value="org.briarproject.briar.android.contact.ConversationActivity"
|
||||
/>
|
||||
</activity>
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package org.briarproject.briar.android;
|
||||
|
||||
import android.arch.lifecycle.ViewModelProvider;
|
||||
|
||||
import org.briarproject.bramble.BrambleAndroidModule;
|
||||
import org.briarproject.bramble.BrambleCoreEagerSingletons;
|
||||
import org.briarproject.bramble.BrambleCoreModule;
|
||||
@@ -28,6 +26,7 @@ import org.briarproject.bramble.api.system.LocationUtils;
|
||||
import org.briarproject.bramble.plugin.tor.CircumventionProvider;
|
||||
import org.briarproject.briar.BriarCoreEagerSingletons;
|
||||
import org.briarproject.briar.BriarCoreModule;
|
||||
import org.briarproject.briar.android.contact.ConversationViewModel;
|
||||
import org.briarproject.briar.android.login.SignInReminderReceiver;
|
||||
import org.briarproject.briar.android.reporting.BriarReportSender;
|
||||
import org.briarproject.briar.android.view.TextInputView;
|
||||
@@ -43,7 +42,7 @@ import org.briarproject.briar.api.feed.FeedManager;
|
||||
import org.briarproject.briar.api.forum.ForumManager;
|
||||
import org.briarproject.briar.api.forum.ForumSharingManager;
|
||||
import org.briarproject.briar.api.introduction.IntroductionManager;
|
||||
import org.briarproject.briar.api.conversation.ConversationManager;
|
||||
import org.briarproject.briar.api.messaging.ConversationManager;
|
||||
import org.briarproject.briar.api.messaging.MessagingManager;
|
||||
import org.briarproject.briar.api.messaging.PrivateMessageFactory;
|
||||
import org.briarproject.briar.api.privategroup.GroupMessageFactory;
|
||||
@@ -156,8 +155,6 @@ public interface AndroidComponent
|
||||
|
||||
CircumventionProvider circumventionProvider();
|
||||
|
||||
ViewModelProvider.Factory viewModelFactory();
|
||||
|
||||
void inject(SignInReminderReceiver briarService);
|
||||
|
||||
void inject(BriarService briarService);
|
||||
@@ -168,6 +165,8 @@ public interface AndroidComponent
|
||||
|
||||
void inject(TextInputView textInputView);
|
||||
|
||||
void inject(ConversationViewModel conversationViewModel);
|
||||
|
||||
// Eager singleton load
|
||||
void inject(AppModule.EagerSingletons init);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.briarproject.bramble.api.system.AndroidExecutor;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.conversation.ConversationActivity;
|
||||
import org.briarproject.briar.android.contact.ConversationActivity;
|
||||
import org.briarproject.briar.android.forum.ForumActivity;
|
||||
import org.briarproject.briar.android.login.SignInReminderReceiver;
|
||||
import org.briarproject.briar.android.navdrawer.NavDrawerActivity;
|
||||
@@ -40,9 +40,9 @@ import org.briarproject.briar.android.splash.SplashScreenActivity;
|
||||
import org.briarproject.briar.android.util.BriarNotificationBuilder;
|
||||
import org.briarproject.briar.api.android.AndroidNotificationManager;
|
||||
import org.briarproject.briar.api.blog.event.BlogPostAddedEvent;
|
||||
import org.briarproject.briar.api.conversation.event.ConversationMessageReceivedEvent;
|
||||
import org.briarproject.briar.api.forum.event.ForumPostReceivedEvent;
|
||||
import org.briarproject.briar.api.introduction.event.IntroductionSucceededEvent;
|
||||
import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent;
|
||||
import org.briarproject.briar.api.privategroup.event.GroupMessageAddedEvent;
|
||||
|
||||
import java.util.Set;
|
||||
@@ -72,7 +72,7 @@ import static android.support.v4.app.NotificationCompat.PRIORITY_MIN;
|
||||
import static android.support.v4.app.NotificationCompat.VISIBILITY_SECRET;
|
||||
import static android.support.v4.content.ContextCompat.getColor;
|
||||
import static org.briarproject.briar.android.activity.BriarActivity.GROUP_ID;
|
||||
import static org.briarproject.briar.android.conversation.ConversationActivity.CONTACT_ID;
|
||||
import static org.briarproject.briar.android.contact.ConversationActivity.CONTACT_ID;
|
||||
import static org.briarproject.briar.android.navdrawer.NavDrawerActivity.INTENT_BLOGS;
|
||||
import static org.briarproject.briar.android.navdrawer.NavDrawerActivity.INTENT_CONTACTS;
|
||||
import static org.briarproject.briar.android.navdrawer.NavDrawerActivity.INTENT_FORUMS;
|
||||
@@ -219,9 +219,8 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
SettingsUpdatedEvent s = (SettingsUpdatedEvent) e;
|
||||
if (s.getNamespace().equals(SETTINGS_NAMESPACE))
|
||||
settings = s.getSettings();
|
||||
} else if (e instanceof ConversationMessageReceivedEvent) {
|
||||
ConversationMessageReceivedEvent p =
|
||||
(ConversationMessageReceivedEvent) e;
|
||||
} else if (e instanceof PrivateMessageReceivedEvent) {
|
||||
PrivateMessageReceivedEvent p = (PrivateMessageReceivedEvent) e;
|
||||
showContactNotification(p.getContactId());
|
||||
} else if (e instanceof GroupMessageAddedEvent) {
|
||||
GroupMessageAddedEvent g = (GroupMessageAddedEvent) e;
|
||||
|
||||
@@ -7,7 +7,6 @@ import android.os.StrictMode;
|
||||
|
||||
import com.vanniktech.emoji.RecentEmoji;
|
||||
|
||||
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
import org.briarproject.bramble.api.db.DatabaseConfig;
|
||||
@@ -33,7 +32,6 @@ import org.briarproject.bramble.plugin.tor.CircumventionProvider;
|
||||
import org.briarproject.bramble.util.AndroidUtils;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.briarproject.briar.android.account.LockManagerImpl;
|
||||
import org.briarproject.briar.android.viewmodel.ViewModelModule;
|
||||
import org.briarproject.briar.api.android.AndroidNotificationManager;
|
||||
import org.briarproject.briar.api.android.DozeWatchdog;
|
||||
import org.briarproject.briar.api.android.LockManager;
|
||||
@@ -59,7 +57,7 @@ import static java.util.Collections.emptyList;
|
||||
import static org.briarproject.bramble.api.reporting.ReportingConstants.DEV_ONION_ADDRESS;
|
||||
import static org.briarproject.bramble.api.reporting.ReportingConstants.DEV_PUBLIC_KEY_HEX;
|
||||
|
||||
@Module(includes = ViewModelModule.class)
|
||||
@Module
|
||||
public class AppModule {
|
||||
|
||||
static class EagerSingletons {
|
||||
@@ -105,8 +103,7 @@ public class AppModule {
|
||||
Application app, NetworkManager networkManager,
|
||||
LocationUtils locationUtils, EventBus eventBus,
|
||||
ResourceProvider resourceProvider,
|
||||
CircumventionProvider circumventionProvider,
|
||||
BatteryManager batteryManager, Clock clock) {
|
||||
CircumventionProvider circumventionProvider, Clock clock) {
|
||||
Context appContext = app.getApplicationContext();
|
||||
DuplexPluginFactory bluetooth =
|
||||
new AndroidBluetoothPluginFactory(ioExecutor, androidExecutor,
|
||||
@@ -114,7 +111,7 @@ public class AppModule {
|
||||
DuplexPluginFactory tor = new AndroidTorPluginFactory(ioExecutor,
|
||||
scheduler, appContext, networkManager, locationUtils, eventBus,
|
||||
torSocketFactory, backoffFactory, resourceProvider,
|
||||
circumventionProvider, batteryManager, clock);
|
||||
circumventionProvider, clock);
|
||||
DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor,
|
||||
eventBus, backoffFactory, appContext);
|
||||
Collection<DuplexPluginFactory> duplex = asList(bluetooth, tor, lan);
|
||||
|
||||
@@ -18,7 +18,8 @@ import org.briarproject.bramble.util.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -39,7 +40,7 @@ class RecentEmojiImpl implements RecentEmoji, Client {
|
||||
private static final int EMOJI_LRU_SIZE = 50;
|
||||
|
||||
// UI thread
|
||||
private final LinkedList<Emoji> recentlyUsed = new LinkedList<>();
|
||||
private final LinkedHashSet<Emoji> recentlyUsed = new LinkedHashSet<>();
|
||||
|
||||
private final Executor dbExecutor;
|
||||
private final AndroidExecutor androidExecutor;
|
||||
@@ -61,9 +62,13 @@ class RecentEmojiImpl implements RecentEmoji, Client {
|
||||
@Override
|
||||
public void addEmoji(Emoji emoji) {
|
||||
recentlyUsed.remove(emoji);
|
||||
recentlyUsed.add(0, emoji);
|
||||
recentlyUsed.add(emoji);
|
||||
|
||||
if (recentlyUsed.size() > EMOJI_LRU_SIZE) recentlyUsed.removeLast();
|
||||
if (recentlyUsed.size() > EMOJI_LRU_SIZE) {
|
||||
Iterator<Emoji> iterator = recentlyUsed.iterator();
|
||||
iterator.next();
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,10 +15,9 @@ import org.briarproject.briar.android.blog.ReblogFragment;
|
||||
import org.briarproject.briar.android.blog.RssFeedImportActivity;
|
||||
import org.briarproject.briar.android.blog.RssFeedManageActivity;
|
||||
import org.briarproject.briar.android.blog.WriteBlogPostActivity;
|
||||
import org.briarproject.briar.android.conversation.AliasDialogFragment;
|
||||
import org.briarproject.briar.android.contact.ContactListFragment;
|
||||
import org.briarproject.briar.android.contact.ContactModule;
|
||||
import org.briarproject.briar.android.conversation.ConversationActivity;
|
||||
import org.briarproject.briar.android.contact.ConversationActivity;
|
||||
import org.briarproject.briar.android.forum.CreateForumActivity;
|
||||
import org.briarproject.briar.android.forum.ForumActivity;
|
||||
import org.briarproject.briar.android.forum.ForumListFragment;
|
||||
@@ -212,7 +211,4 @@ public interface ActivityComponent {
|
||||
void inject(ScreenFilterDialogFragment fragment);
|
||||
|
||||
void inject(ContactExchangeErrorFragment fragment);
|
||||
|
||||
void inject(AliasDialogFragment aliasDialogFragment);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.briarproject.briar.android.conversation;
|
||||
package org.briarproject.briar.android.contact;
|
||||
|
||||
import android.arch.lifecycle.ViewModelProvider;
|
||||
import android.arch.lifecycle.ViewModelProviders;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
@@ -12,37 +11,40 @@ import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
|
||||
import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.activity.BriarActivity;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public class AliasDialogFragment extends AppCompatDialogFragment {
|
||||
|
||||
final static String TAG = AliasDialogFragment.class.getName();
|
||||
|
||||
@Inject
|
||||
ViewModelProvider.Factory viewModelFactory;
|
||||
|
||||
private ConversationViewModel viewModel;
|
||||
private ContactId contactId;
|
||||
private EditText aliasEditText;
|
||||
|
||||
public static AliasDialogFragment newInstance() {
|
||||
return new AliasDialogFragment();
|
||||
public static AliasDialogFragment newInstance(ContactId id) {
|
||||
AliasDialogFragment f = new AliasDialogFragment();
|
||||
|
||||
Bundle args = new Bundle();
|
||||
args.putInt("contactId", id.getInt());
|
||||
f.setArguments(args);
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
if (getArguments() == null) throw new IllegalArgumentException();
|
||||
int contactIdInt = getArguments().getInt("contactId", -1);
|
||||
if (contactIdInt == -1) throw new IllegalArgumentException();
|
||||
contactId = new ContactId(contactIdInt);
|
||||
|
||||
setStyle(STYLE_NO_TITLE, R.style.BriarDialogTheme);
|
||||
|
||||
if (getActivity() == null) return;
|
||||
((BriarActivity) getActivity()).getActivityComponent().inject(this);
|
||||
viewModel = ViewModelProviders.of(getActivity(), viewModelFactory)
|
||||
.get(ConversationViewModel.class);
|
||||
viewModel =
|
||||
ViewModelProviders.of(getActivity()).get(ConversationViewModel.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -53,14 +55,15 @@ public class AliasDialogFragment extends AppCompatDialogFragment {
|
||||
false);
|
||||
|
||||
aliasEditText = v.findViewById(R.id.aliasEditText);
|
||||
Contact contact = requireNonNull(viewModel.getContact().getValue());
|
||||
String alias = contact.getAlias();
|
||||
Contact contact = viewModel.getContact().getValue();
|
||||
String alias = contact == null ? null : contact.getAlias();
|
||||
aliasEditText.setText(alias);
|
||||
if (alias != null) aliasEditText.setSelection(alias.length());
|
||||
|
||||
Button setButton = v.findViewById(R.id.setButton);
|
||||
setButton.setOnClickListener(v1 -> {
|
||||
viewModel.setContactAlias(aliasEditText.getText().toString());
|
||||
viewModel.setContactAlias(contactId,
|
||||
aliasEditText.getText().toString());
|
||||
getDialog().dismiss();
|
||||
});
|
||||
|
||||
@@ -31,15 +31,14 @@ import org.briarproject.bramble.api.plugin.event.ContactDisconnectedEvent;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||
import org.briarproject.briar.android.contact.BaseContactListAdapter.OnContactClickListener;
|
||||
import org.briarproject.briar.android.conversation.ConversationActivity;
|
||||
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||
import org.briarproject.briar.android.keyagreement.ContactExchangeActivity;
|
||||
import org.briarproject.briar.android.view.BriarRecyclerView;
|
||||
import org.briarproject.briar.api.android.AndroidNotificationManager;
|
||||
import org.briarproject.briar.api.client.MessageTracker.GroupCount;
|
||||
import org.briarproject.briar.api.conversation.ConversationManager;
|
||||
import org.briarproject.briar.api.conversation.ConversationMessageHeader;
|
||||
import org.briarproject.briar.api.conversation.event.ConversationMessageReceivedEvent;
|
||||
import org.briarproject.briar.api.messaging.ConversationManager;
|
||||
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
||||
import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -55,7 +54,7 @@ import static java.util.logging.Level.WARNING;
|
||||
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
import static org.briarproject.bramble.util.LogUtils.now;
|
||||
import static org.briarproject.briar.android.conversation.ConversationActivity.CONTACT_ID;
|
||||
import static org.briarproject.briar.android.contact.ConversationActivity.CONTACT_ID;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
@@ -243,16 +242,15 @@ public class ContactListFragment extends BaseFragment implements EventListener {
|
||||
} else if (e instanceof ContactRemovedEvent) {
|
||||
LOG.info("Contact removed, removing item");
|
||||
removeItem(((ContactRemovedEvent) e).getContactId());
|
||||
} else if (e instanceof ConversationMessageReceivedEvent) {
|
||||
LOG.info("Conversation message received, updating item");
|
||||
ConversationMessageReceivedEvent p =
|
||||
(ConversationMessageReceivedEvent) e;
|
||||
ConversationMessageHeader h = p.getMessageHeader();
|
||||
} else if (e instanceof PrivateMessageReceivedEvent) {
|
||||
LOG.info("Private message received, updating item");
|
||||
PrivateMessageReceivedEvent p = (PrivateMessageReceivedEvent) e;
|
||||
PrivateMessageHeader h = p.getMessageHeader();
|
||||
updateItem(p.getContactId(), h);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateItem(ContactId c, ConversationMessageHeader h) {
|
||||
private void updateItem(ContactId c, PrivateMessageHeader h) {
|
||||
runOnUiThreadUnlessDestroyed(() -> {
|
||||
adapter.incrementRevision();
|
||||
int position = adapter.findItemPosition(c);
|
||||
|
||||
@@ -3,7 +3,7 @@ package org.briarproject.briar.android.contact;
|
||||
import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.briar.api.client.MessageTracker.GroupCount;
|
||||
import org.briarproject.briar.api.conversation.ConversationMessageHeader;
|
||||
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
||||
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
@@ -23,7 +23,7 @@ public class ContactListItem extends ContactItem {
|
||||
this.timestamp = count.getLatestMsgTime();
|
||||
}
|
||||
|
||||
void addMessage(ConversationMessageHeader h) {
|
||||
void addMessage(PrivateMessageHeader h) {
|
||||
empty = false;
|
||||
if (h.getTimestamp() > timestamp) timestamp = h.getTimestamp();
|
||||
if (!h.isRead()) unread++;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.briarproject.briar.android.conversation;
|
||||
package org.briarproject.briar.android.contact;
|
||||
|
||||
import android.arch.lifecycle.LiveData;
|
||||
import android.arch.lifecycle.Observer;
|
||||
import android.arch.lifecycle.ViewModelProvider;
|
||||
import android.arch.lifecycle.ViewModelProviders;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
@@ -51,7 +51,8 @@ import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||
import org.briarproject.briar.android.activity.BriarActivity;
|
||||
import org.briarproject.briar.android.blog.BlogActivity;
|
||||
import org.briarproject.briar.android.conversation.ConversationVisitor.TextCache;
|
||||
import org.briarproject.briar.android.contact.ConversationAdapter.ConversationListener;
|
||||
import org.briarproject.briar.android.contact.ConversationVisitor.TextCache;
|
||||
import org.briarproject.briar.android.forum.ForumActivity;
|
||||
import org.briarproject.briar.android.introduction.IntroductionActivity;
|
||||
import org.briarproject.briar.android.privategroup.conversation.GroupActivity;
|
||||
@@ -62,17 +63,16 @@ import org.briarproject.briar.api.android.AndroidNotificationManager;
|
||||
import org.briarproject.briar.api.blog.BlogSharingManager;
|
||||
import org.briarproject.briar.api.client.ProtocolStateException;
|
||||
import org.briarproject.briar.api.client.SessionId;
|
||||
import org.briarproject.briar.api.conversation.ConversationManager;
|
||||
import org.briarproject.briar.api.conversation.ConversationMessageHeader;
|
||||
import org.briarproject.briar.api.conversation.ConversationRequest;
|
||||
import org.briarproject.briar.api.conversation.ConversationResponse;
|
||||
import org.briarproject.briar.api.conversation.event.ConversationMessageReceivedEvent;
|
||||
import org.briarproject.briar.api.forum.ForumSharingManager;
|
||||
import org.briarproject.briar.api.introduction.IntroductionManager;
|
||||
import org.briarproject.briar.api.messaging.ConversationManager;
|
||||
import org.briarproject.briar.api.messaging.MessagingManager;
|
||||
import org.briarproject.briar.api.messaging.PrivateMessage;
|
||||
import org.briarproject.briar.api.messaging.PrivateMessageFactory;
|
||||
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
||||
import org.briarproject.briar.api.messaging.PrivateRequest;
|
||||
import org.briarproject.briar.api.messaging.PrivateResponse;
|
||||
import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent;
|
||||
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -95,8 +95,6 @@ import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt.PromptSt
|
||||
import static android.support.v4.view.ViewCompat.setTransitionName;
|
||||
import static android.support.v7.util.SortedList.INVALID_POSITION;
|
||||
import static android.widget.Toast.LENGTH_SHORT;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
||||
@@ -106,7 +104,6 @@ import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_INTRO
|
||||
import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_NAMESPACE;
|
||||
import static org.briarproject.briar.android.util.UiUtils.getAvatarTransitionName;
|
||||
import static org.briarproject.briar.android.util.UiUtils.getBulbTransitionName;
|
||||
import static org.briarproject.briar.android.util.UiUtils.observeOnce;
|
||||
import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_TEXT_LENGTH;
|
||||
import static uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt.STATE_DISMISSED;
|
||||
import static uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt.STATE_FINISHED;
|
||||
@@ -165,53 +162,46 @@ public class ConversationActivity extends BriarActivity
|
||||
volatile BlogSharingManager blogSharingManager;
|
||||
@Inject
|
||||
volatile GroupInvitationManager groupInvitationManager;
|
||||
@Inject
|
||||
ViewModelProvider.Factory viewModelFactory;
|
||||
|
||||
private volatile ContactId contactId;
|
||||
@Nullable
|
||||
private volatile GroupId messagingGroupId;
|
||||
|
||||
private final Observer<String> contactNameObserver = name -> {
|
||||
requireNonNull(name);
|
||||
loadMessages();
|
||||
};
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle state) {
|
||||
setSceneTransitionAnimation();
|
||||
super.onCreate(state);
|
||||
|
||||
viewModel =
|
||||
ViewModelProviders.of(this).get(ConversationViewModel.class);
|
||||
|
||||
Intent i = getIntent();
|
||||
int id = i.getIntExtra(CONTACT_ID, -1);
|
||||
if (id == -1) throw new IllegalStateException();
|
||||
contactId = new ContactId(id);
|
||||
|
||||
viewModel = ViewModelProviders.of(this, viewModelFactory)
|
||||
.get(ConversationViewModel.class);
|
||||
viewModel.setContactId(contactId);
|
||||
|
||||
setContentView(R.layout.activity_conversation);
|
||||
|
||||
// Custom Toolbar
|
||||
toolbar = requireNonNull(setUpCustomToolbar(true));
|
||||
toolbar = setUpCustomToolbar(true);
|
||||
toolbarAvatar = toolbar.findViewById(R.id.contactAvatar);
|
||||
toolbarStatus = toolbar.findViewById(R.id.contactStatus);
|
||||
toolbarTitle = toolbar.findViewById(R.id.contactName);
|
||||
|
||||
observeOnce(viewModel.getContactAuthorId(), this, authorId -> {
|
||||
requireNonNull(authorId);
|
||||
viewModel.getContactAuthorId().observe(this, authorId -> {
|
||||
toolbarAvatar.setImageDrawable(
|
||||
new IdenticonDrawable(authorId.getBytes()));
|
||||
// we only need this once
|
||||
viewModel.getContactAuthorId().removeObservers(this);
|
||||
});
|
||||
viewModel.getContactDisplayName().observe(this, contactName -> {
|
||||
requireNonNull(contactName);
|
||||
toolbarTitle.setText(contactName);
|
||||
});
|
||||
viewModel.isContactDeleted().observe(this, deleted -> {
|
||||
requireNonNull(deleted);
|
||||
if (deleted) finish();
|
||||
if (deleted != null && deleted) finish();
|
||||
});
|
||||
viewModel.loadContact(contactId);
|
||||
|
||||
setTransitionName(toolbarAvatar, getAvatarTransitionName(contactId));
|
||||
setTransitionName(toolbarStatus, getBulbTransitionName(contactId));
|
||||
@@ -252,7 +242,19 @@ public class ConversationActivity extends BriarActivity
|
||||
notificationManager.blockContactNotification(contactId);
|
||||
notificationManager.clearContactNotification(contactId);
|
||||
displayContactOnlineStatus();
|
||||
viewModel.getContactDisplayName().observe(this, contactNameObserver);
|
||||
LiveData<String> contactName = viewModel.getContactDisplayName();
|
||||
if (contactName.getValue() == null) {
|
||||
// wait for contact name to be initialized
|
||||
contactName.observe(this, new Observer<String>() {
|
||||
@Override
|
||||
public void onChanged(@Nullable String cName) {
|
||||
if (cName != null) {
|
||||
loadMessages();
|
||||
contactName.removeObserver(this);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else loadMessages();
|
||||
list.startPeriodicUpdate();
|
||||
}
|
||||
|
||||
@@ -261,7 +263,6 @@ public class ConversationActivity extends BriarActivity
|
||||
super.onStop();
|
||||
eventBus.removeListener(this);
|
||||
notificationManager.unblockContactNotification(contactId);
|
||||
viewModel.getContactDisplayName().removeObserver(contactNameObserver);
|
||||
list.stopPeriodicUpdate();
|
||||
}
|
||||
|
||||
@@ -273,8 +274,6 @@ public class ConversationActivity extends BriarActivity
|
||||
|
||||
enableIntroductionActionIfAvailable(
|
||||
menu.findItem(R.id.action_introduction));
|
||||
enableAliasActionIfAvailable(
|
||||
menu.findItem(R.id.action_set_alias));
|
||||
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
@@ -293,7 +292,7 @@ public class ConversationActivity extends BriarActivity
|
||||
startActivityForResult(intent, REQUEST_INTRODUCTION);
|
||||
return true;
|
||||
case R.id.action_set_alias:
|
||||
AliasDialogFragment.newInstance().show(
|
||||
AliasDialogFragment.newInstance(contactId).show(
|
||||
getSupportFragmentManager(), AliasDialogFragment.TAG);
|
||||
return true;
|
||||
case R.id.action_social_remove_person:
|
||||
@@ -327,7 +326,7 @@ public class ConversationActivity extends BriarActivity
|
||||
runOnDbThread(() -> {
|
||||
try {
|
||||
long start = now();
|
||||
Collection<ConversationMessageHeader> headers =
|
||||
Collection<PrivateMessageHeader> headers =
|
||||
conversationManager.getMessageHeaders(contactId);
|
||||
logDuration(LOG, "Loading messages", start);
|
||||
displayMessages(revision, headers);
|
||||
@@ -340,7 +339,7 @@ public class ConversationActivity extends BriarActivity
|
||||
}
|
||||
|
||||
private void displayMessages(int revision,
|
||||
Collection<ConversationMessageHeader> headers) {
|
||||
Collection<PrivateMessageHeader> headers) {
|
||||
runOnUiThreadUnlessDestroyed(() -> {
|
||||
if (revision == adapter.getRevision()) {
|
||||
adapter.incrementRevision();
|
||||
@@ -364,10 +363,9 @@ public class ConversationActivity extends BriarActivity
|
||||
*/
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
private List<ConversationItem> createItems(
|
||||
Collection<ConversationMessageHeader> headers) {
|
||||
Collection<PrivateMessageHeader> headers) {
|
||||
List<ConversationItem> items = new ArrayList<>(headers.size());
|
||||
for (ConversationMessageHeader h : headers)
|
||||
items.add(h.accept(visitor));
|
||||
for (PrivateMessageHeader h : headers) items.add(h.accept(visitor));
|
||||
return items;
|
||||
}
|
||||
|
||||
@@ -387,8 +385,8 @@ public class ConversationActivity extends BriarActivity
|
||||
private void displayMessageText(MessageId m, String text) {
|
||||
runOnUiThreadUnlessDestroyed(() -> {
|
||||
textCache.put(m, text);
|
||||
SparseArray<ConversationMessageItem> messages =
|
||||
adapter.getMessageItems();
|
||||
SparseArray<ConversationItem> messages =
|
||||
adapter.getPrivateMessages();
|
||||
for (int i = 0; i < messages.size(); i++) {
|
||||
ConversationItem item = messages.valueAt(i);
|
||||
if (item.getId().equals(m)) {
|
||||
@@ -409,12 +407,11 @@ public class ConversationActivity extends BriarActivity
|
||||
LOG.info("Contact removed");
|
||||
finishOnUiThread();
|
||||
}
|
||||
} else if (e instanceof ConversationMessageReceivedEvent) {
|
||||
ConversationMessageReceivedEvent p =
|
||||
(ConversationMessageReceivedEvent) e;
|
||||
} else if (e instanceof PrivateMessageReceivedEvent) {
|
||||
PrivateMessageReceivedEvent p = (PrivateMessageReceivedEvent) e;
|
||||
if (p.getContactId().equals(contactId)) {
|
||||
LOG.info("Message received, adding");
|
||||
onNewConversationMessage(p.getMessageHeader());
|
||||
onNewPrivateMessage(p.getMessageHeader());
|
||||
}
|
||||
} else if (e instanceof MessagesSentEvent) {
|
||||
MessagesSentEvent m = (MessagesSentEvent) e;
|
||||
@@ -452,16 +449,29 @@ public class ConversationActivity extends BriarActivity
|
||||
});
|
||||
}
|
||||
|
||||
private void onNewConversationMessage(ConversationMessageHeader h) {
|
||||
private void onNewPrivateMessage(PrivateMessageHeader h) {
|
||||
runOnUiThreadUnlessDestroyed(() -> {
|
||||
if (h instanceof ConversationRequest ||
|
||||
h instanceof ConversationResponse) {
|
||||
// contact name might not have been loaded
|
||||
observeOnce(viewModel.getContactDisplayName(), this,
|
||||
name -> addConversationItem(h.accept(visitor)));
|
||||
if (h instanceof PrivateRequest || h instanceof PrivateResponse) {
|
||||
String cName = viewModel.getContactDisplayName().getValue();
|
||||
if (cName == null) {
|
||||
// Wait for the contact name to be loaded
|
||||
viewModel.getContactDisplayName()
|
||||
.observe(this, new Observer<String>() {
|
||||
@Override
|
||||
public void onChanged(@Nullable String cName) {
|
||||
if (cName != null) {
|
||||
addConversationItem(h.accept(visitor));
|
||||
viewModel.getContactDisplayName()
|
||||
.removeObserver(this);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
addConversationItem(h.accept(visitor));
|
||||
}
|
||||
} else {
|
||||
// visitor also loads message text (if existing)
|
||||
addConversationItem(h.accept(visitor));
|
||||
loadMessageText(h.getId());
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -471,9 +481,10 @@ public class ConversationActivity extends BriarActivity
|
||||
runOnUiThreadUnlessDestroyed(() -> {
|
||||
adapter.incrementRevision();
|
||||
Set<MessageId> messages = new HashSet<>(messageIds);
|
||||
SparseArray<ConversationItem> list = adapter.getOutgoingMessages();
|
||||
SparseArray<ConversationOutItem> list =
|
||||
adapter.getOutgoingMessages();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
ConversationItem item = list.valueAt(i);
|
||||
ConversationOutItem item = list.valueAt(i);
|
||||
if (messages.contains(item.getId())) {
|
||||
item.setSent(sent);
|
||||
item.setSeen(seen);
|
||||
@@ -518,7 +529,7 @@ public class ConversationActivity extends BriarActivity
|
||||
try {
|
||||
//noinspection ConstantConditions init in loadGroupId()
|
||||
storeMessage(privateMessageFactory.createPrivateMessage(
|
||||
messagingGroupId, timestamp, text, emptyList()), text);
|
||||
messagingGroupId, timestamp, text), text);
|
||||
} catch (FormatException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -534,8 +545,7 @@ public class ConversationActivity extends BriarActivity
|
||||
Message message = m.getMessage();
|
||||
PrivateMessageHeader h = new PrivateMessageHeader(
|
||||
message.getId(), message.getGroupId(),
|
||||
message.getTimestamp(), true, false, false, false,
|
||||
true, emptyList());
|
||||
message.getTimestamp(), true, false, false, false);
|
||||
textCache.put(message.getId(), text);
|
||||
addConversationItem(h.accept(visitor));
|
||||
} catch (DbException e) {
|
||||
@@ -596,10 +606,6 @@ public class ConversationActivity extends BriarActivity
|
||||
});
|
||||
}
|
||||
|
||||
private void enableAliasActionIfAvailable(MenuItem item) {
|
||||
observeOnce(viewModel.getContact(), this, c -> item.setEnabled(true));
|
||||
}
|
||||
|
||||
private void enableIntroductionAction(MenuItem item) {
|
||||
runOnUiThreadUnlessDestroyed(() -> item.setEnabled(true));
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
package org.briarproject.briar.android.conversation;
|
||||
package org.briarproject.briar.android.contact;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.util.SparseArray;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -13,14 +14,12 @@ import org.briarproject.briar.android.util.BriarAdapter;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@NotNullByDefault
|
||||
class ConversationAdapter
|
||||
extends BriarAdapter<ConversationItem, ConversationItemViewHolder> {
|
||||
|
||||
private ConversationListener listener;
|
||||
|
||||
ConversationAdapter(Context ctx,
|
||||
ConversationListener conversationListener) {
|
||||
ConversationAdapter(Context ctx, ConversationListener conversationListener) {
|
||||
super(ctx, ConversationItem.class);
|
||||
listener = conversationListener;
|
||||
}
|
||||
@@ -39,15 +38,15 @@ class ConversationAdapter
|
||||
type, viewGroup, false);
|
||||
switch (type) {
|
||||
case R.layout.list_item_conversation_msg_in:
|
||||
return new ConversationMessageViewHolder(v, true);
|
||||
return new ConversationItemViewHolder(v);
|
||||
case R.layout.list_item_conversation_msg_out:
|
||||
return new ConversationMessageViewHolder(v, false);
|
||||
return new ConversationMessageOutViewHolder(v);
|
||||
case R.layout.list_item_conversation_notice_in:
|
||||
return new ConversationNoticeViewHolder(v, true);
|
||||
return new ConversationNoticeInViewHolder(v);
|
||||
case R.layout.list_item_conversation_notice_out:
|
||||
return new ConversationNoticeViewHolder(v, false);
|
||||
return new ConversationNoticeOutViewHolder(v);
|
||||
case R.layout.list_item_conversation_request:
|
||||
return new ConversationRequestViewHolder(v, true);
|
||||
return new ConversationRequestViewHolder(v);
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown ConversationItem");
|
||||
}
|
||||
@@ -56,13 +55,22 @@ class ConversationAdapter
|
||||
@Override
|
||||
public void onBindViewHolder(ConversationItemViewHolder ui, int position) {
|
||||
ConversationItem item = items.get(position);
|
||||
ui.bind(item, listener);
|
||||
if (item instanceof ConversationRequestItem) {
|
||||
((ConversationRequestViewHolder) ui).bind(item, listener);
|
||||
} else {
|
||||
ui.bind(item);
|
||||
}
|
||||
listener.onItemVisible(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(ConversationItem c1, ConversationItem c2) {
|
||||
return Long.compare(c1.getTime(), c2.getTime());
|
||||
public int compare(ConversationItem c1,
|
||||
ConversationItem c2) {
|
||||
long time1 = c1.getTime();
|
||||
long time2 = c2.getTime();
|
||||
if (time1 < time2) return -1;
|
||||
if (time1 > time2) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -86,28 +94,54 @@ class ConversationAdapter
|
||||
}
|
||||
}
|
||||
|
||||
SparseArray<ConversationItem> getOutgoingMessages() {
|
||||
SparseArray<ConversationItem> getIncomingMessages() {
|
||||
SparseArray<ConversationItem> messages = new SparseArray<>();
|
||||
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
ConversationItem item = items.get(i);
|
||||
if (!item.isIncoming()) {
|
||||
if (item.isIncoming()) {
|
||||
messages.put(i, item);
|
||||
}
|
||||
}
|
||||
return messages;
|
||||
}
|
||||
|
||||
SparseArray<ConversationMessageItem> getMessageItems() {
|
||||
SparseArray<ConversationMessageItem> messages = new SparseArray<>();
|
||||
SparseArray<ConversationOutItem> getOutgoingMessages() {
|
||||
SparseArray<ConversationOutItem> messages = new SparseArray<>();
|
||||
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
ConversationItem item = items.get(i);
|
||||
if (item instanceof ConversationMessageItem) {
|
||||
messages.put(i, (ConversationMessageItem) item);
|
||||
if (item instanceof ConversationOutItem) {
|
||||
messages.put(i, (ConversationOutItem) item);
|
||||
}
|
||||
}
|
||||
return messages;
|
||||
}
|
||||
|
||||
SparseArray<ConversationItem> getPrivateMessages() {
|
||||
SparseArray<ConversationItem> messages = new SparseArray<>();
|
||||
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
ConversationItem item = items.get(i);
|
||||
if (item instanceof ConversationMessageInItem) {
|
||||
messages.put(i, item);
|
||||
} else if (item instanceof ConversationMessageOutItem) {
|
||||
messages.put(i, item);
|
||||
}
|
||||
}
|
||||
return messages;
|
||||
}
|
||||
|
||||
@UiThread
|
||||
@NotNullByDefault
|
||||
interface ConversationListener {
|
||||
|
||||
void onItemVisible(ConversationItem item);
|
||||
|
||||
void respondToRequest(ConversationRequestItem item, boolean accept);
|
||||
|
||||
void openRequestedShareable(ConversationRequestItem item);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package org.briarproject.briar.android.contact;
|
||||
|
||||
import android.support.annotation.LayoutRes;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
@NotThreadSafe
|
||||
@NotNullByDefault
|
||||
abstract class ConversationItem {
|
||||
|
||||
@Nullable
|
||||
protected String text;
|
||||
private final MessageId id;
|
||||
private final GroupId groupId;
|
||||
private final long time;
|
||||
private boolean read;
|
||||
|
||||
ConversationItem(MessageId id, GroupId groupId, @Nullable String text,
|
||||
long time, boolean read) {
|
||||
this.id = id;
|
||||
this.groupId = groupId;
|
||||
this.text = text;
|
||||
this.time = time;
|
||||
this.read = read;
|
||||
}
|
||||
|
||||
MessageId getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
GroupId getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public boolean isRead() {
|
||||
return read;
|
||||
}
|
||||
|
||||
abstract public boolean isIncoming();
|
||||
|
||||
@LayoutRes
|
||||
abstract public int getLayout();
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.briarproject.briar.android.contact;
|
||||
|
||||
import android.support.annotation.CallSuper;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.support.v7.widget.RecyclerView.ViewHolder;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.util.UiUtils;
|
||||
|
||||
@UiThread
|
||||
@NotNullByDefault
|
||||
class ConversationItemViewHolder extends ViewHolder {
|
||||
|
||||
protected final ViewGroup layout;
|
||||
private final TextView text;
|
||||
private final TextView time;
|
||||
|
||||
ConversationItemViewHolder(View v) {
|
||||
super(v);
|
||||
layout = v.findViewById(R.id.layout);
|
||||
text = v.findViewById(R.id.text);
|
||||
time = v.findViewById(R.id.time);
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
void bind(ConversationItem item) {
|
||||
if (item.getText() == null) {
|
||||
text.setText("\u2026");
|
||||
} else {
|
||||
text.setText(StringUtils.trim(item.getText()));
|
||||
}
|
||||
|
||||
long timestamp = item.getTime();
|
||||
time.setText(UiUtils.formatDate(time.getContext(), timestamp));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package org.briarproject.briar.android.contact;
|
||||
|
||||
import android.support.annotation.LayoutRes;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
||||
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
@NotThreadSafe
|
||||
@NotNullByDefault
|
||||
class ConversationMessageInItem extends ConversationItem {
|
||||
|
||||
ConversationMessageInItem(PrivateMessageHeader h) {
|
||||
super(h.getId(), h.getGroupId(), null, h.getTimestamp(), h.isRead());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncoming() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@LayoutRes
|
||||
@Override
|
||||
public int getLayout() {
|
||||
return R.layout.list_item_conversation_msg_in;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.briarproject.briar.android.contact;
|
||||
|
||||
import android.support.annotation.LayoutRes;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
||||
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
@NotThreadSafe
|
||||
@NotNullByDefault
|
||||
class ConversationMessageOutItem extends ConversationOutItem {
|
||||
|
||||
ConversationMessageOutItem(PrivateMessageHeader h) {
|
||||
super(h.getId(), h.getGroupId(), null, h.getTimestamp(), h.isSent(),
|
||||
h.isSeen());
|
||||
}
|
||||
|
||||
@LayoutRes
|
||||
@Override
|
||||
public int getLayout() {
|
||||
return R.layout.list_item_conversation_msg_out;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.briarproject.briar.android.contact;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
class ConversationMessageOutViewHolder extends ConversationOutItemViewHolder {
|
||||
|
||||
ConversationMessageOutViewHolder(View v) {
|
||||
super(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasDarkBackground() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.briarproject.briar.android.contact;
|
||||
|
||||
import android.support.annotation.LayoutRes;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.api.messaging.PrivateResponse;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
@NotThreadSafe
|
||||
@NotNullByDefault
|
||||
class ConversationNoticeInItem extends ConversationItem {
|
||||
|
||||
@Nullable
|
||||
private final String msgText;
|
||||
|
||||
ConversationNoticeInItem(MessageId id, GroupId groupId, String text,
|
||||
@Nullable String msgText, long time, boolean read) {
|
||||
super(id, groupId, text, time, read);
|
||||
this.msgText = msgText;
|
||||
}
|
||||
|
||||
ConversationNoticeInItem(String text, PrivateResponse r) {
|
||||
super(r.getId(), r.getGroupId(), text, r.getTimestamp(), r.isRead());
|
||||
this.msgText = null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
String getMsgText() {
|
||||
return msgText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncoming() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@LayoutRes
|
||||
@Override
|
||||
public int getLayout() {
|
||||
return R.layout.list_item_conversation_notice_in;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package org.briarproject.briar.android.contact;
|
||||
|
||||
import android.support.annotation.UiThread;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.briarproject.briar.R;
|
||||
|
||||
import static android.view.View.GONE;
|
||||
import static android.view.View.VISIBLE;
|
||||
|
||||
@UiThread
|
||||
@NotNullByDefault
|
||||
class ConversationNoticeInViewHolder extends ConversationItemViewHolder {
|
||||
|
||||
private final TextView msgText;
|
||||
|
||||
ConversationNoticeInViewHolder(View v) {
|
||||
super(v);
|
||||
msgText = v.findViewById(R.id.msgText);
|
||||
}
|
||||
|
||||
@Override
|
||||
void bind(ConversationItem conversationItem) {
|
||||
super.bind(conversationItem);
|
||||
|
||||
ConversationNoticeInItem item =
|
||||
(ConversationNoticeInItem) conversationItem;
|
||||
|
||||
String text = item.getMsgText();
|
||||
if (StringUtils.isNullOrEmpty(text)) {
|
||||
msgText.setVisibility(GONE);
|
||||
layout.setBackgroundResource(R.drawable.notice_in);
|
||||
} else {
|
||||
msgText.setVisibility(VISIBLE);
|
||||
msgText.setText(StringUtils.trim(text));
|
||||
layout.setBackgroundResource(R.drawable.notice_in_bottom);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.briarproject.briar.android.contact;
|
||||
|
||||
import android.support.annotation.LayoutRes;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.api.messaging.PrivateRequest;
|
||||
import org.briarproject.briar.api.messaging.PrivateResponse;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
@NotThreadSafe
|
||||
@NotNullByDefault
|
||||
class ConversationNoticeOutItem extends ConversationOutItem {
|
||||
|
||||
@Nullable
|
||||
private final String msgText;
|
||||
|
||||
ConversationNoticeOutItem(String text, PrivateRequest r) {
|
||||
super(r.getId(), r.getGroupId(), text, r.getTimestamp(), r.isSent(),
|
||||
r.isSeen());
|
||||
this.msgText = r.getText();
|
||||
}
|
||||
|
||||
ConversationNoticeOutItem(String text, PrivateResponse r) {
|
||||
super(r.getId(), r.getGroupId(), text, r.getTimestamp(), r.isSent(),
|
||||
r.isSeen());
|
||||
this.msgText = null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
String getMsgText() {
|
||||
return msgText;
|
||||
}
|
||||
|
||||
@LayoutRes
|
||||
@Override
|
||||
public int getLayout() {
|
||||
return R.layout.list_item_conversation_notice_out;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package org.briarproject.briar.android.contact;
|
||||
|
||||
import android.support.annotation.UiThread;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.briarproject.briar.R;
|
||||
|
||||
import static android.view.View.GONE;
|
||||
import static android.view.View.VISIBLE;
|
||||
|
||||
@UiThread
|
||||
@NotNullByDefault
|
||||
class ConversationNoticeOutViewHolder extends ConversationOutItemViewHolder {
|
||||
|
||||
private final TextView msgText;
|
||||
|
||||
ConversationNoticeOutViewHolder(View v) {
|
||||
super(v);
|
||||
msgText = v.findViewById(R.id.msgText);
|
||||
}
|
||||
|
||||
@Override
|
||||
void bind(ConversationItem conversationItem) {
|
||||
super.bind(conversationItem);
|
||||
|
||||
ConversationNoticeOutItem item =
|
||||
(ConversationNoticeOutItem) conversationItem;
|
||||
|
||||
String text = item.getMsgText();
|
||||
if (StringUtils.isNullOrEmpty(text)) {
|
||||
msgText.setVisibility(GONE);
|
||||
layout.setBackgroundResource(R.drawable.notice_out);
|
||||
} else {
|
||||
msgText.setVisibility(VISIBLE);
|
||||
msgText.setText(StringUtils.trim(text));
|
||||
layout.setBackgroundResource(R.drawable.notice_out_bottom);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasDarkBackground() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package org.briarproject.briar.android.contact;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
@NotThreadSafe
|
||||
@NotNullByDefault
|
||||
abstract class ConversationOutItem extends ConversationItem {
|
||||
|
||||
private boolean sent, seen;
|
||||
|
||||
ConversationOutItem(MessageId id, GroupId groupId, @Nullable String text,
|
||||
long time, boolean sent, boolean seen) {
|
||||
super(id, groupId, text, time, true);
|
||||
|
||||
this.sent = sent;
|
||||
this.seen = seen;
|
||||
}
|
||||
|
||||
boolean isSent() {
|
||||
return sent;
|
||||
}
|
||||
|
||||
void setSent(boolean sent) {
|
||||
this.sent = sent;
|
||||
}
|
||||
|
||||
boolean isSeen() {
|
||||
return seen;
|
||||
}
|
||||
|
||||
void setSeen(boolean seen) {
|
||||
this.seen = seen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncoming() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package org.briarproject.briar.android.contact;
|
||||
|
||||
import android.support.annotation.UiThread;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.briar.R;
|
||||
|
||||
@UiThread
|
||||
@NotNullByDefault
|
||||
abstract class ConversationOutItemViewHolder
|
||||
extends ConversationItemViewHolder {
|
||||
|
||||
private final ImageView status;
|
||||
|
||||
ConversationOutItemViewHolder(View v) {
|
||||
super(v);
|
||||
status = v.findViewById(R.id.status);
|
||||
}
|
||||
|
||||
@Override
|
||||
void bind(ConversationItem conversationItem) {
|
||||
super.bind(conversationItem);
|
||||
|
||||
ConversationOutItem item = (ConversationOutItem) conversationItem;
|
||||
|
||||
int res;
|
||||
if (item.isSeen()) {
|
||||
if (hasDarkBackground()) res = R.drawable.message_delivered_white;
|
||||
else res = R.drawable.message_delivered;
|
||||
} else if (item.isSent()) {
|
||||
if (hasDarkBackground()) res = R.drawable.message_sent_white;
|
||||
else res = R.drawable.message_sent;
|
||||
} else {
|
||||
if (hasDarkBackground()) res = R.drawable.message_stored_white;
|
||||
else res = R.drawable.message_stored;
|
||||
}
|
||||
status.setImageResource(res);
|
||||
}
|
||||
|
||||
protected abstract boolean hasDarkBackground();
|
||||
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
package org.briarproject.briar.android.conversation;
|
||||
package org.briarproject.briar.android.contact;
|
||||
|
||||
import android.support.annotation.LayoutRes;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.api.client.SessionId;
|
||||
import org.briarproject.briar.api.conversation.ConversationRequest;
|
||||
import org.briarproject.briar.api.messaging.PrivateRequest;
|
||||
import org.briarproject.briar.api.sharing.InvitationRequest;
|
||||
import org.briarproject.briar.api.sharing.Shareable;
|
||||
|
||||
@@ -14,7 +15,7 @@ import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
@NotThreadSafe
|
||||
@NotNullByDefault
|
||||
class ConversationRequestItem extends ConversationNoticeItem {
|
||||
class ConversationRequestItem extends ConversationNoticeInItem {
|
||||
|
||||
enum RequestType {INTRODUCTION, FORUM, BLOG, GROUP}
|
||||
|
||||
@@ -25,9 +26,9 @@ class ConversationRequestItem extends ConversationNoticeItem {
|
||||
private final boolean canBeOpened;
|
||||
private boolean answered;
|
||||
|
||||
ConversationRequestItem(@LayoutRes int layoutRes, String text,
|
||||
RequestType type, ConversationRequest r) {
|
||||
super(layoutRes, text, r);
|
||||
ConversationRequestItem(String text, RequestType type, PrivateRequest r) {
|
||||
super(r.getId(), r.getGroupId(), text, r.getText(),
|
||||
r.getTimestamp(), r.isRead());
|
||||
this.requestType = type;
|
||||
this.sessionId = r.getSessionId();
|
||||
this.answered = r.wasAnswered();
|
||||
@@ -49,7 +50,7 @@ class ConversationRequestItem extends ConversationNoticeItem {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
GroupId getRequestedGroupId() {
|
||||
public GroupId getRequestedGroupId() {
|
||||
return requestedGroupId;
|
||||
}
|
||||
|
||||
@@ -61,8 +62,13 @@ class ConversationRequestItem extends ConversationNoticeItem {
|
||||
this.answered = true;
|
||||
}
|
||||
|
||||
boolean canBeOpened() {
|
||||
public boolean canBeOpened() {
|
||||
return canBeOpened;
|
||||
}
|
||||
|
||||
@LayoutRes
|
||||
@Override
|
||||
public int getLayout() {
|
||||
return R.layout.list_item_conversation_request;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.briarproject.briar.android.conversation;
|
||||
package org.briarproject.briar.android.contact;
|
||||
|
||||
import android.support.annotation.UiThread;
|
||||
import android.view.View;
|
||||
@@ -6,35 +6,38 @@ import android.widget.Button;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.contact.ConversationAdapter.ConversationListener;
|
||||
|
||||
import static android.view.View.GONE;
|
||||
import static android.view.View.VISIBLE;
|
||||
|
||||
@UiThread
|
||||
@NotNullByDefault
|
||||
class ConversationRequestViewHolder extends ConversationNoticeViewHolder {
|
||||
class ConversationRequestViewHolder extends ConversationNoticeInViewHolder {
|
||||
|
||||
private final Button acceptButton;
|
||||
private final Button declineButton;
|
||||
|
||||
ConversationRequestViewHolder(View v, boolean isIncoming) {
|
||||
super(v, isIncoming);
|
||||
ConversationRequestViewHolder(View v) {
|
||||
super(v);
|
||||
acceptButton = v.findViewById(R.id.acceptButton);
|
||||
declineButton = v.findViewById(R.id.declineButton);
|
||||
}
|
||||
|
||||
@Override
|
||||
void bind(ConversationItem item, ConversationListener listener) {
|
||||
ConversationRequestItem request = (ConversationRequestItem) item;
|
||||
super.bind(request, listener);
|
||||
void bind(ConversationItem conversationItem,
|
||||
ConversationListener listener) {
|
||||
super.bind(conversationItem);
|
||||
|
||||
if (request.wasAnswered() && request.canBeOpened()) {
|
||||
ConversationRequestItem item =
|
||||
(ConversationRequestItem) conversationItem;
|
||||
|
||||
if (item.wasAnswered() && item.canBeOpened()) {
|
||||
acceptButton.setVisibility(VISIBLE);
|
||||
acceptButton.setText(R.string.open);
|
||||
acceptButton.setOnClickListener(
|
||||
v -> listener.openRequestedShareable(request));
|
||||
v -> listener.openRequestedShareable(item));
|
||||
declineButton.setVisibility(GONE);
|
||||
} else if (request.wasAnswered()) {
|
||||
} else if (item.wasAnswered()) {
|
||||
acceptButton.setVisibility(GONE);
|
||||
declineButton.setVisibility(GONE);
|
||||
} else {
|
||||
@@ -43,13 +46,13 @@ class ConversationRequestViewHolder extends ConversationNoticeViewHolder {
|
||||
acceptButton.setOnClickListener(v -> {
|
||||
acceptButton.setEnabled(false);
|
||||
declineButton.setEnabled(false);
|
||||
listener.respondToRequest(request, true);
|
||||
listener.respondToRequest(item, true);
|
||||
});
|
||||
declineButton.setVisibility(VISIBLE);
|
||||
declineButton.setOnClickListener(v -> {
|
||||
acceptButton.setEnabled(false);
|
||||
declineButton.setEnabled(false);
|
||||
listener.respondToRequest(request, false);
|
||||
listener.respondToRequest(item, false);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package org.briarproject.briar.android.conversation;
|
||||
package org.briarproject.briar.android.contact;
|
||||
|
||||
import android.app.Application;
|
||||
import android.arch.lifecycle.AndroidViewModel;
|
||||
import android.arch.lifecycle.LiveData;
|
||||
import android.arch.lifecycle.MutableLiveData;
|
||||
import android.arch.lifecycle.Transformations;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
@@ -14,7 +14,8 @@ import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.db.NoSuchContactException;
|
||||
import org.briarproject.bramble.api.identity.AuthorId;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.briar.android.AndroidComponent;
|
||||
import org.briarproject.briar.android.BriarApplication;
|
||||
import org.briarproject.briar.android.util.UiUtils;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
@@ -22,25 +23,22 @@ import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
import static org.briarproject.bramble.util.LogUtils.now;
|
||||
|
||||
@NotNullByDefault
|
||||
public class ConversationViewModel extends AndroidViewModel {
|
||||
|
||||
private static Logger LOG =
|
||||
getLogger(ConversationViewModel.class.getName());
|
||||
Logger.getLogger(ConversationViewModel.class.getName());
|
||||
|
||||
@Inject
|
||||
@DatabaseExecutor
|
||||
private final Executor dbExecutor;
|
||||
private final ContactManager contactManager;
|
||||
Executor dbExecutor;
|
||||
@Inject
|
||||
ContactManager contactManager;
|
||||
|
||||
@Nullable
|
||||
private ContactId contactId = null;
|
||||
private final MutableLiveData<Contact> contact = new MutableLiveData<>();
|
||||
private final LiveData<AuthorId> contactAuthorId =
|
||||
Transformations.map(contact, c -> c.getAuthor().getId());
|
||||
@@ -49,32 +47,19 @@ public class ConversationViewModel extends AndroidViewModel {
|
||||
private final MutableLiveData<Boolean> contactDeleted =
|
||||
new MutableLiveData<>();
|
||||
|
||||
@Inject
|
||||
ConversationViewModel(Application application,
|
||||
@DatabaseExecutor Executor dbExecutor,
|
||||
ContactManager contactManager) {
|
||||
public ConversationViewModel(@NonNull Application application) {
|
||||
super(application);
|
||||
this.dbExecutor = dbExecutor;
|
||||
this.contactManager = contactManager;
|
||||
AndroidComponent component =
|
||||
((BriarApplication) application).getApplicationComponent();
|
||||
component.inject(this);
|
||||
contactDeleted.setValue(false);
|
||||
}
|
||||
|
||||
void setContactId(ContactId contactId) {
|
||||
if (this.contactId == null) {
|
||||
this.contactId = contactId;
|
||||
loadContact();
|
||||
} else if (!contactId.equals(this.contactId)) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadContact() {
|
||||
void loadContact(ContactId contactId) {
|
||||
dbExecutor.execute(() -> {
|
||||
try {
|
||||
long start = now();
|
||||
Contact c =
|
||||
contactManager.getContact(requireNonNull(contactId));
|
||||
contact.postValue(c);
|
||||
contact.postValue(contactManager.getContact(contactId));
|
||||
logDuration(LOG, "Loading contact", start);
|
||||
} catch (NoSuchContactException e) {
|
||||
contactDeleted.postValue(true);
|
||||
@@ -84,12 +69,12 @@ public class ConversationViewModel extends AndroidViewModel {
|
||||
});
|
||||
}
|
||||
|
||||
void setContactAlias(String alias) {
|
||||
void setContactAlias(ContactId contactId, String alias) {
|
||||
dbExecutor.execute(() -> {
|
||||
try {
|
||||
contactManager.setContactAlias(requireNonNull(contactId),
|
||||
contactManager.setContactAlias(contactId,
|
||||
alias.isEmpty() ? null : alias);
|
||||
loadContact();
|
||||
loadContact(contactId);
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.briarproject.briar.android.conversation;
|
||||
package org.briarproject.briar.android.contact;
|
||||
|
||||
import android.arch.lifecycle.LiveData;
|
||||
import android.content.Context;
|
||||
@@ -14,22 +14,21 @@ import org.briarproject.briar.api.forum.ForumInvitationResponse;
|
||||
import org.briarproject.briar.api.introduction.IntroductionRequest;
|
||||
import org.briarproject.briar.api.introduction.IntroductionResponse;
|
||||
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
||||
import org.briarproject.briar.api.conversation.ConversationMessageVisitor;
|
||||
import org.briarproject.briar.api.messaging.PrivateMessageVisitor;
|
||||
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationRequest;
|
||||
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationResponse;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static org.briarproject.briar.android.conversation.ConversationRequestItem.RequestType.BLOG;
|
||||
import static org.briarproject.briar.android.conversation.ConversationRequestItem.RequestType.FORUM;
|
||||
import static org.briarproject.briar.android.conversation.ConversationRequestItem.RequestType.GROUP;
|
||||
import static org.briarproject.briar.android.conversation.ConversationRequestItem.RequestType.INTRODUCTION;
|
||||
import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.BLOG;
|
||||
import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.FORUM;
|
||||
import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.GROUP;
|
||||
import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.INTRODUCTION;
|
||||
import static org.briarproject.briar.android.util.UiUtils.getContactDisplayName;
|
||||
|
||||
@UiThread
|
||||
@NotNullByDefault
|
||||
class ConversationVisitor implements
|
||||
ConversationMessageVisitor<ConversationItem> {
|
||||
class ConversationVisitor implements PrivateMessageVisitor<ConversationItem> {
|
||||
|
||||
private final Context ctx;
|
||||
private final TextCache textCache;
|
||||
@@ -45,17 +44,10 @@ class ConversationVisitor implements
|
||||
@Override
|
||||
public ConversationItem visitPrivateMessageHeader(PrivateMessageHeader h) {
|
||||
ConversationItem item;
|
||||
if (h.isLocal()) {
|
||||
item = new ConversationMessageItem(
|
||||
R.layout.list_item_conversation_msg_out, h);
|
||||
} else {
|
||||
item = new ConversationMessageItem(
|
||||
R.layout.list_item_conversation_msg_in, h);
|
||||
}
|
||||
if (h.hasText()) {
|
||||
String text = textCache.getText(h.getId());
|
||||
if (text != null) item.setText(text);
|
||||
}
|
||||
if (h.isLocal()) item = new ConversationMessageOutItem(h);
|
||||
else item = new ConversationMessageInItem(h);
|
||||
String text = textCache.getText(h.getId());
|
||||
if (text != null) item.setText(text);
|
||||
return item;
|
||||
}
|
||||
|
||||
@@ -65,14 +57,12 @@ class ConversationVisitor implements
|
||||
if (r.isLocal()) {
|
||||
String text = ctx.getString(R.string.blogs_sharing_invitation_sent,
|
||||
r.getName(), contactName.getValue());
|
||||
return new ConversationNoticeItem(
|
||||
R.layout.list_item_conversation_notice_out, text, r);
|
||||
return new ConversationNoticeOutItem(text, r);
|
||||
} else {
|
||||
String text = ctx.getString(
|
||||
R.string.blogs_sharing_invitation_received,
|
||||
contactName.getValue(), r.getName());
|
||||
return new ConversationRequestItem(
|
||||
R.layout.list_item_conversation_request, text, BLOG, r);
|
||||
return new ConversationRequestItem(text, BLOG, r);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,8 +80,7 @@ class ConversationVisitor implements
|
||||
R.string.blogs_sharing_response_declined_sent,
|
||||
contactName.getValue());
|
||||
}
|
||||
return new ConversationNoticeItem(
|
||||
R.layout.list_item_conversation_notice_out, text, r);
|
||||
return new ConversationNoticeOutItem(text, r);
|
||||
} else {
|
||||
String text;
|
||||
if (r.wasAccepted()) {
|
||||
@@ -103,8 +92,7 @@ class ConversationVisitor implements
|
||||
R.string.blogs_sharing_response_declined_received,
|
||||
contactName.getValue());
|
||||
}
|
||||
return new ConversationNoticeItem(
|
||||
R.layout.list_item_conversation_notice_in, text, r);
|
||||
return new ConversationNoticeInItem(text, r);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,14 +102,12 @@ class ConversationVisitor implements
|
||||
if (r.isLocal()) {
|
||||
String text = ctx.getString(R.string.forum_invitation_sent,
|
||||
r.getName(), contactName.getValue());
|
||||
return new ConversationNoticeItem(
|
||||
R.layout.list_item_conversation_notice_out, text, r);
|
||||
return new ConversationNoticeOutItem(text, r);
|
||||
} else {
|
||||
String text = ctx.getString(
|
||||
R.string.forum_invitation_received,
|
||||
contactName.getValue(), r.getName());
|
||||
return new ConversationRequestItem(
|
||||
R.layout.list_item_conversation_request, text, FORUM, r);
|
||||
return new ConversationRequestItem(text, FORUM, r);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,8 +125,7 @@ class ConversationVisitor implements
|
||||
R.string.forum_invitation_response_declined_sent,
|
||||
contactName.getValue());
|
||||
}
|
||||
return new ConversationNoticeItem(
|
||||
R.layout.list_item_conversation_notice_out, text, r);
|
||||
return new ConversationNoticeOutItem(text, r);
|
||||
} else {
|
||||
String text;
|
||||
if (r.wasAccepted()) {
|
||||
@@ -152,8 +137,7 @@ class ConversationVisitor implements
|
||||
R.string.forum_invitation_response_declined_received,
|
||||
contactName.getValue());
|
||||
}
|
||||
return new ConversationNoticeItem(
|
||||
R.layout.list_item_conversation_notice_in, text, r);
|
||||
return new ConversationNoticeInItem(text, r);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,14 +148,12 @@ class ConversationVisitor implements
|
||||
String text = ctx.getString(
|
||||
R.string.groups_invitations_invitation_sent,
|
||||
contactName.getValue(), r.getName());
|
||||
return new ConversationNoticeItem(
|
||||
R.layout.list_item_conversation_notice_out, text, r);
|
||||
return new ConversationNoticeOutItem(text, r);
|
||||
} else {
|
||||
String text = ctx.getString(
|
||||
R.string.groups_invitations_invitation_received,
|
||||
contactName.getValue(), r.getName());
|
||||
return new ConversationRequestItem(
|
||||
R.layout.list_item_conversation_request, text, GROUP, r);
|
||||
return new ConversationRequestItem(text, GROUP, r);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,8 +171,7 @@ class ConversationVisitor implements
|
||||
R.string.groups_invitations_response_declined_sent,
|
||||
contactName.getValue());
|
||||
}
|
||||
return new ConversationNoticeItem(
|
||||
R.layout.list_item_conversation_notice_out, text, r);
|
||||
return new ConversationNoticeOutItem(text, r);
|
||||
} else {
|
||||
String text;
|
||||
if (r.wasAccepted()) {
|
||||
@@ -202,8 +183,7 @@ class ConversationVisitor implements
|
||||
R.string.groups_invitations_response_declined_received,
|
||||
contactName.getValue());
|
||||
}
|
||||
return new ConversationNoticeItem(
|
||||
R.layout.list_item_conversation_notice_in, text, r);
|
||||
return new ConversationNoticeInItem(text, r);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,14 +193,11 @@ class ConversationVisitor implements
|
||||
if (r.isLocal()) {
|
||||
String text = ctx.getString(R.string.introduction_request_sent,
|
||||
contactName.getValue(), name);
|
||||
return new ConversationNoticeItem(
|
||||
R.layout.list_item_conversation_notice_out, text, r);
|
||||
return new ConversationNoticeOutItem(text, r);
|
||||
} else {
|
||||
String text = ctx.getString(R.string.introduction_request_received,
|
||||
contactName.getValue(), name);
|
||||
return new ConversationRequestItem(
|
||||
R.layout.list_item_conversation_request, text, INTRODUCTION,
|
||||
r);
|
||||
return new ConversationRequestItem(text, INTRODUCTION, r);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,8 +220,7 @@ class ConversationVisitor implements
|
||||
R.string.introduction_response_declined_sent,
|
||||
introducedAuthor);
|
||||
}
|
||||
return new ConversationNoticeItem(
|
||||
R.layout.list_item_conversation_notice_out, text, r);
|
||||
return new ConversationNoticeOutItem(text, r);
|
||||
} else {
|
||||
String text;
|
||||
if (r.wasAccepted()) {
|
||||
@@ -263,8 +239,7 @@ class ConversationVisitor implements
|
||||
contactName.getValue(),
|
||||
introducedAuthor);
|
||||
}
|
||||
return new ConversationNoticeItem(
|
||||
R.layout.list_item_conversation_notice_in, text, r);
|
||||
return new ConversationNoticeInItem(text, r);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
package org.briarproject.briar.android.conversation;
|
||||
|
||||
import android.support.annotation.LayoutRes;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.briar.api.conversation.ConversationMessageHeader;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
@NotThreadSafe
|
||||
@NotNullByDefault
|
||||
abstract class ConversationItem {
|
||||
|
||||
@LayoutRes
|
||||
private final int layoutRes;
|
||||
@Nullable
|
||||
protected String text;
|
||||
private final MessageId id;
|
||||
private final GroupId groupId;
|
||||
private final long time;
|
||||
private final boolean isIncoming;
|
||||
private boolean read, sent, seen;
|
||||
|
||||
ConversationItem(@LayoutRes int layoutRes, ConversationMessageHeader h) {
|
||||
this.layoutRes = layoutRes;
|
||||
this.text = null;
|
||||
this.id = h.getId();
|
||||
this.groupId = h.getGroupId();
|
||||
this.time = h.getTimestamp();
|
||||
this.read = h.isRead();
|
||||
this.sent = h.isSent();
|
||||
this.seen = h.isSeen();
|
||||
this.isIncoming = !h.isLocal();
|
||||
}
|
||||
|
||||
@LayoutRes
|
||||
int getLayout() {
|
||||
return layoutRes;
|
||||
}
|
||||
|
||||
MessageId getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
GroupId getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only useful for incoming messages.
|
||||
*/
|
||||
boolean isRead() {
|
||||
return read;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only useful for outgoing messages.
|
||||
*/
|
||||
boolean isSent() {
|
||||
return sent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only useful for outgoing messages.
|
||||
*/
|
||||
void setSent(boolean sent) {
|
||||
this.sent = sent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only useful for outgoing messages.
|
||||
*/
|
||||
boolean isSeen() {
|
||||
return seen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only useful for outgoing messages.
|
||||
*/
|
||||
void setSeen(boolean seen) {
|
||||
this.seen = seen;
|
||||
}
|
||||
|
||||
boolean isIncoming() {
|
||||
return isIncoming;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
package org.briarproject.briar.android.conversation;
|
||||
|
||||
import android.support.annotation.CallSuper;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.support.v7.widget.RecyclerView.ViewHolder;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.briar.R;
|
||||
|
||||
import static org.briarproject.bramble.util.StringUtils.trim;
|
||||
import static org.briarproject.briar.android.util.UiUtils.formatDate;
|
||||
|
||||
@UiThread
|
||||
@NotNullByDefault
|
||||
abstract class ConversationItemViewHolder extends ViewHolder {
|
||||
|
||||
protected final ViewGroup layout;
|
||||
@Nullable
|
||||
private final OutItemViewHolder outViewHolder;
|
||||
private final TextView text;
|
||||
private final TextView time;
|
||||
|
||||
ConversationItemViewHolder(View v, boolean isIncoming) {
|
||||
super(v);
|
||||
this.outViewHolder = isIncoming ? null : new OutItemViewHolder(v);
|
||||
layout = v.findViewById(R.id.layout);
|
||||
text = v.findViewById(R.id.text);
|
||||
time = v.findViewById(R.id.time);
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
void bind(ConversationItem item, ConversationListener listener) {
|
||||
if (item.getText() != null) {
|
||||
text.setText(trim(item.getText()));
|
||||
}
|
||||
|
||||
long timestamp = item.getTime();
|
||||
time.setText(formatDate(time.getContext(), timestamp));
|
||||
|
||||
if (outViewHolder != null) outViewHolder.bind(item);
|
||||
}
|
||||
|
||||
boolean isIncoming() {
|
||||
return outViewHolder == null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package org.briarproject.briar.android.conversation;
|
||||
|
||||
import android.support.annotation.UiThread;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
@UiThread
|
||||
@NotNullByDefault
|
||||
interface ConversationListener {
|
||||
|
||||
void onItemVisible(ConversationItem item);
|
||||
|
||||
void respondToRequest(ConversationRequestItem item, boolean accept);
|
||||
|
||||
void openRequestedShareable(ConversationRequestItem item);
|
||||
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package org.briarproject.briar.android.conversation;
|
||||
|
||||
import android.support.annotation.LayoutRes;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.briar.api.messaging.AttachmentHeader;
|
||||
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
@NotThreadSafe
|
||||
@NotNullByDefault
|
||||
class ConversationMessageItem extends ConversationItem {
|
||||
|
||||
private final List<AttachmentHeader> attachments;
|
||||
|
||||
ConversationMessageItem(@LayoutRes int layoutRes, PrivateMessageHeader h) {
|
||||
super(layoutRes, h);
|
||||
this.attachments = h.getAttachmentHeaders();
|
||||
}
|
||||
|
||||
List<AttachmentHeader> getAttachments() {
|
||||
return attachments;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package org.briarproject.briar.android.conversation;
|
||||
|
||||
import android.support.annotation.UiThread;
|
||||
import android.view.View;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
@UiThread
|
||||
@NotNullByDefault
|
||||
class ConversationMessageViewHolder extends ConversationItemViewHolder {
|
||||
|
||||
// image support will be added here (#1242)
|
||||
|
||||
ConversationMessageViewHolder(View v, boolean isIncoming) {
|
||||
super(v, isIncoming);
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user