mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-24 16:49:55 +01:00
Compare commits
1 Commits
beta-2017-
...
752-780-ac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5734f90f7 |
@@ -18,7 +18,6 @@ import org.briarproject.bramble.api.keyagreement.KeyAgreementListener;
|
|||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.Backoff;
|
import org.briarproject.bramble.api.plugin.Backoff;
|
||||||
import org.briarproject.bramble.api.plugin.PluginException;
|
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
|
||||||
@@ -129,7 +128,7 @@ class DroidtoothPlugin implements DuplexPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() throws PluginException {
|
public boolean start() throws IOException {
|
||||||
if (used.getAndSet(true)) throw new IllegalStateException();
|
if (used.getAndSet(true)) throw new IllegalStateException();
|
||||||
// BluetoothAdapter.getDefaultAdapter() must be called on a thread
|
// BluetoothAdapter.getDefaultAdapter() must be called on a thread
|
||||||
// with a message queue, so submit it to the AndroidExecutor
|
// with a message queue, so submit it to the AndroidExecutor
|
||||||
@@ -143,14 +142,13 @@ class DroidtoothPlugin implements DuplexPlugin {
|
|||||||
}).get();
|
}).get();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
LOG.warning("Interrupted while getting BluetoothAdapter");
|
throw new IOException("Interrupted while getting BluetoothAdapter");
|
||||||
throw new PluginException(e);
|
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
throw new PluginException(e);
|
throw new IOException(e);
|
||||||
}
|
}
|
||||||
if (adapter == null) {
|
if (adapter == null) {
|
||||||
LOG.info("Bluetooth is not supported");
|
LOG.info("Bluetooth is not supported");
|
||||||
throw new PluginException();
|
return false;
|
||||||
}
|
}
|
||||||
running = true;
|
running = true;
|
||||||
// Listen for changes to the Bluetooth state
|
// Listen for changes to the Bluetooth state
|
||||||
@@ -172,6 +170,7 @@ class DroidtoothPlugin implements DuplexPlugin {
|
|||||||
LOG.info("Not enabling Bluetooth");
|
LOG.info("Not enabling Bluetooth");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bind() {
|
private void bind() {
|
||||||
|
|||||||
@@ -39,13 +39,14 @@ class AndroidLanTcpPlugin extends LanTcpPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public boolean start() {
|
||||||
if (used.getAndSet(true)) throw new IllegalStateException();
|
if (used.getAndSet(true)) throw new IllegalStateException();
|
||||||
running = true;
|
running = true;
|
||||||
// Register to receive network status events
|
// Register to receive network status events
|
||||||
networkStateReceiver = new NetworkStateReceiver();
|
networkStateReceiver = new NetworkStateReceiver();
|
||||||
IntentFilter filter = new IntentFilter(CONNECTIVITY_ACTION);
|
IntentFilter filter = new IntentFilter(CONNECTIVITY_ACTION);
|
||||||
appContext.registerReceiver(networkStateReceiver, filter);
|
appContext.registerReceiver(networkStateReceiver, filter);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import org.briarproject.bramble.api.keyagreement.KeyAgreementListener;
|
|||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.Backoff;
|
import org.briarproject.bramble.api.plugin.Backoff;
|
||||||
import org.briarproject.bramble.api.plugin.PluginException;
|
|
||||||
import org.briarproject.bramble.api.plugin.TorConstants;
|
import org.briarproject.bramble.api.plugin.TorConstants;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
||||||
@@ -163,18 +162,14 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() throws PluginException {
|
public boolean start() throws IOException {
|
||||||
if (used.getAndSet(true)) throw new IllegalStateException();
|
if (used.getAndSet(true)) throw new IllegalStateException();
|
||||||
// Install or update the assets if necessary
|
// Install or update the assets if necessary
|
||||||
if (!assetsAreUpToDate()) installAssets();
|
if (!assetsAreUpToDate()) installAssets();
|
||||||
LOG.info("Starting Tor");
|
LOG.info("Starting Tor");
|
||||||
// Watch for the auth cookie file being updated
|
// Watch for the auth cookie file being updated
|
||||||
try {
|
cookieFile.getParentFile().mkdirs();
|
||||||
cookieFile.getParentFile().mkdirs();
|
cookieFile.createNewFile();
|
||||||
cookieFile.createNewFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new PluginException(e);
|
|
||||||
}
|
|
||||||
CountDownLatch latch = new CountDownLatch(1);
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
FileObserver obs = new WriteObserver(cookieFile, latch);
|
FileObserver obs = new WriteObserver(cookieFile, latch);
|
||||||
obs.startWatching();
|
obs.startWatching();
|
||||||
@@ -187,8 +182,8 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
Process torProcess;
|
Process torProcess;
|
||||||
try {
|
try {
|
||||||
torProcess = Runtime.getRuntime().exec(cmd, env, torDirectory);
|
torProcess = Runtime.getRuntime().exec(cmd, env, torDirectory);
|
||||||
} catch (SecurityException | IOException e) {
|
} catch (SecurityException e) {
|
||||||
throw new PluginException(e);
|
throw new IOException(e);
|
||||||
}
|
}
|
||||||
// Log the process's standard output until it detaches
|
// Log the process's standard output until it detaches
|
||||||
if (LOG.isLoggable(INFO)) {
|
if (LOG.isLoggable(INFO)) {
|
||||||
@@ -202,39 +197,35 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
if (exit != 0) {
|
if (exit != 0) {
|
||||||
if (LOG.isLoggable(WARNING))
|
if (LOG.isLoggable(WARNING))
|
||||||
LOG.warning("Tor exited with value " + exit);
|
LOG.warning("Tor exited with value " + exit);
|
||||||
throw new PluginException();
|
return false;
|
||||||
}
|
}
|
||||||
// Wait for the auth cookie file to be created/updated
|
// Wait for the auth cookie file to be created/updated
|
||||||
if (!latch.await(COOKIE_TIMEOUT, MILLISECONDS)) {
|
if (!latch.await(COOKIE_TIMEOUT, MILLISECONDS)) {
|
||||||
LOG.warning("Auth cookie not created");
|
LOG.warning("Auth cookie not created");
|
||||||
if (LOG.isLoggable(INFO)) listFiles(torDirectory);
|
if (LOG.isLoggable(INFO)) listFiles(torDirectory);
|
||||||
throw new PluginException();
|
return false;
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
LOG.warning("Interrupted while starting Tor");
|
LOG.warning("Interrupted while starting Tor");
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
throw new PluginException();
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
// Open a control connection and authenticate using the cookie file
|
||||||
// Open a control connection and authenticate using the cookie file
|
controlSocket = new Socket("127.0.0.1", CONTROL_PORT);
|
||||||
controlSocket = new Socket("127.0.0.1", CONTROL_PORT);
|
controlConnection = new TorControlConnection(controlSocket);
|
||||||
controlConnection = new TorControlConnection(controlSocket);
|
controlConnection.authenticate(read(cookieFile));
|
||||||
controlConnection.authenticate(read(cookieFile));
|
// Tell Tor to exit when the control connection is closed
|
||||||
// Tell Tor to exit when the control connection is closed
|
controlConnection.takeOwnership();
|
||||||
controlConnection.takeOwnership();
|
controlConnection.resetConf(Collections.singletonList(OWNER));
|
||||||
controlConnection.resetConf(Collections.singletonList(OWNER));
|
running = true;
|
||||||
running = true;
|
// Register to receive events from the Tor process
|
||||||
// Register to receive events from the Tor process
|
controlConnection.setEventHandler(this);
|
||||||
controlConnection.setEventHandler(this);
|
controlConnection.setEvents(Arrays.asList(EVENTS));
|
||||||
controlConnection.setEvents(Arrays.asList(EVENTS));
|
// Check whether Tor has already bootstrapped
|
||||||
// Check whether Tor has already bootstrapped
|
String phase = controlConnection.getInfo("status/bootstrap-phase");
|
||||||
String phase = controlConnection.getInfo("status/bootstrap-phase");
|
if (phase != null && phase.contains("PROGRESS=100")) {
|
||||||
if (phase != null && phase.contains("PROGRESS=100")) {
|
LOG.info("Tor has already bootstrapped");
|
||||||
LOG.info("Tor has already bootstrapped");
|
connectionStatus.setBootstrapped();
|
||||||
connectionStatus.setBootstrapped();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new PluginException(e);
|
|
||||||
}
|
}
|
||||||
// Register to receive network status events
|
// Register to receive network status events
|
||||||
networkStateReceiver = new NetworkStateReceiver();
|
networkStateReceiver = new NetworkStateReceiver();
|
||||||
@@ -242,6 +233,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
appContext.registerReceiver(networkStateReceiver, filter);
|
appContext.registerReceiver(networkStateReceiver, filter);
|
||||||
// Bind a server socket to receive incoming hidden service connections
|
// Bind a server socket to receive incoming hidden service connections
|
||||||
bind();
|
bind();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean assetsAreUpToDate() {
|
private boolean assetsAreUpToDate() {
|
||||||
@@ -254,7 +246,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void installAssets() throws PluginException {
|
private void installAssets() throws IOException {
|
||||||
InputStream in = null;
|
InputStream in = null;
|
||||||
OutputStream out = null;
|
OutputStream out = null;
|
||||||
try {
|
try {
|
||||||
@@ -277,7 +269,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
tryToClose(in);
|
tryToClose(in);
|
||||||
tryToClose(out);
|
tryToClose(out);
|
||||||
throw new PluginException(e);
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -484,7 +476,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop() throws PluginException {
|
public void stop() throws IOException {
|
||||||
running = false;
|
running = false;
|
||||||
tryToClose(socket);
|
tryToClose(socket);
|
||||||
if (networkStateReceiver != null)
|
if (networkStateReceiver != null)
|
||||||
|
|||||||
@@ -8,34 +8,15 @@ dependencies {
|
|||||||
compile "com.google.dagger:dagger:2.0.2"
|
compile "com.google.dagger:dagger:2.0.2"
|
||||||
compile 'com.google.dagger:dagger-compiler:2.0.2'
|
compile 'com.google.dagger:dagger-compiler:2.0.2'
|
||||||
compile 'com.google.code.findbugs:jsr305:3.0.1'
|
compile 'com.google.code.findbugs:jsr305:3.0.1'
|
||||||
|
|
||||||
testCompile 'junit:junit:4.12'
|
|
||||||
testCompile "org.jmock:jmock:2.8.1"
|
|
||||||
testCompile "org.jmock:jmock-junit4:2.8.1"
|
|
||||||
testCompile "org.jmock:jmock-legacy:2.8.1"
|
|
||||||
testCompile "org.hamcrest:hamcrest-library:1.3"
|
|
||||||
testCompile "org.hamcrest:hamcrest-core:1.3"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencyVerification {
|
dependencyVerification {
|
||||||
verify = [
|
verify = [
|
||||||
'com.google.dagger:dagger:84c0282ed8be73a29e0475d639da030b55dee72369e58dd35ae7d4fe6243dcf9',
|
'com.google.dagger:dagger:84c0282ed8be73a29e0475d639da030b55dee72369e58dd35ae7d4fe6243dcf9',
|
||||||
'com.google.dagger:dagger-compiler:b74bc9de063dd4c6400b232231f2ef5056145b8fbecbf5382012007dd1c071b3',
|
'com.google.dagger:dagger-compiler:b74bc9de063dd4c6400b232231f2ef5056145b8fbecbf5382012007dd1c071b3',
|
||||||
'com.google.code.findbugs:jsr305:c885ce34249682bc0236b4a7d56efcc12048e6135a5baf7a9cde8ad8cda13fcd',
|
|
||||||
'javax.inject:javax.inject:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
'javax.inject:javax.inject:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||||
'com.google.dagger:dagger-producers:99ec15e8a0507ba569e7655bc1165ee5e5ca5aa914b3c8f7e2c2458f724edd6b',
|
'com.google.dagger:dagger-producers:99ec15e8a0507ba569e7655bc1165ee5e5ca5aa914b3c8f7e2c2458f724edd6b',
|
||||||
'com.google.guava:guava:d664fbfc03d2e5ce9cab2a44fb01f1d0bf9dfebeccc1a473b1f9ea31f79f6f99',
|
'com.google.guava:guava:d664fbfc03d2e5ce9cab2a44fb01f1d0bf9dfebeccc1a473b1f9ea31f79f6f99',
|
||||||
|
'com.google.code.findbugs:jsr305:c885ce34249682bc0236b4a7d56efcc12048e6135a5baf7a9cde8ad8cda13fcd'
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
// needed to make test output available to bramble-core and briar-core
|
|
||||||
configurations {
|
|
||||||
testOutput.extendsFrom(testCompile)
|
|
||||||
}
|
|
||||||
task jarTest(type: Jar, dependsOn: testClasses) {
|
|
||||||
from sourceSets.test.output
|
|
||||||
classifier = 'test'
|
|
||||||
}
|
|
||||||
artifacts {
|
|
||||||
testOutput jarTest
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -43,24 +43,6 @@ public interface ContactManager {
|
|||||||
*/
|
*/
|
||||||
Contact getContact(ContactId c) throws DbException;
|
Contact getContact(ContactId c) throws DbException;
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the contact with the given remoteAuthorId
|
|
||||||
* that was added by the LocalAuthor with the given localAuthorId
|
|
||||||
*
|
|
||||||
* @throws org.briarproject.bramble.api.db.NoSuchContactException
|
|
||||||
*/
|
|
||||||
Contact getContact(AuthorId remoteAuthorId, AuthorId localAuthorId)
|
|
||||||
throws DbException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the contact with the given remoteAuthorId
|
|
||||||
* that was added by the LocalAuthor with the given localAuthorId
|
|
||||||
*
|
|
||||||
* @throws org.briarproject.bramble.api.db.NoSuchContactException
|
|
||||||
*/
|
|
||||||
Contact getContact(Transaction txn, AuthorId remoteAuthorId,
|
|
||||||
AuthorId localAuthorId) throws DbException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all active contacts.
|
* Returns all active contacts.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.briarproject.bramble.api.plugin;
|
|||||||
import org.briarproject.bramble.api.contact.ContactId;
|
import org.briarproject.bramble.api.contact.ContactId;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
@@ -24,14 +25,14 @@ public interface Plugin {
|
|||||||
int getMaxIdleTime();
|
int getMaxIdleTime();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts the plugin.
|
* Starts the plugin and returns true if it started successfully.
|
||||||
*/
|
*/
|
||||||
void start() throws PluginException;
|
boolean start() throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops the plugin.
|
* Stops the plugin.
|
||||||
*/
|
*/
|
||||||
void stop() throws PluginException;
|
void stop() throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the plugin is running.
|
* Returns true if the plugin is running.
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
package org.briarproject.bramble.api.plugin;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An exception that indicates an error starting or stopping a {@link Plugin}.
|
|
||||||
*/
|
|
||||||
public class PluginException extends Exception {
|
|
||||||
|
|
||||||
public PluginException() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public PluginException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,7 @@ package org.briarproject.bramble.api.sync;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A record acknowledging receipt of one or more {@link Message Messages}.
|
* A packet acknowledging receipt of one or more {@link Message Messages}.
|
||||||
*/
|
*/
|
||||||
public class Ack {
|
public class Ack {
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package org.briarproject.bramble.api.sync;
|
package org.briarproject.bramble.api.sync;
|
||||||
|
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
|
|
||||||
|
|
||||||
public class Group {
|
public class Group {
|
||||||
|
|
||||||
public enum Visibility {
|
public enum Visibility {
|
||||||
@@ -15,8 +13,6 @@ public class Group {
|
|||||||
private final byte[] descriptor;
|
private final byte[] descriptor;
|
||||||
|
|
||||||
public Group(GroupId id, ClientId clientId, byte[] descriptor) {
|
public Group(GroupId id, ClientId clientId, byte[] descriptor) {
|
||||||
if (descriptor.length > MAX_GROUP_DESCRIPTOR_LENGTH)
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.clientId = clientId;
|
this.clientId = clientId;
|
||||||
this.descriptor = descriptor;
|
this.descriptor = descriptor;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package org.briarproject.bramble.api.sync;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A record offering the recipient one or more {@link Message Messages}.
|
* A packet offering the recipient one or more {@link Message Messages}.
|
||||||
*/
|
*/
|
||||||
public class Offer {
|
public class Offer {
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public interface RecordReader {
|
public interface PacketReader {
|
||||||
|
|
||||||
boolean eof() throws IOException;
|
boolean eof() throws IOException;
|
||||||
|
|
||||||
@@ -24,5 +24,4 @@ public interface RecordReader {
|
|||||||
boolean hasRequest() throws IOException;
|
boolean hasRequest() throws IOException;
|
||||||
|
|
||||||
Request readRequest() throws IOException;
|
Request readRequest() throws IOException;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public interface RecordReaderFactory {
|
public interface PacketReaderFactory {
|
||||||
|
|
||||||
RecordReader createRecordReader(InputStream in);
|
PacketReader createPacketReader(InputStream in);
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
package org.briarproject.bramble.api.sync;
|
package org.briarproject.bramble.api.sync;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Record types for the sync protocol.
|
* Packet types for the sync protocol.
|
||||||
*/
|
*/
|
||||||
public interface RecordTypes {
|
public interface PacketTypes {
|
||||||
|
|
||||||
byte ACK = 0;
|
byte ACK = 0;
|
||||||
byte MESSAGE = 1;
|
byte MESSAGE = 1;
|
||||||
byte OFFER = 2;
|
byte OFFER = 2;
|
||||||
byte REQUEST = 3;
|
byte REQUEST = 3;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public interface RecordWriter {
|
public interface PacketWriter {
|
||||||
|
|
||||||
void writeAck(Ack a) throws IOException;
|
void writeAck(Ack a) throws IOException;
|
||||||
|
|
||||||
@@ -5,7 +5,7 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public interface RecordWriterFactory {
|
public interface PacketWriterFactory {
|
||||||
|
|
||||||
RecordWriter createRecordWriter(OutputStream out);
|
PacketWriter createPacketWriter(OutputStream out);
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@ package org.briarproject.bramble.api.sync;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A record requesting one or more {@link Message Messages} from the recipient.
|
* A packet requesting one or more {@link Message Messages} from the recipient.
|
||||||
*/
|
*/
|
||||||
public class Request {
|
public class Request {
|
||||||
|
|
||||||
|
|||||||
@@ -10,17 +10,19 @@ public interface SyncConstants {
|
|||||||
byte PROTOCOL_VERSION = 0;
|
byte PROTOCOL_VERSION = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The length of the record header in bytes.
|
* The length of the packet header in bytes.
|
||||||
*/
|
*/
|
||||||
int RECORD_HEADER_LENGTH = 4;
|
int PACKET_HEADER_LENGTH = 4;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum length of the record payload in bytes.
|
* The maximum length of the packet payload in bytes.
|
||||||
*/
|
*/
|
||||||
int MAX_RECORD_PAYLOAD_LENGTH = 48 * 1024; // 48 KiB
|
int MAX_PACKET_PAYLOAD_LENGTH = 32 * 1024; // 32 KiB
|
||||||
|
|
||||||
/** The maximum length of a group descriptor in bytes. */
|
/**
|
||||||
int MAX_GROUP_DESCRIPTOR_LENGTH = 16 * 1024; // 16 KiB
|
* The maximum length of a message in bytes.
|
||||||
|
*/
|
||||||
|
int MAX_MESSAGE_LENGTH = MAX_PACKET_PAYLOAD_LENGTH - PACKET_HEADER_LENGTH;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The length of the message header in bytes.
|
* The length of the message header in bytes.
|
||||||
@@ -30,15 +32,10 @@ public interface SyncConstants {
|
|||||||
/**
|
/**
|
||||||
* The maximum length of a message body in bytes.
|
* The maximum length of a message body in bytes.
|
||||||
*/
|
*/
|
||||||
int MAX_MESSAGE_BODY_LENGTH = 32 * 1024; // 32 KiB
|
int MAX_MESSAGE_BODY_LENGTH = MAX_MESSAGE_LENGTH - MESSAGE_HEADER_LENGTH;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum length of a message in bytes.
|
* The maximum number of message IDs in an ack, offer or request packet.
|
||||||
*/
|
*/
|
||||||
int MAX_MESSAGE_LENGTH = MESSAGE_HEADER_LENGTH + MAX_MESSAGE_BODY_LENGTH;
|
int MAX_MESSAGE_IDS = MAX_PACKET_PAYLOAD_LENGTH / UniqueId.LENGTH;
|
||||||
|
|
||||||
/**
|
|
||||||
* The maximum number of message IDs in an ack, offer or request record.
|
|
||||||
*/
|
|
||||||
int MAX_MESSAGE_IDS = MAX_RECORD_PAYLOAD_LENGTH / UniqueId.LENGTH;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import java.io.IOException;
|
|||||||
public interface SyncSession {
|
public interface SyncSession {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs the session. This method returns when there are no more records to
|
* Runs the session. This method returns when there are no more packets to
|
||||||
* send or receive, or when the {@link #interrupt()} method has been called.
|
* send or receive, or when the {@link #interrupt()} method has been called.
|
||||||
*/
|
*/
|
||||||
void run() throws IOException;
|
void run() throws IOException;
|
||||||
|
|||||||
1
bramble-core/.gitignore
vendored
1
bramble-core/.gitignore
vendored
@@ -1,4 +1,3 @@
|
|||||||
bin
|
bin
|
||||||
build
|
build
|
||||||
test.tmp
|
|
||||||
.settings
|
.settings
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
plugins {
|
apply plugin: 'java'
|
||||||
id "java"
|
|
||||||
id "net.ltgt.apt" version "0.9"
|
|
||||||
id "idea"
|
|
||||||
}
|
|
||||||
sourceCompatibility = 1.6
|
sourceCompatibility = 1.6
|
||||||
targetCompatibility = 1.6
|
targetCompatibility = 1.6
|
||||||
|
|
||||||
@@ -13,8 +9,6 @@ dependencies {
|
|||||||
compile fileTree(dir: 'libs', include: '*.jar')
|
compile fileTree(dir: 'libs', include: '*.jar')
|
||||||
compile 'com.madgag.spongycastle:core:1.54.0.0'
|
compile 'com.madgag.spongycastle:core:1.54.0.0'
|
||||||
compile 'com.h2database:h2:1.4.190'
|
compile 'com.h2database:h2:1.4.190'
|
||||||
|
|
||||||
testCompile project(path: ':bramble-api', configuration: 'testOutput')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencyVerification {
|
dependencyVerification {
|
||||||
@@ -23,15 +17,3 @@ dependencyVerification {
|
|||||||
'com.h2database:h2:23ba495a07bbbb3bd6c3084d10a96dad7a23741b8b6d64b213459a784195a98c'
|
'com.h2database:h2:23ba495a07bbbb3bd6c3084d10a96dad7a23741b8b6d64b213459a784195a98c'
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
// needed to make test output available to bramble-j2se
|
|
||||||
configurations {
|
|
||||||
testOutput.extendsFrom(testCompile)
|
|
||||||
}
|
|
||||||
task jarTest(type: Jar, dependsOn: testClasses) {
|
|
||||||
from sourceSets.test.output
|
|
||||||
classifier = 'test'
|
|
||||||
}
|
|
||||||
artifacts {
|
|
||||||
testOutput jarTest
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import org.briarproject.bramble.api.contact.ContactManager;
|
|||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.NoSuchContactException;
|
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
import org.briarproject.bramble.api.identity.AuthorId;
|
import org.briarproject.bramble.api.identity.AuthorId;
|
||||||
@@ -89,32 +88,6 @@ class ContactManagerImpl implements ContactManager {
|
|||||||
return contact;
|
return contact;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Contact getContact(AuthorId remoteAuthorId, AuthorId localAuthorId)
|
|
||||||
throws DbException {
|
|
||||||
Transaction txn = db.startTransaction(true);
|
|
||||||
try {
|
|
||||||
Contact c = getContact(txn, remoteAuthorId, localAuthorId);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
return c;
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Contact getContact(Transaction txn, AuthorId remoteAuthorId,
|
|
||||||
AuthorId localAuthorId) throws DbException {
|
|
||||||
Collection<Contact> contacts =
|
|
||||||
db.getContactsByAuthorId(txn, remoteAuthorId);
|
|
||||||
for (Contact c : contacts) {
|
|
||||||
if (c.getLocalAuthorId().equals(localAuthorId)) {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new NoSuchContactException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Contact> getActiveContacts() throws DbException {
|
public Collection<Contact> getActiveContacts() throws DbException {
|
||||||
Collection<Contact> contacts;
|
Collection<Contact> contacts;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ class KeyAgreementProtocol {
|
|||||||
|
|
||||||
void connectionWaiting();
|
void connectionWaiting();
|
||||||
|
|
||||||
void initialRecordReceived();
|
void initialPacketReceived();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Callbacks callbacks;
|
private final Callbacks callbacks;
|
||||||
@@ -117,7 +117,7 @@ class KeyAgreementProtocol {
|
|||||||
|
|
||||||
private byte[] receiveKey() throws AbortException {
|
private byte[] receiveKey() throws AbortException {
|
||||||
byte[] publicKey = transport.receiveKey();
|
byte[] publicKey = transport.receiveKey();
|
||||||
callbacks.initialRecordReceived();
|
callbacks.initialPacketReceived();
|
||||||
byte[] expected = crypto.deriveKeyCommitment(publicKey);
|
byte[] expected = crypto.deriveKeyCommitment(publicKey);
|
||||||
if (!Arrays.equals(expected, theirPayload.getCommitment()))
|
if (!Arrays.equals(expected, theirPayload.getCommitment()))
|
||||||
throw new AbortException();
|
throw new AbortException();
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ class KeyAgreementTaskImpl extends Thread implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialRecordReceived() {
|
public void initialPacketReceived() {
|
||||||
// We send this here instead of when we create the protocol, so that
|
// We send this here instead of when we create the protocol, so that
|
||||||
// if device A makes a connection after getting device B's payload and
|
// if device A makes a connection after getting device B's payload and
|
||||||
// starts its protocol, device A's UI doesn't change to prevent device B
|
// starts its protocol, device A's UI doesn't change to prevent device B
|
||||||
|
|||||||
@@ -95,30 +95,20 @@ class KeyAgreementTransport {
|
|||||||
out.flush();
|
out.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] readRecord(byte expectedType) throws AbortException {
|
private byte[] readRecord(byte type) throws AbortException {
|
||||||
while (true) {
|
byte[] header = readHeader();
|
||||||
byte[] header = readHeader();
|
if (header[0] != PROTOCOL_VERSION)
|
||||||
byte version = header[0], type = header[1];
|
throw new AbortException(); // TODO handle?
|
||||||
int len = ByteUtils.readUint16(header,
|
if (header[1] != type) {
|
||||||
RECORD_HEADER_PAYLOAD_LENGTH_OFFSET);
|
// Unexpected packet
|
||||||
// Reject unrecognised protocol version
|
throw new AbortException(header[1] == ABORT);
|
||||||
if (version != PROTOCOL_VERSION) throw new AbortException(false);
|
}
|
||||||
if (type == ABORT) throw new AbortException(true);
|
int len = ByteUtils.readUint16(header,
|
||||||
if (type == expectedType) {
|
RECORD_HEADER_PAYLOAD_LENGTH_OFFSET);
|
||||||
try {
|
try {
|
||||||
return readData(len);
|
return readData(len);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new AbortException(e);
|
throw new AbortException(e);
|
||||||
}
|
|
||||||
}
|
|
||||||
// Reject recognised but unexpected record type
|
|
||||||
if (type == KEY || type == CONFIRM) throw new AbortException(false);
|
|
||||||
// Skip unrecognised record type
|
|
||||||
try {
|
|
||||||
readData(len);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new AbortException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import org.briarproject.bramble.api.plugin.ConnectionManager;
|
|||||||
import org.briarproject.bramble.api.plugin.Plugin;
|
import org.briarproject.bramble.api.plugin.Plugin;
|
||||||
import org.briarproject.bramble.api.plugin.PluginCallback;
|
import org.briarproject.bramble.api.plugin.PluginCallback;
|
||||||
import org.briarproject.bramble.api.plugin.PluginConfig;
|
import org.briarproject.bramble.api.plugin.PluginConfig;
|
||||||
import org.briarproject.bramble.api.plugin.PluginException;
|
|
||||||
import org.briarproject.bramble.api.plugin.PluginManager;
|
import org.briarproject.bramble.api.plugin.PluginManager;
|
||||||
import org.briarproject.bramble.api.plugin.TransportConnectionReader;
|
import org.briarproject.bramble.api.plugin.TransportConnectionReader;
|
||||||
import org.briarproject.bramble.api.plugin.TransportConnectionWriter;
|
import org.briarproject.bramble.api.plugin.TransportConnectionWriter;
|
||||||
@@ -31,6 +30,7 @@ import org.briarproject.bramble.api.settings.Settings;
|
|||||||
import org.briarproject.bramble.api.settings.SettingsManager;
|
import org.briarproject.bramble.api.settings.SettingsManager;
|
||||||
import org.briarproject.bramble.api.ui.UiCallback;
|
import org.briarproject.bramble.api.ui.UiCallback;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -193,17 +193,24 @@ class PluginManagerImpl implements PluginManager, Service {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
long start = System.currentTimeMillis();
|
try {
|
||||||
plugin.start();
|
long start = System.currentTimeMillis();
|
||||||
long duration = System.currentTimeMillis() - start;
|
boolean started = plugin.start();
|
||||||
if (LOG.isLoggable(INFO)) {
|
long duration = System.currentTimeMillis() - start;
|
||||||
LOG.info("Starting plugin " + plugin.getId() + " took " +
|
if (started) {
|
||||||
duration + " ms");
|
if (LOG.isLoggable(INFO)) {
|
||||||
}
|
LOG.info("Starting plugin " + plugin.getId()
|
||||||
} catch (PluginException e) {
|
+ " took " + duration + " ms");
|
||||||
if (LOG.isLoggable(WARNING)) {
|
}
|
||||||
LOG.warning("Plugin " + plugin.getId() + " did not start");
|
} else {
|
||||||
LOG.log(WARNING, e.toString(), e);
|
if (LOG.isLoggable(WARNING)) {
|
||||||
|
LOG.warning("Plugin" + plugin.getId()
|
||||||
|
+ " did not start");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (LOG.isLoggable(WARNING))
|
||||||
|
LOG.log(WARNING, e.toString(), e);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
startLatch.countDown();
|
startLatch.countDown();
|
||||||
@@ -239,13 +246,10 @@ class PluginManagerImpl implements PluginManager, Service {
|
|||||||
+ " took " + duration + " ms");
|
+ " took " + duration + " ms");
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
LOG.warning("Interrupted while waiting for plugin to stop");
|
LOG.warning("Interrupted while waiting for plugin to start");
|
||||||
// This task runs on an executor, so don't reset the interrupt
|
// This task runs on an executor, so don't reset the interrupt
|
||||||
} catch (PluginException e) {
|
} catch (IOException e) {
|
||||||
if (LOG.isLoggable(WARNING)) {
|
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||||
LOG.warning("Plugin " + plugin.getId() + " did not stop");
|
|
||||||
LOG.log(WARNING, e.toString(), e);
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
stopLatch.countDown();
|
stopLatch.countDown();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,10 +101,11 @@ abstract class TcpPlugin implements DuplexPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public boolean start() {
|
||||||
if (used.getAndSet(true)) throw new IllegalStateException();
|
if (used.getAndSet(true)) throw new IllegalStateException();
|
||||||
running = true;
|
running = true;
|
||||||
bind();
|
bind();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void bind() {
|
protected void bind() {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import org.briarproject.bramble.api.lifecycle.event.ShutdownEvent;
|
|||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.Ack;
|
import org.briarproject.bramble.api.sync.Ack;
|
||||||
import org.briarproject.bramble.api.sync.Offer;
|
import org.briarproject.bramble.api.sync.Offer;
|
||||||
import org.briarproject.bramble.api.sync.RecordWriter;
|
import org.briarproject.bramble.api.sync.PacketWriter;
|
||||||
import org.briarproject.bramble.api.sync.Request;
|
import org.briarproject.bramble.api.sync.Request;
|
||||||
import org.briarproject.bramble.api.sync.SyncSession;
|
import org.briarproject.bramble.api.sync.SyncSession;
|
||||||
import org.briarproject.bramble.api.sync.event.GroupVisibilityUpdatedEvent;
|
import org.briarproject.bramble.api.sync.event.GroupVisibilityUpdatedEvent;
|
||||||
@@ -37,19 +37,19 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
|||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS;
|
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_RECORD_PAYLOAD_LENGTH;
|
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_PACKET_PAYLOAD_LENGTH;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An outgoing {@link SyncSession} suitable for duplex transports. The session
|
* An outgoing {@link SyncSession} suitable for duplex transports. The session
|
||||||
* offers messages before sending them, keeps its output stream open when there
|
* offers messages before sending them, keeps its output stream open when there
|
||||||
* are no records to send, and reacts to events that make records available to
|
* are no packets to send, and reacts to events that make packets available to
|
||||||
* send.
|
* send.
|
||||||
*/
|
*/
|
||||||
@ThreadSafe
|
@ThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class DuplexOutgoingSession implements SyncSession, EventListener {
|
class DuplexOutgoingSession implements SyncSession, EventListener {
|
||||||
|
|
||||||
// Check for retransmittable records once every 60 seconds
|
// Check for retransmittable packets once every 60 seconds
|
||||||
private static final int RETX_QUERY_INTERVAL = 60 * 1000;
|
private static final int RETX_QUERY_INTERVAL = 60 * 1000;
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(DuplexOutgoingSession.class.getName());
|
Logger.getLogger(DuplexOutgoingSession.class.getName());
|
||||||
@@ -67,14 +67,14 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
|||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
private final ContactId contactId;
|
private final ContactId contactId;
|
||||||
private final int maxLatency, maxIdleTime;
|
private final int maxLatency, maxIdleTime;
|
||||||
private final RecordWriter recordWriter;
|
private final PacketWriter packetWriter;
|
||||||
private final BlockingQueue<ThrowingRunnable<IOException>> writerTasks;
|
private final BlockingQueue<ThrowingRunnable<IOException>> writerTasks;
|
||||||
|
|
||||||
private volatile boolean interrupted = false;
|
private volatile boolean interrupted = false;
|
||||||
|
|
||||||
DuplexOutgoingSession(DatabaseComponent db, Executor dbExecutor,
|
DuplexOutgoingSession(DatabaseComponent db, Executor dbExecutor,
|
||||||
EventBus eventBus, Clock clock, ContactId contactId, int maxLatency,
|
EventBus eventBus, Clock clock, ContactId contactId, int maxLatency,
|
||||||
int maxIdleTime, RecordWriter recordWriter) {
|
int maxIdleTime, PacketWriter packetWriter) {
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.dbExecutor = dbExecutor;
|
this.dbExecutor = dbExecutor;
|
||||||
this.eventBus = eventBus;
|
this.eventBus = eventBus;
|
||||||
@@ -82,7 +82,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
|||||||
this.contactId = contactId;
|
this.contactId = contactId;
|
||||||
this.maxLatency = maxLatency;
|
this.maxLatency = maxLatency;
|
||||||
this.maxIdleTime = maxIdleTime;
|
this.maxIdleTime = maxIdleTime;
|
||||||
this.recordWriter = recordWriter;
|
this.packetWriter = packetWriter;
|
||||||
writerTasks = new LinkedBlockingQueue<ThrowingRunnable<IOException>>();
|
writerTasks = new LinkedBlockingQueue<ThrowingRunnable<IOException>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
|||||||
public void run() throws IOException {
|
public void run() throws IOException {
|
||||||
eventBus.addListener(this);
|
eventBus.addListener(this);
|
||||||
try {
|
try {
|
||||||
// Start a query for each type of record
|
// Start a query for each type of packet
|
||||||
dbExecutor.execute(new GenerateAck());
|
dbExecutor.execute(new GenerateAck());
|
||||||
dbExecutor.execute(new GenerateBatch());
|
dbExecutor.execute(new GenerateBatch());
|
||||||
dbExecutor.execute(new GenerateOffer());
|
dbExecutor.execute(new GenerateOffer());
|
||||||
@@ -100,33 +100,33 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
|||||||
long nextKeepalive = now + maxIdleTime;
|
long nextKeepalive = now + maxIdleTime;
|
||||||
long nextRetxQuery = now + RETX_QUERY_INTERVAL;
|
long nextRetxQuery = now + RETX_QUERY_INTERVAL;
|
||||||
boolean dataToFlush = true;
|
boolean dataToFlush = true;
|
||||||
// Write records until interrupted
|
// Write packets until interrupted
|
||||||
try {
|
try {
|
||||||
while (!interrupted) {
|
while (!interrupted) {
|
||||||
// Work out how long we should wait for a record
|
// Work out how long we should wait for a packet
|
||||||
now = clock.currentTimeMillis();
|
now = clock.currentTimeMillis();
|
||||||
long wait = Math.min(nextKeepalive, nextRetxQuery) - now;
|
long wait = Math.min(nextKeepalive, nextRetxQuery) - now;
|
||||||
if (wait < 0) wait = 0;
|
if (wait < 0) wait = 0;
|
||||||
// Flush any unflushed data if we're going to wait
|
// Flush any unflushed data if we're going to wait
|
||||||
if (wait > 0 && dataToFlush && writerTasks.isEmpty()) {
|
if (wait > 0 && dataToFlush && writerTasks.isEmpty()) {
|
||||||
recordWriter.flush();
|
packetWriter.flush();
|
||||||
dataToFlush = false;
|
dataToFlush = false;
|
||||||
nextKeepalive = now + maxIdleTime;
|
nextKeepalive = now + maxIdleTime;
|
||||||
}
|
}
|
||||||
// Wait for a record
|
// Wait for a packet
|
||||||
ThrowingRunnable<IOException> task = writerTasks.poll(wait,
|
ThrowingRunnable<IOException> task = writerTasks.poll(wait,
|
||||||
MILLISECONDS);
|
MILLISECONDS);
|
||||||
if (task == null) {
|
if (task == null) {
|
||||||
now = clock.currentTimeMillis();
|
now = clock.currentTimeMillis();
|
||||||
if (now >= nextRetxQuery) {
|
if (now >= nextRetxQuery) {
|
||||||
// Check for retransmittable records
|
// Check for retransmittable packets
|
||||||
dbExecutor.execute(new GenerateBatch());
|
dbExecutor.execute(new GenerateBatch());
|
||||||
dbExecutor.execute(new GenerateOffer());
|
dbExecutor.execute(new GenerateOffer());
|
||||||
nextRetxQuery = now + RETX_QUERY_INTERVAL;
|
nextRetxQuery = now + RETX_QUERY_INTERVAL;
|
||||||
}
|
}
|
||||||
if (now >= nextKeepalive) {
|
if (now >= nextKeepalive) {
|
||||||
// Flush the stream to keep it alive
|
// Flush the stream to keep it alive
|
||||||
recordWriter.flush();
|
packetWriter.flush();
|
||||||
dataToFlush = false;
|
dataToFlush = false;
|
||||||
nextKeepalive = now + maxIdleTime;
|
nextKeepalive = now + maxIdleTime;
|
||||||
}
|
}
|
||||||
@@ -137,9 +137,9 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
|||||||
dataToFlush = true;
|
dataToFlush = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dataToFlush) recordWriter.flush();
|
if (dataToFlush) packetWriter.flush();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
LOG.info("Interrupted while waiting for a record to write");
|
LOG.info("Interrupted while waiting for a packet to write");
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@@ -215,7 +215,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
|||||||
@Override
|
@Override
|
||||||
public void run() throws IOException {
|
public void run() throws IOException {
|
||||||
if (interrupted) return;
|
if (interrupted) return;
|
||||||
recordWriter.writeAck(ack);
|
packetWriter.writeAck(ack);
|
||||||
LOG.info("Sent ack");
|
LOG.info("Sent ack");
|
||||||
dbExecutor.execute(new GenerateAck());
|
dbExecutor.execute(new GenerateAck());
|
||||||
}
|
}
|
||||||
@@ -232,7 +232,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
|||||||
Transaction txn = db.startTransaction(false);
|
Transaction txn = db.startTransaction(false);
|
||||||
try {
|
try {
|
||||||
b = db.generateRequestedBatch(txn, contactId,
|
b = db.generateRequestedBatch(txn, contactId,
|
||||||
MAX_RECORD_PAYLOAD_LENGTH, maxLatency);
|
MAX_PACKET_PAYLOAD_LENGTH, maxLatency);
|
||||||
db.commitTransaction(txn);
|
db.commitTransaction(txn);
|
||||||
} finally {
|
} finally {
|
||||||
db.endTransaction(txn);
|
db.endTransaction(txn);
|
||||||
@@ -259,7 +259,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
|||||||
@Override
|
@Override
|
||||||
public void run() throws IOException {
|
public void run() throws IOException {
|
||||||
if (interrupted) return;
|
if (interrupted) return;
|
||||||
for (byte[] raw : batch) recordWriter.writeMessage(raw);
|
for (byte[] raw : batch) packetWriter.writeMessage(raw);
|
||||||
LOG.info("Sent batch");
|
LOG.info("Sent batch");
|
||||||
dbExecutor.execute(new GenerateBatch());
|
dbExecutor.execute(new GenerateBatch());
|
||||||
}
|
}
|
||||||
@@ -303,7 +303,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
|||||||
@Override
|
@Override
|
||||||
public void run() throws IOException {
|
public void run() throws IOException {
|
||||||
if (interrupted) return;
|
if (interrupted) return;
|
||||||
recordWriter.writeOffer(offer);
|
packetWriter.writeOffer(offer);
|
||||||
LOG.info("Sent offer");
|
LOG.info("Sent offer");
|
||||||
dbExecutor.execute(new GenerateOffer());
|
dbExecutor.execute(new GenerateOffer());
|
||||||
}
|
}
|
||||||
@@ -346,7 +346,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
|||||||
@Override
|
@Override
|
||||||
public void run() throws IOException {
|
public void run() throws IOException {
|
||||||
if (interrupted) return;
|
if (interrupted) return;
|
||||||
recordWriter.writeRequest(request);
|
packetWriter.writeRequest(request);
|
||||||
LOG.info("Sent request");
|
LOG.info("Sent request");
|
||||||
dbExecutor.execute(new GenerateRequest());
|
dbExecutor.execute(new GenerateRequest());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|||||||
import org.briarproject.bramble.api.sync.Ack;
|
import org.briarproject.bramble.api.sync.Ack;
|
||||||
import org.briarproject.bramble.api.sync.Message;
|
import org.briarproject.bramble.api.sync.Message;
|
||||||
import org.briarproject.bramble.api.sync.Offer;
|
import org.briarproject.bramble.api.sync.Offer;
|
||||||
import org.briarproject.bramble.api.sync.RecordReader;
|
import org.briarproject.bramble.api.sync.PacketReader;
|
||||||
import org.briarproject.bramble.api.sync.Request;
|
import org.briarproject.bramble.api.sync.Request;
|
||||||
import org.briarproject.bramble.api.sync.SyncSession;
|
import org.briarproject.bramble.api.sync.SyncSession;
|
||||||
|
|
||||||
@@ -42,18 +42,18 @@ class IncomingSession implements SyncSession, EventListener {
|
|||||||
private final Executor dbExecutor;
|
private final Executor dbExecutor;
|
||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
private final ContactId contactId;
|
private final ContactId contactId;
|
||||||
private final RecordReader recordReader;
|
private final PacketReader packetReader;
|
||||||
|
|
||||||
private volatile boolean interrupted = false;
|
private volatile boolean interrupted = false;
|
||||||
|
|
||||||
IncomingSession(DatabaseComponent db, Executor dbExecutor,
|
IncomingSession(DatabaseComponent db, Executor dbExecutor,
|
||||||
EventBus eventBus, ContactId contactId,
|
EventBus eventBus, ContactId contactId,
|
||||||
RecordReader recordReader) {
|
PacketReader packetReader) {
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.dbExecutor = dbExecutor;
|
this.dbExecutor = dbExecutor;
|
||||||
this.eventBus = eventBus;
|
this.eventBus = eventBus;
|
||||||
this.contactId = contactId;
|
this.contactId = contactId;
|
||||||
this.recordReader = recordReader;
|
this.packetReader = packetReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
@IoExecutor
|
@IoExecutor
|
||||||
@@ -61,22 +61,21 @@ class IncomingSession implements SyncSession, EventListener {
|
|||||||
public void run() throws IOException {
|
public void run() throws IOException {
|
||||||
eventBus.addListener(this);
|
eventBus.addListener(this);
|
||||||
try {
|
try {
|
||||||
// Read records until interrupted or EOF
|
// Read packets until interrupted or EOF
|
||||||
while (!interrupted && !recordReader.eof()) {
|
while (!interrupted && !packetReader.eof()) {
|
||||||
if (recordReader.hasAck()) {
|
if (packetReader.hasAck()) {
|
||||||
Ack a = recordReader.readAck();
|
Ack a = packetReader.readAck();
|
||||||
dbExecutor.execute(new ReceiveAck(a));
|
dbExecutor.execute(new ReceiveAck(a));
|
||||||
} else if (recordReader.hasMessage()) {
|
} else if (packetReader.hasMessage()) {
|
||||||
Message m = recordReader.readMessage();
|
Message m = packetReader.readMessage();
|
||||||
dbExecutor.execute(new ReceiveMessage(m));
|
dbExecutor.execute(new ReceiveMessage(m));
|
||||||
} else if (recordReader.hasOffer()) {
|
} else if (packetReader.hasOffer()) {
|
||||||
Offer o = recordReader.readOffer();
|
Offer o = packetReader.readOffer();
|
||||||
dbExecutor.execute(new ReceiveOffer(o));
|
dbExecutor.execute(new ReceiveOffer(o));
|
||||||
} else if (recordReader.hasRequest()) {
|
} else if (packetReader.hasRequest()) {
|
||||||
Request r = recordReader.readRequest();
|
Request r = packetReader.readRequest();
|
||||||
dbExecutor.execute(new ReceiveRequest(r));
|
dbExecutor.execute(new ReceiveRequest(r));
|
||||||
} else {
|
} else {
|
||||||
// unknown records are ignored in RecordReader#eof()
|
|
||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,15 +30,11 @@ class MessageFactoryImpl implements MessageFactory {
|
|||||||
public Message createMessage(GroupId g, long timestamp, byte[] body) {
|
public Message createMessage(GroupId g, long timestamp, byte[] body) {
|
||||||
if (body.length > MAX_MESSAGE_BODY_LENGTH)
|
if (body.length > MAX_MESSAGE_BODY_LENGTH)
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
byte[] timeBytes = new byte[ByteUtils.INT_64_BYTES];
|
|
||||||
ByteUtils.writeUint64(timestamp, timeBytes, 0);
|
|
||||||
byte[] idHash =
|
|
||||||
crypto.hash(MessageId.LABEL, g.getBytes(), timeBytes, body);
|
|
||||||
MessageId id = new MessageId(idHash);
|
|
||||||
byte[] raw = new byte[MESSAGE_HEADER_LENGTH + body.length];
|
byte[] raw = new byte[MESSAGE_HEADER_LENGTH + body.length];
|
||||||
System.arraycopy(g.getBytes(), 0, raw, 0, UniqueId.LENGTH);
|
System.arraycopy(g.getBytes(), 0, raw, 0, UniqueId.LENGTH);
|
||||||
ByteUtils.writeUint64(timestamp, raw, UniqueId.LENGTH);
|
ByteUtils.writeUint64(timestamp, raw, UniqueId.LENGTH);
|
||||||
System.arraycopy(body, 0, raw, MESSAGE_HEADER_LENGTH, body.length);
|
System.arraycopy(body, 0, raw, MESSAGE_HEADER_LENGTH, body.length);
|
||||||
|
MessageId id = new MessageId(crypto.hash(MessageId.LABEL, raw));
|
||||||
return new Message(id, g, timestamp, raw);
|
return new Message(id, g, timestamp, raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package org.briarproject.bramble.sync;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.sync.PacketReader;
|
||||||
|
import org.briarproject.bramble.api.sync.PacketReaderFactory;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
@NotNullByDefault
|
||||||
|
class PacketReaderFactoryImpl implements PacketReaderFactory {
|
||||||
|
|
||||||
|
private final CryptoComponent crypto;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
PacketReaderFactoryImpl(CryptoComponent crypto) {
|
||||||
|
this.crypto = crypto;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PacketReader createPacketReader(InputStream in) {
|
||||||
|
return new PacketReaderImpl(crypto, in);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,14 +2,14 @@ package org.briarproject.bramble.sync;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.FormatException;
|
import org.briarproject.bramble.api.FormatException;
|
||||||
import org.briarproject.bramble.api.UniqueId;
|
import org.briarproject.bramble.api.UniqueId;
|
||||||
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.Ack;
|
import org.briarproject.bramble.api.sync.Ack;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.api.sync.Message;
|
import org.briarproject.bramble.api.sync.Message;
|
||||||
import org.briarproject.bramble.api.sync.MessageFactory;
|
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.bramble.api.sync.Offer;
|
import org.briarproject.bramble.api.sync.Offer;
|
||||||
import org.briarproject.bramble.api.sync.RecordReader;
|
import org.briarproject.bramble.api.sync.PacketReader;
|
||||||
import org.briarproject.bramble.api.sync.Request;
|
import org.briarproject.bramble.api.sync.Request;
|
||||||
import org.briarproject.bramble.util.ByteUtils;
|
import org.briarproject.bramble.util.ByteUtils;
|
||||||
|
|
||||||
@@ -20,84 +20,66 @@ import java.util.List;
|
|||||||
|
|
||||||
import javax.annotation.concurrent.NotThreadSafe;
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
import static org.briarproject.bramble.api.sync.RecordTypes.ACK;
|
import static org.briarproject.bramble.api.sync.PacketTypes.ACK;
|
||||||
import static org.briarproject.bramble.api.sync.RecordTypes.MESSAGE;
|
import static org.briarproject.bramble.api.sync.PacketTypes.MESSAGE;
|
||||||
import static org.briarproject.bramble.api.sync.RecordTypes.OFFER;
|
import static org.briarproject.bramble.api.sync.PacketTypes.OFFER;
|
||||||
import static org.briarproject.bramble.api.sync.RecordTypes.REQUEST;
|
import static org.briarproject.bramble.api.sync.PacketTypes.REQUEST;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_RECORD_PAYLOAD_LENGTH;
|
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_PACKET_PAYLOAD_LENGTH;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
|
import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
|
||||||
|
import static org.briarproject.bramble.api.sync.SyncConstants.PACKET_HEADER_LENGTH;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.PROTOCOL_VERSION;
|
import static org.briarproject.bramble.api.sync.SyncConstants.PROTOCOL_VERSION;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.RECORD_HEADER_LENGTH;
|
|
||||||
|
|
||||||
@NotThreadSafe
|
@NotThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class RecordReaderImpl implements RecordReader {
|
class PacketReaderImpl implements PacketReader {
|
||||||
|
|
||||||
private enum State {BUFFER_EMPTY, BUFFER_FULL, EOF}
|
private enum State { BUFFER_EMPTY, BUFFER_FULL, EOF }
|
||||||
|
|
||||||
private final MessageFactory messageFactory;
|
private final CryptoComponent crypto;
|
||||||
private final InputStream in;
|
private final InputStream in;
|
||||||
private final byte[] header, payload;
|
private final byte[] header, payload;
|
||||||
|
|
||||||
private State state = State.BUFFER_EMPTY;
|
private State state = State.BUFFER_EMPTY;
|
||||||
private int payloadLength = 0;
|
private int payloadLength = 0;
|
||||||
|
|
||||||
RecordReaderImpl(MessageFactory messageFactory, InputStream in) {
|
PacketReaderImpl(CryptoComponent crypto, InputStream in) {
|
||||||
this.messageFactory = messageFactory;
|
this.crypto = crypto;
|
||||||
this.in = in;
|
this.in = in;
|
||||||
header = new byte[RECORD_HEADER_LENGTH];
|
header = new byte[PACKET_HEADER_LENGTH];
|
||||||
payload = new byte[MAX_RECORD_PAYLOAD_LENGTH];
|
payload = new byte[MAX_PACKET_PAYLOAD_LENGTH];
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readRecord() throws IOException {
|
private void readPacket() throws IOException {
|
||||||
if (state != State.BUFFER_EMPTY) throw new IllegalStateException();
|
if (state != State.BUFFER_EMPTY) throw new IllegalStateException();
|
||||||
while (true) {
|
// Read the header
|
||||||
// Read the header
|
int offset = 0;
|
||||||
int offset = 0;
|
while (offset < PACKET_HEADER_LENGTH) {
|
||||||
while (offset < RECORD_HEADER_LENGTH) {
|
int read = in.read(header, offset, PACKET_HEADER_LENGTH - offset);
|
||||||
int read =
|
if (read == -1) {
|
||||||
in.read(header, offset, RECORD_HEADER_LENGTH - offset);
|
if (offset > 0) throw new FormatException();
|
||||||
if (read == -1) {
|
state = State.EOF;
|
||||||
if (offset > 0) throw new FormatException();
|
|
||||||
state = State.EOF;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
offset += read;
|
|
||||||
}
|
|
||||||
byte version = header[0], type = header[1];
|
|
||||||
payloadLength = ByteUtils.readUint16(header, 2);
|
|
||||||
// Check the protocol version
|
|
||||||
if (version != PROTOCOL_VERSION) throw new FormatException();
|
|
||||||
// Check the payload length
|
|
||||||
if (payloadLength > MAX_RECORD_PAYLOAD_LENGTH)
|
|
||||||
throw new FormatException();
|
|
||||||
// Read the payload
|
|
||||||
offset = 0;
|
|
||||||
while (offset < payloadLength) {
|
|
||||||
int read = in.read(payload, offset, payloadLength - offset);
|
|
||||||
if (read == -1) throw new FormatException();
|
|
||||||
offset += read;
|
|
||||||
}
|
|
||||||
state = State.BUFFER_FULL;
|
|
||||||
// Return if this is a known record type, otherwise continue
|
|
||||||
if (type == ACK || type == MESSAGE || type == OFFER ||
|
|
||||||
type == REQUEST) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
offset += read;
|
||||||
}
|
}
|
||||||
|
// Check the protocol version
|
||||||
|
if (header[0] != PROTOCOL_VERSION) throw new FormatException();
|
||||||
|
// Read the payload length
|
||||||
|
payloadLength = ByteUtils.readUint16(header, 2);
|
||||||
|
if (payloadLength > MAX_PACKET_PAYLOAD_LENGTH) throw new FormatException();
|
||||||
|
// Read the payload
|
||||||
|
offset = 0;
|
||||||
|
while (offset < payloadLength) {
|
||||||
|
int read = in.read(payload, offset, payloadLength - offset);
|
||||||
|
if (read == -1) throw new FormatException();
|
||||||
|
offset += read;
|
||||||
|
}
|
||||||
|
state = State.BUFFER_FULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if there's another record available or false if we've
|
|
||||||
* reached the end of the input stream.
|
|
||||||
* <p>
|
|
||||||
* If a record is available, it's been read into the buffer by the time
|
|
||||||
* eof() returns, so the method that called eof() can access the record
|
|
||||||
* from the buffer, for example to check its type or extract its payload.
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean eof() throws IOException {
|
public boolean eof() throws IOException {
|
||||||
if (state == State.BUFFER_EMPTY) readRecord();
|
if (state == State.BUFFER_EMPTY) readPacket();
|
||||||
if (state == State.BUFFER_EMPTY) throw new IllegalStateException();
|
if (state == State.BUFFER_EMPTY) throw new IllegalStateException();
|
||||||
return state == State.EOF;
|
return state == State.EOF;
|
||||||
}
|
}
|
||||||
@@ -142,12 +124,13 @@ class RecordReaderImpl implements RecordReader {
|
|||||||
// Timestamp
|
// Timestamp
|
||||||
long timestamp = ByteUtils.readUint64(payload, UniqueId.LENGTH);
|
long timestamp = ByteUtils.readUint64(payload, UniqueId.LENGTH);
|
||||||
if (timestamp < 0) throw new FormatException();
|
if (timestamp < 0) throw new FormatException();
|
||||||
// Body
|
// Raw message
|
||||||
byte[] body = new byte[payloadLength - MESSAGE_HEADER_LENGTH];
|
byte[] raw = new byte[payloadLength];
|
||||||
System.arraycopy(payload, MESSAGE_HEADER_LENGTH, body, 0,
|
System.arraycopy(payload, 0, raw, 0, payloadLength);
|
||||||
payloadLength - MESSAGE_HEADER_LENGTH);
|
|
||||||
state = State.BUFFER_EMPTY;
|
state = State.BUFFER_EMPTY;
|
||||||
return messageFactory.createMessage(groupId, timestamp, body);
|
// Message ID
|
||||||
|
MessageId messageId = new MessageId(crypto.hash(MessageId.LABEL, raw));
|
||||||
|
return new Message(messageId, groupId, timestamp, raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -171,5 +154,4 @@ class RecordReaderImpl implements RecordReader {
|
|||||||
if (!hasRequest()) throw new FormatException();
|
if (!hasRequest()) throw new FormatException();
|
||||||
return new Request(readMessageIds());
|
return new Request(readMessageIds());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package org.briarproject.bramble.sync;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.sync.PacketWriter;
|
||||||
|
import org.briarproject.bramble.api.sync.PacketWriterFactory;
|
||||||
|
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
@NotNullByDefault
|
||||||
|
class PacketWriterFactoryImpl implements PacketWriterFactory {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PacketWriter createPacketWriter(OutputStream out) {
|
||||||
|
return new PacketWriterImpl(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,8 +4,8 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|||||||
import org.briarproject.bramble.api.sync.Ack;
|
import org.briarproject.bramble.api.sync.Ack;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.bramble.api.sync.Offer;
|
import org.briarproject.bramble.api.sync.Offer;
|
||||||
import org.briarproject.bramble.api.sync.RecordTypes;
|
import org.briarproject.bramble.api.sync.PacketTypes;
|
||||||
import org.briarproject.bramble.api.sync.RecordWriter;
|
import org.briarproject.bramble.api.sync.PacketWriter;
|
||||||
import org.briarproject.bramble.api.sync.Request;
|
import org.briarproject.bramble.api.sync.Request;
|
||||||
import org.briarproject.bramble.util.ByteUtils;
|
import org.briarproject.bramble.util.ByteUtils;
|
||||||
|
|
||||||
@@ -15,30 +15,30 @@ import java.io.OutputStream;
|
|||||||
|
|
||||||
import javax.annotation.concurrent.NotThreadSafe;
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
import static org.briarproject.bramble.api.sync.RecordTypes.ACK;
|
import static org.briarproject.bramble.api.sync.PacketTypes.ACK;
|
||||||
import static org.briarproject.bramble.api.sync.RecordTypes.OFFER;
|
import static org.briarproject.bramble.api.sync.PacketTypes.OFFER;
|
||||||
import static org.briarproject.bramble.api.sync.RecordTypes.REQUEST;
|
import static org.briarproject.bramble.api.sync.PacketTypes.REQUEST;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_RECORD_PAYLOAD_LENGTH;
|
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_PACKET_PAYLOAD_LENGTH;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.RECORD_HEADER_LENGTH;
|
import static org.briarproject.bramble.api.sync.SyncConstants.PACKET_HEADER_LENGTH;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.PROTOCOL_VERSION;
|
import static org.briarproject.bramble.api.sync.SyncConstants.PROTOCOL_VERSION;
|
||||||
|
|
||||||
@NotThreadSafe
|
@NotThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class RecordWriterImpl implements RecordWriter {
|
class PacketWriterImpl implements PacketWriter {
|
||||||
|
|
||||||
private final OutputStream out;
|
private final OutputStream out;
|
||||||
private final byte[] header;
|
private final byte[] header;
|
||||||
private final ByteArrayOutputStream payload;
|
private final ByteArrayOutputStream payload;
|
||||||
|
|
||||||
RecordWriterImpl(OutputStream out) {
|
PacketWriterImpl(OutputStream out) {
|
||||||
this.out = out;
|
this.out = out;
|
||||||
header = new byte[RECORD_HEADER_LENGTH];
|
header = new byte[PACKET_HEADER_LENGTH];
|
||||||
header[0] = PROTOCOL_VERSION;
|
header[0] = PROTOCOL_VERSION;
|
||||||
payload = new ByteArrayOutputStream(MAX_RECORD_PAYLOAD_LENGTH);
|
payload = new ByteArrayOutputStream(MAX_PACKET_PAYLOAD_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeRecord(byte recordType) throws IOException {
|
private void writePacket(byte packetType) throws IOException {
|
||||||
header[1] = recordType;
|
header[1] = packetType;
|
||||||
ByteUtils.writeUint16(payload.size(), header, 2);
|
ByteUtils.writeUint16(payload.size(), header, 2);
|
||||||
out.write(header);
|
out.write(header);
|
||||||
payload.writeTo(out);
|
payload.writeTo(out);
|
||||||
@@ -49,12 +49,12 @@ class RecordWriterImpl implements RecordWriter {
|
|||||||
public void writeAck(Ack a) throws IOException {
|
public void writeAck(Ack a) throws IOException {
|
||||||
if (payload.size() != 0) throw new IllegalStateException();
|
if (payload.size() != 0) throw new IllegalStateException();
|
||||||
for (MessageId m : a.getMessageIds()) payload.write(m.getBytes());
|
for (MessageId m : a.getMessageIds()) payload.write(m.getBytes());
|
||||||
writeRecord(ACK);
|
writePacket(ACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeMessage(byte[] raw) throws IOException {
|
public void writeMessage(byte[] raw) throws IOException {
|
||||||
header[1] = RecordTypes.MESSAGE;
|
header[1] = PacketTypes.MESSAGE;
|
||||||
ByteUtils.writeUint16(raw.length, header, 2);
|
ByteUtils.writeUint16(raw.length, header, 2);
|
||||||
out.write(header);
|
out.write(header);
|
||||||
out.write(raw);
|
out.write(raw);
|
||||||
@@ -64,14 +64,14 @@ class RecordWriterImpl implements RecordWriter {
|
|||||||
public void writeOffer(Offer o) throws IOException {
|
public void writeOffer(Offer o) throws IOException {
|
||||||
if (payload.size() != 0) throw new IllegalStateException();
|
if (payload.size() != 0) throw new IllegalStateException();
|
||||||
for (MessageId m : o.getMessageIds()) payload.write(m.getBytes());
|
for (MessageId m : o.getMessageIds()) payload.write(m.getBytes());
|
||||||
writeRecord(OFFER);
|
writePacket(OFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeRequest(Request r) throws IOException {
|
public void writeRequest(Request r) throws IOException {
|
||||||
if (payload.size() != 0) throw new IllegalStateException();
|
if (payload.size() != 0) throw new IllegalStateException();
|
||||||
for (MessageId m : r.getMessageIds()) payload.write(m.getBytes());
|
for (MessageId m : r.getMessageIds()) payload.write(m.getBytes());
|
||||||
writeRecord(REQUEST);
|
writePacket(REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
package org.briarproject.bramble.sync;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|
||||||
import org.briarproject.bramble.api.sync.MessageFactory;
|
|
||||||
import org.briarproject.bramble.api.sync.RecordReader;
|
|
||||||
import org.briarproject.bramble.api.sync.RecordReaderFactory;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
@Immutable
|
|
||||||
@NotNullByDefault
|
|
||||||
class RecordReaderFactoryImpl implements RecordReaderFactory {
|
|
||||||
|
|
||||||
private final MessageFactory messageFactory;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
RecordReaderFactoryImpl(MessageFactory messageFactory) {
|
|
||||||
this.messageFactory = messageFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RecordReader createRecordReader(InputStream in) {
|
|
||||||
return new RecordReaderImpl(messageFactory, in);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package org.briarproject.bramble.sync;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|
||||||
import org.briarproject.bramble.api.sync.RecordWriter;
|
|
||||||
import org.briarproject.bramble.api.sync.RecordWriterFactory;
|
|
||||||
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
|
||||||
class RecordWriterFactoryImpl implements RecordWriterFactory {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RecordWriter createRecordWriter(OutputStream out) {
|
|
||||||
return new RecordWriterImpl(out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -13,7 +13,7 @@ import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
|||||||
import org.briarproject.bramble.api.lifecycle.event.ShutdownEvent;
|
import org.briarproject.bramble.api.lifecycle.event.ShutdownEvent;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.Ack;
|
import org.briarproject.bramble.api.sync.Ack;
|
||||||
import org.briarproject.bramble.api.sync.RecordWriter;
|
import org.briarproject.bramble.api.sync.PacketWriter;
|
||||||
import org.briarproject.bramble.api.sync.SyncSession;
|
import org.briarproject.bramble.api.sync.SyncSession;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -29,12 +29,12 @@ import javax.annotation.concurrent.ThreadSafe;
|
|||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS;
|
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_RECORD_PAYLOAD_LENGTH;
|
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_PACKET_PAYLOAD_LENGTH;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An outgoing {@link SyncSession} suitable for simplex transports. The session
|
* An outgoing {@link SyncSession} suitable for simplex transports. The session
|
||||||
* sends messages without offering them first, and closes its output stream
|
* sends messages without offering them first, and closes its output stream
|
||||||
* when there are no more records to send.
|
* when there are no more packets to send.
|
||||||
*/
|
*/
|
||||||
@ThreadSafe
|
@ThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
@@ -55,7 +55,7 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
|
|||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
private final ContactId contactId;
|
private final ContactId contactId;
|
||||||
private final int maxLatency;
|
private final int maxLatency;
|
||||||
private final RecordWriter recordWriter;
|
private final PacketWriter packetWriter;
|
||||||
private final AtomicInteger outstandingQueries;
|
private final AtomicInteger outstandingQueries;
|
||||||
private final BlockingQueue<ThrowingRunnable<IOException>> writerTasks;
|
private final BlockingQueue<ThrowingRunnable<IOException>> writerTasks;
|
||||||
|
|
||||||
@@ -63,14 +63,14 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
|
|||||||
|
|
||||||
SimplexOutgoingSession(DatabaseComponent db, Executor dbExecutor,
|
SimplexOutgoingSession(DatabaseComponent db, Executor dbExecutor,
|
||||||
EventBus eventBus, ContactId contactId,
|
EventBus eventBus, ContactId contactId,
|
||||||
int maxLatency, RecordWriter recordWriter) {
|
int maxLatency, PacketWriter packetWriter) {
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.dbExecutor = dbExecutor;
|
this.dbExecutor = dbExecutor;
|
||||||
this.eventBus = eventBus;
|
this.eventBus = eventBus;
|
||||||
this.contactId = contactId;
|
this.contactId = contactId;
|
||||||
this.maxLatency = maxLatency;
|
this.maxLatency = maxLatency;
|
||||||
this.recordWriter = recordWriter;
|
this.packetWriter = packetWriter;
|
||||||
outstandingQueries = new AtomicInteger(2); // One per type of record
|
outstandingQueries = new AtomicInteger(2); // One per type of packet
|
||||||
writerTasks = new LinkedBlockingQueue<ThrowingRunnable<IOException>>();
|
writerTasks = new LinkedBlockingQueue<ThrowingRunnable<IOException>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,19 +79,19 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
|
|||||||
public void run() throws IOException {
|
public void run() throws IOException {
|
||||||
eventBus.addListener(this);
|
eventBus.addListener(this);
|
||||||
try {
|
try {
|
||||||
// Start a query for each type of record
|
// Start a query for each type of packet
|
||||||
dbExecutor.execute(new GenerateAck());
|
dbExecutor.execute(new GenerateAck());
|
||||||
dbExecutor.execute(new GenerateBatch());
|
dbExecutor.execute(new GenerateBatch());
|
||||||
// Write records until interrupted or no more records to write
|
// Write packets until interrupted or no more packets to write
|
||||||
try {
|
try {
|
||||||
while (!interrupted) {
|
while (!interrupted) {
|
||||||
ThrowingRunnable<IOException> task = writerTasks.take();
|
ThrowingRunnable<IOException> task = writerTasks.take();
|
||||||
if (task == CLOSE) break;
|
if (task == CLOSE) break;
|
||||||
task.run();
|
task.run();
|
||||||
}
|
}
|
||||||
recordWriter.flush();
|
packetWriter.flush();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
LOG.info("Interrupted while waiting for a record to write");
|
LOG.info("Interrupted while waiting for a packet to write");
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@@ -157,7 +157,7 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
|
|||||||
@Override
|
@Override
|
||||||
public void run() throws IOException {
|
public void run() throws IOException {
|
||||||
if (interrupted) return;
|
if (interrupted) return;
|
||||||
recordWriter.writeAck(ack);
|
packetWriter.writeAck(ack);
|
||||||
LOG.info("Sent ack");
|
LOG.info("Sent ack");
|
||||||
dbExecutor.execute(new GenerateAck());
|
dbExecutor.execute(new GenerateAck());
|
||||||
}
|
}
|
||||||
@@ -174,7 +174,7 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
|
|||||||
Transaction txn = db.startTransaction(false);
|
Transaction txn = db.startTransaction(false);
|
||||||
try {
|
try {
|
||||||
b = db.generateBatch(txn, contactId,
|
b = db.generateBatch(txn, contactId,
|
||||||
MAX_RECORD_PAYLOAD_LENGTH, maxLatency);
|
MAX_PACKET_PAYLOAD_LENGTH, maxLatency);
|
||||||
db.commitTransaction(txn);
|
db.commitTransaction(txn);
|
||||||
} finally {
|
} finally {
|
||||||
db.endTransaction(txn);
|
db.endTransaction(txn);
|
||||||
@@ -202,7 +202,7 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
|
|||||||
@Override
|
@Override
|
||||||
public void run() throws IOException {
|
public void run() throws IOException {
|
||||||
if (interrupted) return;
|
if (interrupted) return;
|
||||||
for (byte[] raw : batch) recordWriter.writeMessage(raw);
|
for (byte[] raw : batch) packetWriter.writeMessage(raw);
|
||||||
LOG.info("Sent batch");
|
LOG.info("Sent batch");
|
||||||
dbExecutor.execute(new GenerateBatch());
|
dbExecutor.execute(new GenerateBatch());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import org.briarproject.bramble.api.event.EventBus;
|
|||||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.bramble.api.sync.GroupFactory;
|
import org.briarproject.bramble.api.sync.GroupFactory;
|
||||||
import org.briarproject.bramble.api.sync.MessageFactory;
|
import org.briarproject.bramble.api.sync.MessageFactory;
|
||||||
import org.briarproject.bramble.api.sync.RecordReaderFactory;
|
import org.briarproject.bramble.api.sync.PacketReaderFactory;
|
||||||
import org.briarproject.bramble.api.sync.RecordWriterFactory;
|
import org.briarproject.bramble.api.sync.PacketWriterFactory;
|
||||||
import org.briarproject.bramble.api.sync.SyncSessionFactory;
|
import org.briarproject.bramble.api.sync.SyncSessionFactory;
|
||||||
import org.briarproject.bramble.api.sync.ValidationManager;
|
import org.briarproject.bramble.api.sync.ValidationManager;
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
@@ -40,24 +40,23 @@ public class SyncModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
RecordReaderFactory provideRecordReaderFactory(
|
PacketReaderFactory providePacketReaderFactory(CryptoComponent crypto) {
|
||||||
RecordReaderFactoryImpl recordReaderFactory) {
|
return new PacketReaderFactoryImpl(crypto);
|
||||||
return recordReaderFactory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
RecordWriterFactory provideRecordWriterFactory() {
|
PacketWriterFactory providePacketWriterFactory() {
|
||||||
return new RecordWriterFactoryImpl();
|
return new PacketWriterFactoryImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
SyncSessionFactory provideSyncSessionFactory(DatabaseComponent db,
|
SyncSessionFactory provideSyncSessionFactory(DatabaseComponent db,
|
||||||
@DatabaseExecutor Executor dbExecutor, EventBus eventBus,
|
@DatabaseExecutor Executor dbExecutor, EventBus eventBus,
|
||||||
Clock clock, RecordReaderFactory recordReaderFactory,
|
Clock clock, PacketReaderFactory packetReaderFactory,
|
||||||
RecordWriterFactory recordWriterFactory) {
|
PacketWriterFactory packetWriterFactory) {
|
||||||
return new SyncSessionFactoryImpl(db, dbExecutor, eventBus, clock,
|
return new SyncSessionFactoryImpl(db, dbExecutor, eventBus, clock,
|
||||||
recordReaderFactory, recordWriterFactory);
|
packetReaderFactory, packetWriterFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import org.briarproject.bramble.api.db.DatabaseComponent;
|
|||||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.RecordReader;
|
import org.briarproject.bramble.api.sync.PacketReader;
|
||||||
import org.briarproject.bramble.api.sync.RecordReaderFactory;
|
import org.briarproject.bramble.api.sync.PacketReaderFactory;
|
||||||
import org.briarproject.bramble.api.sync.RecordWriter;
|
import org.briarproject.bramble.api.sync.PacketWriter;
|
||||||
import org.briarproject.bramble.api.sync.RecordWriterFactory;
|
import org.briarproject.bramble.api.sync.PacketWriterFactory;
|
||||||
import org.briarproject.bramble.api.sync.SyncSession;
|
import org.briarproject.bramble.api.sync.SyncSession;
|
||||||
import org.briarproject.bramble.api.sync.SyncSessionFactory;
|
import org.briarproject.bramble.api.sync.SyncSessionFactory;
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
@@ -28,41 +28,41 @@ class SyncSessionFactoryImpl implements SyncSessionFactory {
|
|||||||
private final Executor dbExecutor;
|
private final Executor dbExecutor;
|
||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
private final RecordReaderFactory recordReaderFactory;
|
private final PacketReaderFactory packetReaderFactory;
|
||||||
private final RecordWriterFactory recordWriterFactory;
|
private final PacketWriterFactory packetWriterFactory;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
SyncSessionFactoryImpl(DatabaseComponent db,
|
SyncSessionFactoryImpl(DatabaseComponent db,
|
||||||
@DatabaseExecutor Executor dbExecutor, EventBus eventBus,
|
@DatabaseExecutor Executor dbExecutor, EventBus eventBus,
|
||||||
Clock clock, RecordReaderFactory recordReaderFactory,
|
Clock clock, PacketReaderFactory packetReaderFactory,
|
||||||
RecordWriterFactory recordWriterFactory) {
|
PacketWriterFactory packetWriterFactory) {
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.dbExecutor = dbExecutor;
|
this.dbExecutor = dbExecutor;
|
||||||
this.eventBus = eventBus;
|
this.eventBus = eventBus;
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
this.recordReaderFactory = recordReaderFactory;
|
this.packetReaderFactory = packetReaderFactory;
|
||||||
this.recordWriterFactory = recordWriterFactory;
|
this.packetWriterFactory = packetWriterFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SyncSession createIncomingSession(ContactId c, InputStream in) {
|
public SyncSession createIncomingSession(ContactId c, InputStream in) {
|
||||||
RecordReader recordReader = recordReaderFactory.createRecordReader(in);
|
PacketReader packetReader = packetReaderFactory.createPacketReader(in);
|
||||||
return new IncomingSession(db, dbExecutor, eventBus, c, recordReader);
|
return new IncomingSession(db, dbExecutor, eventBus, c, packetReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SyncSession createSimplexOutgoingSession(ContactId c,
|
public SyncSession createSimplexOutgoingSession(ContactId c,
|
||||||
int maxLatency, OutputStream out) {
|
int maxLatency, OutputStream out) {
|
||||||
RecordWriter recordWriter = recordWriterFactory.createRecordWriter(out);
|
PacketWriter packetWriter = packetWriterFactory.createPacketWriter(out);
|
||||||
return new SimplexOutgoingSession(db, dbExecutor, eventBus, c,
|
return new SimplexOutgoingSession(db, dbExecutor, eventBus, c,
|
||||||
maxLatency, recordWriter);
|
maxLatency, packetWriter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SyncSession createDuplexOutgoingSession(ContactId c, int maxLatency,
|
public SyncSession createDuplexOutgoingSession(ContactId c, int maxLatency,
|
||||||
int maxIdleTime, OutputStream out) {
|
int maxIdleTime, OutputStream out) {
|
||||||
RecordWriter recordWriter = recordWriterFactory.createRecordWriter(out);
|
PacketWriter packetWriter = packetWriterFactory.createPacketWriter(out);
|
||||||
return new DuplexOutgoingSession(db, dbExecutor, eventBus, clock, c,
|
return new DuplexOutgoingSession(db, dbExecutor, eventBus, clock, c,
|
||||||
maxLatency, maxIdleTime, recordWriter);
|
maxLatency, maxIdleTime, packetWriter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
package org.briarproject.bramble.crypto;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
|
||||||
import org.briarproject.bramble.test.BrambleTestCase;
|
|
||||||
import org.briarproject.bramble.test.TestSeedProvider;
|
|
||||||
import org.briarproject.bramble.test.TestUtils;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
|
|
||||||
public class HashTest extends BrambleTestCase {
|
|
||||||
|
|
||||||
private final CryptoComponent crypto;
|
|
||||||
|
|
||||||
private final String label = TestUtils.getRandomString(42);
|
|
||||||
private final byte[] inputBytes = TestUtils.getRandomBytes(123);
|
|
||||||
private final byte[] inputBytes1 = TestUtils.getRandomBytes(234);
|
|
||||||
private final byte[] inputBytes2 = new byte[0];
|
|
||||||
|
|
||||||
public HashTest() {
|
|
||||||
crypto = new CryptoComponentImpl(new TestSeedProvider());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIdenticalInputsProduceIdenticalHashes() {
|
|
||||||
byte[] hash1 = crypto.hash(label, inputBytes, inputBytes1, inputBytes2);
|
|
||||||
byte[] hash2 = crypto.hash(label, inputBytes, inputBytes1, inputBytes2);
|
|
||||||
assertArrayEquals(hash1, hash2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDifferentInputsProduceDifferentHashes() {
|
|
||||||
byte[] hash1 = crypto.hash(label, inputBytes, inputBytes1, inputBytes2);
|
|
||||||
byte[] hash2 = crypto.hash(label, inputBytes2, inputBytes1, inputBytes);
|
|
||||||
assertFalse(Arrays.equals(hash1, hash2));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDifferentLabelsProduceDifferentHashes() {
|
|
||||||
String label2 = TestUtils.getRandomString(42);
|
|
||||||
byte[] hash1 = crypto.hash(label, inputBytes, inputBytes1, inputBytes2);
|
|
||||||
byte[] hash2 =
|
|
||||||
crypto.hash(label2, inputBytes, inputBytes1, inputBytes2);
|
|
||||||
assertFalse(Arrays.equals(hash1, hash2));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,251 +0,0 @@
|
|||||||
package org.briarproject.bramble.keyagreement;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementConnection;
|
|
||||||
import org.briarproject.bramble.api.plugin.TransportConnectionReader;
|
|
||||||
import org.briarproject.bramble.api.plugin.TransportConnectionWriter;
|
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
|
||||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
|
||||||
import org.briarproject.bramble.test.TestUtils;
|
|
||||||
import org.briarproject.bramble.util.ByteUtils;
|
|
||||||
import org.jmock.Expectations;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
|
|
||||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION;
|
|
||||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.RECORD_HEADER_LENGTH;
|
|
||||||
import static org.briarproject.bramble.api.keyagreement.RecordTypes.ABORT;
|
|
||||||
import static org.briarproject.bramble.api.keyagreement.RecordTypes.CONFIRM;
|
|
||||||
import static org.briarproject.bramble.api.keyagreement.RecordTypes.KEY;
|
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
|
|
||||||
public class KeyAgreementTransportTest extends BrambleMockTestCase {
|
|
||||||
|
|
||||||
private final DuplexTransportConnection duplexTransportConnection =
|
|
||||||
context.mock(DuplexTransportConnection.class);
|
|
||||||
private final TransportConnectionReader transportConnectionReader =
|
|
||||||
context.mock(TransportConnectionReader.class);
|
|
||||||
private final TransportConnectionWriter transportConnectionWriter =
|
|
||||||
context.mock(TransportConnectionWriter.class);
|
|
||||||
|
|
||||||
private final TransportId transportId = new TransportId("test");
|
|
||||||
private final KeyAgreementConnection keyAgreementConnection =
|
|
||||||
new KeyAgreementConnection(duplexTransportConnection, transportId);
|
|
||||||
|
|
||||||
private ByteArrayInputStream inputStream;
|
|
||||||
private ByteArrayOutputStream outputStream;
|
|
||||||
private KeyAgreementTransport kat;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSendKey() throws Exception {
|
|
||||||
setup(new byte[0]);
|
|
||||||
byte[] key = TestUtils.getRandomBytes(123);
|
|
||||||
kat.sendKey(key);
|
|
||||||
assertRecordSent(KEY, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSendConfirm() throws Exception {
|
|
||||||
setup(new byte[0]);
|
|
||||||
byte[] confirm = TestUtils.getRandomBytes(123);
|
|
||||||
kat.sendConfirm(confirm);
|
|
||||||
assertRecordSent(CONFIRM, confirm);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSendAbortWithException() throws Exception {
|
|
||||||
setup(new byte[0]);
|
|
||||||
context.checking(new Expectations() {{
|
|
||||||
oneOf(transportConnectionReader).dispose(true, true);
|
|
||||||
oneOf(transportConnectionWriter).dispose(true);
|
|
||||||
}});
|
|
||||||
kat.sendAbort(true);
|
|
||||||
assertRecordSent(ABORT, new byte[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSendAbortWithoutException() throws Exception {
|
|
||||||
setup(new byte[0]);
|
|
||||||
context.checking(new Expectations() {{
|
|
||||||
oneOf(transportConnectionReader).dispose(false, true);
|
|
||||||
oneOf(transportConnectionWriter).dispose(false);
|
|
||||||
}});
|
|
||||||
kat.sendAbort(false);
|
|
||||||
assertRecordSent(ABORT, new byte[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = AbortException.class)
|
|
||||||
public void testReceiveKeyThrowsExceptionIfAtEndOfStream()
|
|
||||||
throws Exception {
|
|
||||||
setup(new byte[0]);
|
|
||||||
kat.receiveKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = AbortException.class)
|
|
||||||
public void testReceiveKeyThrowsExceptionIfHeaderIsTooShort()
|
|
||||||
throws Exception {
|
|
||||||
byte[] input = new byte[RECORD_HEADER_LENGTH - 1];
|
|
||||||
input[0] = PROTOCOL_VERSION;
|
|
||||||
input[1] = KEY;
|
|
||||||
setup(input);
|
|
||||||
kat.receiveKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = AbortException.class)
|
|
||||||
public void testReceiveKeyThrowsExceptionIfPayloadIsTooShort()
|
|
||||||
throws Exception {
|
|
||||||
int payloadLength = 123;
|
|
||||||
byte[] input = new byte[RECORD_HEADER_LENGTH + payloadLength - 1];
|
|
||||||
input[0] = PROTOCOL_VERSION;
|
|
||||||
input[1] = KEY;
|
|
||||||
ByteUtils.writeUint16(payloadLength, input, 2);
|
|
||||||
setup(input);
|
|
||||||
kat.receiveKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = AbortException.class)
|
|
||||||
public void testReceiveKeyThrowsExceptionIfProtocolVersionIsUnrecognised()
|
|
||||||
throws Exception {
|
|
||||||
setup(createRecord((byte) (PROTOCOL_VERSION + 1), KEY, new byte[123]));
|
|
||||||
kat.receiveKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = AbortException.class)
|
|
||||||
public void testReceiveKeyThrowsExceptionIfAbortIsReceived()
|
|
||||||
throws Exception {
|
|
||||||
setup(createRecord(PROTOCOL_VERSION, ABORT, new byte[0]));
|
|
||||||
kat.receiveKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = AbortException.class)
|
|
||||||
public void testReceiveKeyThrowsExceptionIfConfirmIsReceived()
|
|
||||||
throws Exception {
|
|
||||||
setup(createRecord(PROTOCOL_VERSION, CONFIRM, new byte[123]));
|
|
||||||
kat.receiveKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testReceiveKeySkipsUnrecognisedRecordTypes() throws Exception {
|
|
||||||
byte[] skip1 = createRecord(PROTOCOL_VERSION, (byte) (ABORT + 1),
|
|
||||||
new byte[123]);
|
|
||||||
byte[] skip2 = createRecord(PROTOCOL_VERSION, (byte) (ABORT + 2),
|
|
||||||
new byte[0]);
|
|
||||||
byte[] payload = TestUtils.getRandomBytes(123);
|
|
||||||
byte[] key = createRecord(PROTOCOL_VERSION, KEY, payload);
|
|
||||||
ByteArrayOutputStream input = new ByteArrayOutputStream();
|
|
||||||
input.write(skip1);
|
|
||||||
input.write(skip2);
|
|
||||||
input.write(key);
|
|
||||||
setup(input.toByteArray());
|
|
||||||
assertArrayEquals(payload, kat.receiveKey());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = AbortException.class)
|
|
||||||
public void testReceiveConfirmThrowsExceptionIfAtEndOfStream()
|
|
||||||
throws Exception {
|
|
||||||
setup(new byte[0]);
|
|
||||||
kat.receiveConfirm();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = AbortException.class)
|
|
||||||
public void testReceiveConfirmThrowsExceptionIfHeaderIsTooShort()
|
|
||||||
throws Exception {
|
|
||||||
byte[] input = new byte[RECORD_HEADER_LENGTH - 1];
|
|
||||||
input[0] = PROTOCOL_VERSION;
|
|
||||||
input[1] = CONFIRM;
|
|
||||||
setup(input);
|
|
||||||
kat.receiveConfirm();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = AbortException.class)
|
|
||||||
public void testReceiveConfirmThrowsExceptionIfPayloadIsTooShort()
|
|
||||||
throws Exception {
|
|
||||||
int payloadLength = 123;
|
|
||||||
byte[] input = new byte[RECORD_HEADER_LENGTH + payloadLength - 1];
|
|
||||||
input[0] = PROTOCOL_VERSION;
|
|
||||||
input[1] = CONFIRM;
|
|
||||||
ByteUtils.writeUint16(payloadLength, input, 2);
|
|
||||||
setup(input);
|
|
||||||
kat.receiveConfirm();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = AbortException.class)
|
|
||||||
public void testReceiveConfirmThrowsExceptionIfProtocolVersionIsUnrecognised()
|
|
||||||
throws Exception {
|
|
||||||
setup(createRecord((byte) (PROTOCOL_VERSION + 1), CONFIRM,
|
|
||||||
new byte[123]));
|
|
||||||
kat.receiveConfirm();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = AbortException.class)
|
|
||||||
public void testReceiveConfirmThrowsExceptionIfAbortIsReceived()
|
|
||||||
throws Exception {
|
|
||||||
setup(createRecord(PROTOCOL_VERSION, ABORT, new byte[0]));
|
|
||||||
kat.receiveConfirm();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = AbortException.class)
|
|
||||||
public void testReceiveKeyThrowsExceptionIfKeyIsReceived()
|
|
||||||
throws Exception {
|
|
||||||
setup(createRecord(PROTOCOL_VERSION, KEY, new byte[123]));
|
|
||||||
kat.receiveConfirm();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testReceiveConfirmSkipsUnrecognisedRecordTypes()
|
|
||||||
throws Exception {
|
|
||||||
byte[] skip1 = createRecord(PROTOCOL_VERSION, (byte) (ABORT + 1),
|
|
||||||
new byte[123]);
|
|
||||||
byte[] skip2 = createRecord(PROTOCOL_VERSION, (byte) (ABORT + 2),
|
|
||||||
new byte[0]);
|
|
||||||
byte[] payload = TestUtils.getRandomBytes(123);
|
|
||||||
byte[] confirm = createRecord(PROTOCOL_VERSION, CONFIRM, payload);
|
|
||||||
ByteArrayOutputStream input = new ByteArrayOutputStream();
|
|
||||||
input.write(skip1);
|
|
||||||
input.write(skip2);
|
|
||||||
input.write(confirm);
|
|
||||||
setup(input.toByteArray());
|
|
||||||
assertArrayEquals(payload, kat.receiveConfirm());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setup(byte[] input) throws Exception {
|
|
||||||
inputStream = new ByteArrayInputStream(input);
|
|
||||||
outputStream = new ByteArrayOutputStream();
|
|
||||||
context.checking(new Expectations() {{
|
|
||||||
allowing(duplexTransportConnection).getReader();
|
|
||||||
will(returnValue(transportConnectionReader));
|
|
||||||
allowing(transportConnectionReader).getInputStream();
|
|
||||||
will(returnValue(inputStream));
|
|
||||||
allowing(duplexTransportConnection).getWriter();
|
|
||||||
will(returnValue(transportConnectionWriter));
|
|
||||||
allowing(transportConnectionWriter).getOutputStream();
|
|
||||||
will(returnValue(outputStream));
|
|
||||||
}});
|
|
||||||
kat = new KeyAgreementTransport(keyAgreementConnection);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertRecordSent(byte expectedType, byte[] expectedPayload) {
|
|
||||||
byte[] output = outputStream.toByteArray();
|
|
||||||
assertEquals(RECORD_HEADER_LENGTH + expectedPayload.length,
|
|
||||||
output.length);
|
|
||||||
assertEquals(PROTOCOL_VERSION, output[0]);
|
|
||||||
assertEquals(expectedType, output[1]);
|
|
||||||
assertEquals(expectedPayload.length, ByteUtils.readUint16(output, 2));
|
|
||||||
byte[] payload = new byte[output.length - RECORD_HEADER_LENGTH];
|
|
||||||
System.arraycopy(output, RECORD_HEADER_LENGTH, payload, 0,
|
|
||||||
payload.length);
|
|
||||||
assertArrayEquals(expectedPayload, payload);
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] createRecord(byte version, byte type, byte[] payload) {
|
|
||||||
byte[] b = new byte[RECORD_HEADER_LENGTH + payload.length];
|
|
||||||
b[0] = version;
|
|
||||||
b[1] = type;
|
|
||||||
ByteUtils.writeUint16(payload.length, b, 2);
|
|
||||||
System.arraycopy(payload, 0, b, RECORD_HEADER_LENGTH, payload.length);
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,219 +0,0 @@
|
|||||||
package org.briarproject.bramble.sync;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.FormatException;
|
|
||||||
import org.briarproject.bramble.api.UniqueId;
|
|
||||||
import org.briarproject.bramble.api.sync.Ack;
|
|
||||||
import org.briarproject.bramble.api.sync.MessageFactory;
|
|
||||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
|
||||||
import org.briarproject.bramble.test.TestUtils;
|
|
||||||
import org.briarproject.bramble.util.ByteUtils;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
|
|
||||||
import static org.briarproject.bramble.api.sync.RecordTypes.ACK;
|
|
||||||
import static org.briarproject.bramble.api.sync.RecordTypes.OFFER;
|
|
||||||
import static org.briarproject.bramble.api.sync.RecordTypes.REQUEST;
|
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS;
|
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_RECORD_PAYLOAD_LENGTH;
|
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.PROTOCOL_VERSION;
|
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.RECORD_HEADER_LENGTH;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
public class RecordReaderImplTest extends BrambleMockTestCase {
|
|
||||||
|
|
||||||
private final MessageFactory messageFactory =
|
|
||||||
context.mock(MessageFactory.class);
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testFormatExceptionIfAckIsTooLarge() throws Exception {
|
|
||||||
byte[] b = createAck(true);
|
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(b);
|
|
||||||
RecordReaderImpl reader = new RecordReaderImpl(messageFactory, in);
|
|
||||||
reader.readAck();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNoFormatExceptionIfAckIsMaximumSize() throws Exception {
|
|
||||||
byte[] b = createAck(false);
|
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(b);
|
|
||||||
RecordReaderImpl reader = new RecordReaderImpl(messageFactory, in);
|
|
||||||
reader.readAck();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testFormatExceptionIfAckIsEmpty() throws Exception {
|
|
||||||
byte[] b = createEmptyAck();
|
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(b);
|
|
||||||
RecordReaderImpl reader = new RecordReaderImpl(messageFactory, in);
|
|
||||||
reader.readAck();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testFormatExceptionIfOfferIsTooLarge() throws Exception {
|
|
||||||
byte[] b = createOffer(true);
|
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(b);
|
|
||||||
RecordReaderImpl reader = new RecordReaderImpl(messageFactory, in);
|
|
||||||
reader.readOffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNoFormatExceptionIfOfferIsMaximumSize() throws Exception {
|
|
||||||
byte[] b = createOffer(false);
|
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(b);
|
|
||||||
RecordReaderImpl reader = new RecordReaderImpl(messageFactory, in);
|
|
||||||
reader.readOffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testFormatExceptionIfOfferIsEmpty() throws Exception {
|
|
||||||
byte[] b = createEmptyOffer();
|
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(b);
|
|
||||||
RecordReaderImpl reader = new RecordReaderImpl(messageFactory, in);
|
|
||||||
reader.readOffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testFormatExceptionIfRequestIsTooLarge() throws Exception {
|
|
||||||
byte[] b = createRequest(true);
|
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(b);
|
|
||||||
RecordReaderImpl reader = new RecordReaderImpl(messageFactory, in);
|
|
||||||
reader.readRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNoFormatExceptionIfRequestIsMaximumSize() throws Exception {
|
|
||||||
byte[] b = createRequest(false);
|
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(b);
|
|
||||||
RecordReaderImpl reader = new RecordReaderImpl(messageFactory, in);
|
|
||||||
reader.readRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testFormatExceptionIfRequestIsEmpty() throws Exception {
|
|
||||||
byte[] b = createEmptyRequest();
|
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(b);
|
|
||||||
RecordReaderImpl reader = new RecordReaderImpl(messageFactory, in);
|
|
||||||
reader.readRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testEofReturnsTrueWhenAtEndOfStream() throws Exception {
|
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(new byte[0]);
|
|
||||||
RecordReaderImpl reader = new RecordReaderImpl(messageFactory, in);
|
|
||||||
assertTrue(reader.eof());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testEofReturnsFalseWhenNotAtEndOfStream() throws Exception {
|
|
||||||
byte[] b = createAck(false);
|
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(b);
|
|
||||||
RecordReaderImpl reader = new RecordReaderImpl(messageFactory, in);
|
|
||||||
assertFalse(reader.eof());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testThrowsExceptionIfHeaderIsTooShort() throws Exception {
|
|
||||||
byte[] b = new byte[RECORD_HEADER_LENGTH - 1];
|
|
||||||
b[0] = PROTOCOL_VERSION;
|
|
||||||
b[1] = ACK;
|
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(b);
|
|
||||||
RecordReaderImpl reader = new RecordReaderImpl(messageFactory, in);
|
|
||||||
reader.eof();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testThrowsExceptionIfPayloadIsTooShort() throws Exception {
|
|
||||||
int payloadLength = 123;
|
|
||||||
byte[] b = new byte[RECORD_HEADER_LENGTH + payloadLength - 1];
|
|
||||||
b[0] = PROTOCOL_VERSION;
|
|
||||||
b[1] = ACK;
|
|
||||||
ByteUtils.writeUint16(payloadLength, b, 2);
|
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(b);
|
|
||||||
RecordReaderImpl reader = new RecordReaderImpl(messageFactory, in);
|
|
||||||
reader.eof();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testThrowsExceptionIfProtocolVersionIsUnrecognised()
|
|
||||||
throws Exception {
|
|
||||||
byte version = (byte) (PROTOCOL_VERSION + 1);
|
|
||||||
byte[] b = createRecord(version, ACK, new byte[0]);
|
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(b);
|
|
||||||
RecordReaderImpl reader = new RecordReaderImpl(messageFactory, in);
|
|
||||||
reader.eof();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testThrowsExceptionIfPayloadIsTooLong() throws Exception {
|
|
||||||
byte[] payload = new byte[MAX_RECORD_PAYLOAD_LENGTH + 1];
|
|
||||||
byte[] b = createRecord(PROTOCOL_VERSION, ACK, payload);
|
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(b);
|
|
||||||
RecordReaderImpl reader = new RecordReaderImpl(messageFactory, in);
|
|
||||||
reader.eof();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSkipsUnrecognisedRecordTypes() throws Exception {
|
|
||||||
byte[] skip1 = createRecord(PROTOCOL_VERSION, (byte) (REQUEST + 1),
|
|
||||||
new byte[123]);
|
|
||||||
byte[] skip2 = createRecord(PROTOCOL_VERSION, (byte) (REQUEST + 2),
|
|
||||||
new byte[0]);
|
|
||||||
byte[] ack = createAck(false);
|
|
||||||
ByteArrayOutputStream input = new ByteArrayOutputStream();
|
|
||||||
input.write(skip1);
|
|
||||||
input.write(skip2);
|
|
||||||
input.write(ack);
|
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(input.toByteArray());
|
|
||||||
RecordReaderImpl reader = new RecordReaderImpl(messageFactory, in);
|
|
||||||
assertTrue(reader.hasAck());
|
|
||||||
Ack a = reader.readAck();
|
|
||||||
assertEquals(MAX_MESSAGE_IDS, a.getMessageIds().size());
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] createAck(boolean tooBig) throws Exception {
|
|
||||||
return createRecord(PROTOCOL_VERSION, ACK, createPayload(tooBig));
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] createEmptyAck() throws Exception {
|
|
||||||
return createRecord(PROTOCOL_VERSION, ACK, new byte[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] createOffer(boolean tooBig) throws Exception {
|
|
||||||
return createRecord(PROTOCOL_VERSION, OFFER, createPayload(tooBig));
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] createEmptyOffer() throws Exception {
|
|
||||||
return createRecord(PROTOCOL_VERSION, OFFER, new byte[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] createRequest(boolean tooBig) throws Exception {
|
|
||||||
return createRecord(PROTOCOL_VERSION, REQUEST, createPayload(tooBig));
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] createEmptyRequest() throws Exception {
|
|
||||||
return createRecord(PROTOCOL_VERSION, REQUEST, new byte[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] createRecord(byte version, byte type, byte[] payload) {
|
|
||||||
byte[] b = new byte[RECORD_HEADER_LENGTH + payload.length];
|
|
||||||
b[0] = version;
|
|
||||||
b[1] = type;
|
|
||||||
ByteUtils.writeUint16(payload.length, b, 2);
|
|
||||||
System.arraycopy(payload, 0, b, RECORD_HEADER_LENGTH, payload.length);
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] createPayload(boolean tooBig) throws Exception {
|
|
||||||
ByteArrayOutputStream payload = new ByteArrayOutputStream();
|
|
||||||
while (payload.size() + UniqueId.LENGTH <= MAX_RECORD_PAYLOAD_LENGTH) {
|
|
||||||
payload.write(TestUtils.getRandomId());
|
|
||||||
}
|
|
||||||
if (tooBig) payload.write(TestUtils.getRandomId());
|
|
||||||
assertEquals(tooBig, payload.size() > MAX_RECORD_PAYLOAD_LENGTH);
|
|
||||||
return payload.toByteArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,10 +7,4 @@ apply plugin: 'witness'
|
|||||||
dependencies {
|
dependencies {
|
||||||
compile project(':bramble-core')
|
compile project(':bramble-core')
|
||||||
compile fileTree(dir: 'libs', include: '*.jar')
|
compile fileTree(dir: 'libs', include: '*.jar')
|
||||||
|
|
||||||
testCompile project(path: ':bramble-core', configuration: 'testOutput')
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.withType(Test) {
|
|
||||||
systemProperty 'java.library.path', 'libs'
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import org.briarproject.bramble.api.keyagreement.KeyAgreementListener;
|
|||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.Backoff;
|
import org.briarproject.bramble.api.plugin.Backoff;
|
||||||
import org.briarproject.bramble.api.plugin.PluginException;
|
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
|
||||||
@@ -100,7 +99,7 @@ class BluetoothPlugin implements DuplexPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() throws PluginException {
|
public boolean start() throws IOException {
|
||||||
if (used.getAndSet(true)) throw new IllegalStateException();
|
if (used.getAndSet(true)) throw new IllegalStateException();
|
||||||
// Initialise the Bluetooth stack
|
// Initialise the Bluetooth stack
|
||||||
try {
|
try {
|
||||||
@@ -109,14 +108,13 @@ class BluetoothPlugin implements DuplexPlugin {
|
|||||||
// On Linux the user may need to install libbluetooth-dev
|
// On Linux the user may need to install libbluetooth-dev
|
||||||
if (OsUtils.isLinux())
|
if (OsUtils.isLinux())
|
||||||
callback.showMessage("BLUETOOTH_INSTALL_LIBS");
|
callback.showMessage("BLUETOOTH_INSTALL_LIBS");
|
||||||
throw new PluginException(e);
|
return false;
|
||||||
} catch (BluetoothStateException e) {
|
|
||||||
throw new PluginException(e);
|
|
||||||
}
|
}
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Local address " + localDevice.getBluetoothAddress());
|
LOG.info("Local address " + localDevice.getBluetoothAddress());
|
||||||
running = true;
|
running = true;
|
||||||
bind();
|
bind();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bind() {
|
private void bind() {
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package org.briarproject.bramble.plugin.file;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.contact.ContactId;
|
import org.briarproject.bramble.api.contact.ContactId;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.PluginException;
|
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.plugin.simplex.SimplexPluginCallback;
|
import org.briarproject.bramble.api.plugin.simplex.SimplexPluginCallback;
|
||||||
|
|
||||||
@@ -43,24 +42,17 @@ class RemovableDrivePlugin extends FilePlugin
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() throws PluginException {
|
public boolean start() throws IOException {
|
||||||
if (used.getAndSet(true)) throw new IllegalStateException();
|
if (used.getAndSet(true)) throw new IllegalStateException();
|
||||||
running = true;
|
running = true;
|
||||||
try {
|
monitor.start(this);
|
||||||
monitor.start(this);
|
return true;
|
||||||
} catch (IOException e) {
|
|
||||||
throw new PluginException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop() throws PluginException {
|
public void stop() throws IOException {
|
||||||
running = false;
|
running = false;
|
||||||
try {
|
monitor.stop();
|
||||||
monitor.stop();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new PluginException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import org.briarproject.bramble.api.data.BdfList;
|
|||||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementListener;
|
import org.briarproject.bramble.api.keyagreement.KeyAgreementListener;
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.PluginException;
|
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.AbstractDuplexTransportConnection;
|
import org.briarproject.bramble.api.plugin.duplex.AbstractDuplexTransportConnection;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
||||||
@@ -69,7 +68,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() throws PluginException {
|
public boolean start() {
|
||||||
if (used.getAndSet(true)) throw new IllegalStateException();
|
if (used.getAndSet(true)) throw new IllegalStateException();
|
||||||
for (String portName : serialPortList.getPortNames()) {
|
for (String portName : serialPortList.getPortNames()) {
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
@@ -80,12 +79,12 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
|
|||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Initialised modem on " + portName);
|
LOG.info("Initialised modem on " + portName);
|
||||||
running = true;
|
running = true;
|
||||||
return;
|
return true;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new PluginException();
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
5
briar-android-tests/.gitignore
vendored
Normal file
5
briar-android-tests/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
bin
|
||||||
|
gen
|
||||||
|
build
|
||||||
|
local.properties
|
||||||
|
.settings
|
||||||
27
briar-android-tests/build.gradle
Normal file
27
briar-android-tests/build.gradle
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
apply plugin: 'com.android.library'
|
||||||
|
apply plugin: 'com.neenbedankt.android-apt'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 23
|
||||||
|
buildToolsVersion "23.0.3"
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdkVersion 14
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../briar-android/proguard-rules.txt'
|
||||||
|
consumerProguardFiles getDefaultProguardFile('proguard-android.txt'), '../briar-android/proguard-rules.txt'
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_7
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
testCompile project(':briar-tests')
|
||||||
|
testCompile 'junit:junit:4.12'
|
||||||
|
testCompile 'net.jodah:concurrentunit:0.4.2'
|
||||||
|
testCompile 'com.android.support:appcompat-v7:23.2.1'
|
||||||
|
testApt 'com.google.dagger:dagger-compiler:2.0.2'
|
||||||
|
provided 'javax.annotation:jsr250-api:1.0'
|
||||||
|
}
|
||||||
12
briar-android-tests/src/main/AndroidManifest.xml
Normal file
12
briar-android-tests/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<manifest package="org.briarproject"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:supportsRtl="true"
|
||||||
|
>
|
||||||
|
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
3
briar-android-tests/src/main/res/values/strings.xml
Normal file
3
briar-android-tests/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name">briar-android-tests</string>
|
||||||
|
</resources>
|
||||||
@@ -1,15 +1,12 @@
|
|||||||
package org.briarproject.briar.blog;
|
package org.briarproject;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.bramble.test.TestDatabaseModule;
|
|
||||||
import org.briarproject.briar.api.blog.Blog;
|
import org.briarproject.briar.api.blog.Blog;
|
||||||
import org.briarproject.briar.api.blog.BlogCommentHeader;
|
import org.briarproject.briar.api.blog.BlogCommentHeader;
|
||||||
import org.briarproject.briar.api.blog.BlogManager;
|
import org.briarproject.briar.api.blog.BlogManager;
|
||||||
import org.briarproject.briar.api.blog.BlogPost;
|
import org.briarproject.briar.api.blog.BlogPost;
|
||||||
import org.briarproject.briar.api.blog.BlogPostHeader;
|
import org.briarproject.briar.api.blog.BlogPostHeader;
|
||||||
import org.briarproject.briar.test.BriarIntegrationTest;
|
|
||||||
import org.briarproject.briar.test.BriarIntegrationTestComponent;
|
|
||||||
import org.briarproject.briar.test.DaggerBriarIntegrationTestComponent;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -20,7 +17,6 @@ import java.util.Iterator;
|
|||||||
|
|
||||||
import static junit.framework.Assert.assertFalse;
|
import static junit.framework.Assert.assertFalse;
|
||||||
import static junit.framework.Assert.assertNotNull;
|
import static junit.framework.Assert.assertNotNull;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomString;
|
|
||||||
import static org.briarproject.briar.api.blog.MessageType.COMMENT;
|
import static org.briarproject.briar.api.blog.MessageType.COMMENT;
|
||||||
import static org.briarproject.briar.api.blog.MessageType.POST;
|
import static org.briarproject.briar.api.blog.MessageType.POST;
|
||||||
import static org.briarproject.briar.api.blog.MessageType.WRAPPED_COMMENT;
|
import static org.briarproject.briar.api.blog.MessageType.WRAPPED_COMMENT;
|
||||||
@@ -28,7 +24,7 @@ import static org.briarproject.briar.api.blog.MessageType.WRAPPED_POST;
|
|||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class BlogManagerIntegrationTest
|
public class BlogManagerTest
|
||||||
extends BriarIntegrationTest<BriarIntegrationTestComponent> {
|
extends BriarIntegrationTest<BriarIntegrationTestComponent> {
|
||||||
|
|
||||||
private BlogManager blogManager0, blogManager1;
|
private BlogManager blogManager0, blogManager1;
|
||||||
@@ -105,7 +101,7 @@ public class BlogManagerIntegrationTest
|
|||||||
@Test
|
@Test
|
||||||
public void testBlogPost() throws Exception {
|
public void testBlogPost() throws Exception {
|
||||||
// check that blog0 has no posts
|
// check that blog0 has no posts
|
||||||
final String body = getRandomString(42);
|
final String body = TestUtils.getRandomString(42);
|
||||||
Collection<BlogPostHeader> headers0 =
|
Collection<BlogPostHeader> headers0 =
|
||||||
blogManager0.getPostHeaders(blog0.getId());
|
blogManager0.getPostHeaders(blog0.getId());
|
||||||
assertEquals(0, headers0.size());
|
assertEquals(0, headers0.size());
|
||||||
@@ -143,7 +139,7 @@ public class BlogManagerIntegrationTest
|
|||||||
@Test
|
@Test
|
||||||
public void testBlogPostInWrongBlog() throws Exception {
|
public void testBlogPostInWrongBlog() throws Exception {
|
||||||
// add a post to blog1
|
// add a post to blog1
|
||||||
final String body = getRandomString(42);
|
final String body = TestUtils.getRandomString(42);
|
||||||
BlogPost p = blogPostFactory
|
BlogPost p = blogPostFactory
|
||||||
.createBlogPost(blog1.getId(), clock.currentTimeMillis(), null,
|
.createBlogPost(blog1.getId(), clock.currentTimeMillis(), null,
|
||||||
author0, body);
|
author0, body);
|
||||||
@@ -169,7 +165,7 @@ public class BlogManagerIntegrationTest
|
|||||||
assertFalse(blogManager1.canBeRemoved(blog0.getId()));
|
assertFalse(blogManager1.canBeRemoved(blog0.getId()));
|
||||||
|
|
||||||
// the following two calls should throw a DbException now
|
// the following two calls should throw a DbException now
|
||||||
thrown.expect(IllegalArgumentException.class);
|
thrown.expect(DbException.class);
|
||||||
|
|
||||||
blogManager0.removeBlog(blog1);
|
blogManager0.removeBlog(blog1);
|
||||||
blogManager1.removeBlog(blog0);
|
blogManager1.removeBlog(blog0);
|
||||||
@@ -182,7 +178,7 @@ public class BlogManagerIntegrationTest
|
|||||||
@Test
|
@Test
|
||||||
public void testBlogComment() throws Exception {
|
public void testBlogComment() throws Exception {
|
||||||
// add a post to blog0
|
// add a post to blog0
|
||||||
final String body = getRandomString(42);
|
final String body = TestUtils.getRandomString(42);
|
||||||
BlogPost p = blogPostFactory
|
BlogPost p = blogPostFactory
|
||||||
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
|
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
|
||||||
author0, body);
|
author0, body);
|
||||||
@@ -227,7 +223,7 @@ public class BlogManagerIntegrationTest
|
|||||||
@Test
|
@Test
|
||||||
public void testBlogCommentOnOwnPost() throws Exception {
|
public void testBlogCommentOnOwnPost() throws Exception {
|
||||||
// add a post to blog0
|
// add a post to blog0
|
||||||
final String body = getRandomString(42);
|
final String body = TestUtils.getRandomString(42);
|
||||||
BlogPost p = blogPostFactory
|
BlogPost p = blogPostFactory
|
||||||
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
|
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
|
||||||
author0, body);
|
author0, body);
|
||||||
@@ -263,7 +259,7 @@ public class BlogManagerIntegrationTest
|
|||||||
@Test
|
@Test
|
||||||
public void testCommentOnComment() throws Exception {
|
public void testCommentOnComment() throws Exception {
|
||||||
// add a post to blog0
|
// add a post to blog0
|
||||||
final String body = getRandomString(42);
|
final String body = TestUtils.getRandomString(42);
|
||||||
BlogPost p = blogPostFactory
|
BlogPost p = blogPostFactory
|
||||||
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
|
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
|
||||||
author0, body);
|
author0, body);
|
||||||
@@ -353,7 +349,7 @@ public class BlogManagerIntegrationTest
|
|||||||
@Test
|
@Test
|
||||||
public void testCommentOnOwnComment() throws Exception {
|
public void testCommentOnOwnComment() throws Exception {
|
||||||
// add a post to blog0
|
// add a post to blog0
|
||||||
final String body = getRandomString(42);
|
final String body = TestUtils.getRandomString(42);
|
||||||
BlogPost p = blogPostFactory
|
BlogPost p = blogPostFactory
|
||||||
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
|
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
|
||||||
author0, body);
|
author0, body);
|
||||||
@@ -1,15 +1,13 @@
|
|||||||
package org.briarproject.briar.sharing;
|
package org.briarproject;
|
||||||
|
|
||||||
import net.jodah.concurrentunit.Waiter;
|
import net.jodah.concurrentunit.Waiter;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.contact.Contact;
|
import org.briarproject.bramble.api.contact.Contact;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.NoSuchGroupException;
|
|
||||||
import org.briarproject.bramble.api.event.Event;
|
import org.briarproject.bramble.api.event.Event;
|
||||||
import org.briarproject.bramble.api.event.EventListener;
|
import org.briarproject.bramble.api.event.EventListener;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.test.TestDatabaseModule;
|
|
||||||
import org.briarproject.briar.api.blog.Blog;
|
import org.briarproject.briar.api.blog.Blog;
|
||||||
import org.briarproject.briar.api.blog.BlogInvitationRequest;
|
import org.briarproject.briar.api.blog.BlogInvitationRequest;
|
||||||
import org.briarproject.briar.api.blog.BlogInvitationResponse;
|
import org.briarproject.briar.api.blog.BlogInvitationResponse;
|
||||||
@@ -18,9 +16,6 @@ import org.briarproject.briar.api.blog.BlogSharingManager;
|
|||||||
import org.briarproject.briar.api.blog.event.BlogInvitationRequestReceivedEvent;
|
import org.briarproject.briar.api.blog.event.BlogInvitationRequestReceivedEvent;
|
||||||
import org.briarproject.briar.api.blog.event.BlogInvitationResponseReceivedEvent;
|
import org.briarproject.briar.api.blog.event.BlogInvitationResponseReceivedEvent;
|
||||||
import org.briarproject.briar.api.sharing.InvitationMessage;
|
import org.briarproject.briar.api.sharing.InvitationMessage;
|
||||||
import org.briarproject.briar.test.BriarIntegrationTest;
|
|
||||||
import org.briarproject.briar.test.BriarIntegrationTestComponent;
|
|
||||||
import org.briarproject.briar.test.DaggerBriarIntegrationTestComponent;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -30,13 +25,11 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.briarproject.TestUtils.assertGroupCount;
|
||||||
import static org.briarproject.briar.api.blog.BlogSharingManager.CLIENT_ID;
|
import static org.briarproject.briar.api.blog.BlogSharingManager.CLIENT_ID;
|
||||||
import static org.briarproject.briar.test.BriarTestUtils.assertGroupCount;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
|
|
||||||
public class BlogSharingIntegrationTest
|
public class BlogSharingIntegrationTest
|
||||||
extends BriarIntegrationTest<BriarIntegrationTestComponent> {
|
extends BriarIntegrationTest<BriarIntegrationTestComponent> {
|
||||||
@@ -93,7 +86,7 @@ public class BlogSharingIntegrationTest
|
|||||||
injectEagerSingletons(c2);
|
injectEagerSingletons(c2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test
|
||||||
public void testPersonalBlogCannotBeSharedWithOwner() throws Exception {
|
public void testPersonalBlogCannotBeSharedWithOwner() throws Exception {
|
||||||
listenToEvents(true);
|
listenToEvents(true);
|
||||||
|
|
||||||
@@ -108,8 +101,12 @@ public class BlogSharingIntegrationTest
|
|||||||
|
|
||||||
// create invitation
|
// create invitation
|
||||||
blogSharingManager0
|
blogSharingManager0
|
||||||
.sendInvitation(blog1.getId(), contactId1From0, "Hi!",
|
.sendInvitation(blog1.getId(), contactId1From0, "Hi!");
|
||||||
clock.currentTimeMillis());
|
|
||||||
|
// sync invitation
|
||||||
|
sync0To1(1, false);
|
||||||
|
// make sure the invitee ignored the request for their own blog
|
||||||
|
assertFalse(listener1.requestReceived);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -119,8 +116,7 @@ public class BlogSharingIntegrationTest
|
|||||||
|
|
||||||
// send invitation
|
// send invitation
|
||||||
blogSharingManager0
|
blogSharingManager0
|
||||||
.sendInvitation(blog2.getId(), contactId1From0, "Hi!",
|
.sendInvitation(blog2.getId(), contactId1From0, "Hi!");
|
||||||
clock.currentTimeMillis());
|
|
||||||
|
|
||||||
// invitee has own blog and that of the sharer
|
// invitee has own blog and that of the sharer
|
||||||
assertEquals(2, blogManager1.getBlogs().size());
|
assertEquals(2, blogManager1.getBlogs().size());
|
||||||
@@ -149,7 +145,7 @@ public class BlogSharingIntegrationTest
|
|||||||
|
|
||||||
// invitee has one invitation message from sharer
|
// invitee has one invitation message from sharer
|
||||||
List<InvitationMessage> list =
|
List<InvitationMessage> list =
|
||||||
new ArrayList<InvitationMessage>(blogSharingManager1
|
new ArrayList<>(blogSharingManager1
|
||||||
.getInvitationMessages(contactId0From1));
|
.getInvitationMessages(contactId0From1));
|
||||||
assertEquals(2, list.size());
|
assertEquals(2, list.size());
|
||||||
// check other things are alright with the message
|
// check other things are alright with the message
|
||||||
@@ -192,8 +188,7 @@ public class BlogSharingIntegrationTest
|
|||||||
|
|
||||||
// send invitation
|
// send invitation
|
||||||
blogSharingManager0
|
blogSharingManager0
|
||||||
.sendInvitation(blog2.getId(), contactId1From0, null,
|
.sendInvitation(blog2.getId(), contactId1From0, null);
|
||||||
clock.currentTimeMillis());
|
|
||||||
|
|
||||||
// sync first request message
|
// sync first request message
|
||||||
sync0To1(1, true);
|
sync0To1(1, true);
|
||||||
@@ -213,7 +208,7 @@ public class BlogSharingIntegrationTest
|
|||||||
|
|
||||||
// invitee has one invitation message from sharer and one response
|
// invitee has one invitation message from sharer and one response
|
||||||
List<InvitationMessage> list =
|
List<InvitationMessage> list =
|
||||||
new ArrayList<InvitationMessage>(blogSharingManager1
|
new ArrayList<>(blogSharingManager1
|
||||||
.getInvitationMessages(contactId0From1));
|
.getInvitationMessages(contactId0From1));
|
||||||
assertEquals(2, list.size());
|
assertEquals(2, list.size());
|
||||||
// check things are alright with the message
|
// check things are alright with the message
|
||||||
@@ -250,8 +245,7 @@ public class BlogSharingIntegrationTest
|
|||||||
|
|
||||||
// send invitation
|
// send invitation
|
||||||
blogSharingManager0
|
blogSharingManager0
|
||||||
.sendInvitation(blog2.getId(), contactId1From0, "Hi!",
|
.sendInvitation(blog2.getId(), contactId1From0, "Hi!");
|
||||||
clock.currentTimeMillis());
|
|
||||||
|
|
||||||
// sync first request message
|
// sync first request message
|
||||||
sync0To1(1, true);
|
sync0To1(1, true);
|
||||||
@@ -272,7 +266,7 @@ public class BlogSharingIntegrationTest
|
|||||||
assertTrue(blogSharingManager0.getSharedWith(blog2.getId())
|
assertTrue(blogSharingManager0.getSharedWith(blog2.getId())
|
||||||
.contains(contact1From0));
|
.contains(contact1From0));
|
||||||
// invitee gets blog shared by sharer
|
// invitee gets blog shared by sharer
|
||||||
assertTrue(blogSharingManager1.getSharedWith(blog2.getId())
|
assertTrue(blogSharingManager1.getSharedBy(blog2.getId())
|
||||||
.contains(contact0From1));
|
.contains(contact0From1));
|
||||||
|
|
||||||
// invitee un-subscribes from blog
|
// invitee un-subscribes from blog
|
||||||
@@ -288,12 +282,14 @@ public class BlogSharingIntegrationTest
|
|||||||
// sharer no longer shares blog with invitee
|
// sharer no longer shares blog with invitee
|
||||||
assertFalse(blogSharingManager0.getSharedWith(blog2.getId())
|
assertFalse(blogSharingManager0.getSharedWith(blog2.getId())
|
||||||
.contains(contact1From0));
|
.contains(contact1From0));
|
||||||
// invitee no longer has blog shared by sharer
|
// invitee no longer gets blog shared by sharer
|
||||||
assertEquals(0,
|
assertFalse(blogSharingManager1.getSharedBy(blog2.getId())
|
||||||
blogSharingManager1.getSharedWith(blog2.getId()).size());
|
.contains(contact0From1));
|
||||||
// blog can be shared again by sharer
|
// blog can be shared again
|
||||||
assertTrue(
|
assertTrue(
|
||||||
blogSharingManager0.canBeShared(blog2.getId(), contact1From0));
|
blogSharingManager0.canBeShared(blog2.getId(), contact1From0));
|
||||||
|
assertTrue(
|
||||||
|
blogSharingManager1.canBeShared(blog2.getId(), contact0From1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -307,18 +303,17 @@ public class BlogSharingIntegrationTest
|
|||||||
|
|
||||||
// sharer sends invitation for 2's blog to 1
|
// sharer sends invitation for 2's blog to 1
|
||||||
blogSharingManager0
|
blogSharingManager0
|
||||||
.sendInvitation(blog2.getId(), contactId1From0, "Hi!",
|
.sendInvitation(blog2.getId(), contactId1From0, "Hi!");
|
||||||
clock.currentTimeMillis());
|
|
||||||
|
|
||||||
// sync first request message
|
// sync first request message
|
||||||
sync0To1(1, true);
|
sync0To1(1, true);
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
assertTrue(listener1.requestReceived);
|
assertTrue(listener1.requestReceived);
|
||||||
|
|
||||||
// make sure blog2 is shared by 0 and 2
|
// make sure blog2 is shared by 0
|
||||||
Collection<Contact> contacts =
|
Collection<Contact> contacts =
|
||||||
blogSharingManager1.getSharedWith(blog2.getId());
|
blogSharingManager1.getSharedBy(blog2.getId());
|
||||||
assertEquals(2, contacts.size());
|
assertEquals(1, contacts.size());
|
||||||
assertTrue(contacts.contains(contact0From1));
|
assertTrue(contacts.contains(contact0From1));
|
||||||
|
|
||||||
// make sure 1 knows that they have blog2 already
|
// make sure 1 knows that they have blog2 already
|
||||||
@@ -344,8 +339,7 @@ public class BlogSharingIntegrationTest
|
|||||||
|
|
||||||
// send invitation
|
// send invitation
|
||||||
blogSharingManager0
|
blogSharingManager0
|
||||||
.sendInvitation(blog2.getId(), contactId1From0, "Hi!",
|
.sendInvitation(blog2.getId(), contactId1From0, "Hi!");
|
||||||
clock.currentTimeMillis());
|
|
||||||
|
|
||||||
// sync first request message
|
// sync first request message
|
||||||
sync0To1(1, true);
|
sync0To1(1, true);
|
||||||
@@ -361,11 +355,10 @@ public class BlogSharingIntegrationTest
|
|||||||
assertEquals(3, blogManager1.getBlogs().size());
|
assertEquals(3, blogManager1.getBlogs().size());
|
||||||
Collection<Contact> sharedWith =
|
Collection<Contact> sharedWith =
|
||||||
blogSharingManager0.getSharedWith(blog2.getId());
|
blogSharingManager0.getSharedWith(blog2.getId());
|
||||||
assertEquals(2, sharedWith.size());
|
assertEquals(1, sharedWith.size());
|
||||||
assertTrue(sharedWith.contains(contact1From0));
|
assertEquals(contact1From0, sharedWith.iterator().next());
|
||||||
assertTrue(sharedWith.contains(contact2From0));
|
|
||||||
Collection<Contact> sharedBy =
|
Collection<Contact> sharedBy =
|
||||||
blogSharingManager1.getSharedWith(blog2.getId());
|
blogSharingManager1.getSharedBy(blog2.getId());
|
||||||
assertEquals(1, sharedBy.size());
|
assertEquals(1, sharedBy.size());
|
||||||
assertEquals(contact0From1, sharedBy.iterator().next());
|
assertEquals(contact0From1, sharedBy.iterator().next());
|
||||||
|
|
||||||
@@ -381,8 +374,7 @@ public class BlogSharingIntegrationTest
|
|||||||
// sharer does not share this blog anymore with invitee
|
// sharer does not share this blog anymore with invitee
|
||||||
sharedWith =
|
sharedWith =
|
||||||
blogSharingManager0.getSharedWith(blog2.getId());
|
blogSharingManager0.getSharedWith(blog2.getId());
|
||||||
assertEquals(1, sharedWith.size());
|
assertEquals(0, sharedWith.size());
|
||||||
assertTrue(sharedWith.contains(contact2From0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -395,8 +387,7 @@ public class BlogSharingIntegrationTest
|
|||||||
|
|
||||||
// sharer sends invitation for 2's blog to 1
|
// sharer sends invitation for 2's blog to 1
|
||||||
blogSharingManager0
|
blogSharingManager0
|
||||||
.sendInvitation(blog2.getId(), contactId1From0, "Hi!",
|
.sendInvitation(blog2.getId(), contactId1From0, "Hi!");
|
||||||
clock.currentTimeMillis());
|
|
||||||
|
|
||||||
// sync first request message
|
// sync first request message
|
||||||
sync0To1(1, true);
|
sync0To1(1, true);
|
||||||
@@ -405,7 +396,7 @@ public class BlogSharingIntegrationTest
|
|||||||
|
|
||||||
// make sure blog2 is shared by 0
|
// make sure blog2 is shared by 0
|
||||||
Collection<Contact> contacts =
|
Collection<Contact> contacts =
|
||||||
blogSharingManager1.getSharedWith(blog2.getId());
|
blogSharingManager1.getSharedBy(blog2.getId());
|
||||||
assertEquals(1, contacts.size());
|
assertEquals(1, contacts.size());
|
||||||
assertTrue(contacts.contains(contact0From1));
|
assertTrue(contacts.contains(contact0From1));
|
||||||
|
|
||||||
@@ -426,65 +417,6 @@ public class BlogSharingIntegrationTest
|
|||||||
assertFalse(blogManager1.canBeRemoved(blog2.getId()));
|
assertFalse(blogManager1.canBeRemoved(blog2.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSharerIsInformedWhenBlogIsRemovedDueToContactDeletion()
|
|
||||||
throws Exception {
|
|
||||||
// initialize and let invitee accept all requests
|
|
||||||
listenToEvents(true);
|
|
||||||
|
|
||||||
// sharer sends invitation for 2's blog to 1
|
|
||||||
blogSharingManager0
|
|
||||||
.sendInvitation(blog2.getId(), contactId1From0, "Hi!",
|
|
||||||
clock.currentTimeMillis());
|
|
||||||
|
|
||||||
// sync first request message
|
|
||||||
sync0To1(1, true);
|
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
|
||||||
assertTrue(listener1.requestReceived);
|
|
||||||
|
|
||||||
// sync response back
|
|
||||||
sync1To0(1, true);
|
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
|
||||||
assertTrue(listener0.responseReceived);
|
|
||||||
|
|
||||||
// 1 and 2 are adding each other
|
|
||||||
addContacts1And2();
|
|
||||||
assertEquals(3, blogManager1.getBlogs().size());
|
|
||||||
|
|
||||||
// make sure blog2 is shared between 0 and 1
|
|
||||||
Collection<Contact> contacts =
|
|
||||||
blogSharingManager1.getSharedWith(blog2.getId());
|
|
||||||
assertEquals(2, contacts.size());
|
|
||||||
assertTrue(contacts.contains(contact0From1));
|
|
||||||
contacts = blogSharingManager0.getSharedWith(blog2.getId());
|
|
||||||
assertEquals(2, contacts.size());
|
|
||||||
assertTrue(contacts.contains(contact1From0));
|
|
||||||
|
|
||||||
// 1 removes contact 2
|
|
||||||
assertNotNull(contactId2From1);
|
|
||||||
contactManager1.removeContact(contactId2From1);
|
|
||||||
|
|
||||||
// sync leave message to 0
|
|
||||||
sync1To0(1, true);
|
|
||||||
|
|
||||||
// make sure blog2 is no longer shared between 0 and 1
|
|
||||||
contacts = blogSharingManager0.getSharedWith(blog2.getId());
|
|
||||||
assertEquals(1, contacts.size());
|
|
||||||
assertFalse(contacts.contains(contact1From0));
|
|
||||||
|
|
||||||
// 1 doesn't even have blog2 anymore
|
|
||||||
try {
|
|
||||||
blogManager1.getBlog(blog2.getId());
|
|
||||||
fail();
|
|
||||||
} catch (NoSuchGroupException e) {
|
|
||||||
// expected
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0 can share blog2 again with 1
|
|
||||||
assertTrue(
|
|
||||||
blogSharingManager0.canBeShared(blog2.getId(), contact1From0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
private class SharerListener implements EventListener {
|
private class SharerListener implements EventListener {
|
||||||
|
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
package org.briarproject.briar.test;
|
package org.briarproject;
|
||||||
|
|
||||||
|
import android.support.annotation.CallSuper;
|
||||||
|
|
||||||
import net.jodah.concurrentunit.Waiter;
|
import net.jodah.concurrentunit.Waiter;
|
||||||
|
|
||||||
@@ -29,8 +31,6 @@ import org.briarproject.bramble.lifecycle.LifecycleModule;
|
|||||||
import org.briarproject.bramble.properties.PropertiesModule;
|
import org.briarproject.bramble.properties.PropertiesModule;
|
||||||
import org.briarproject.bramble.sync.SyncModule;
|
import org.briarproject.bramble.sync.SyncModule;
|
||||||
import org.briarproject.bramble.system.SystemModule;
|
import org.briarproject.bramble.system.SystemModule;
|
||||||
import org.briarproject.bramble.test.TestPluginConfigModule;
|
|
||||||
import org.briarproject.bramble.test.TestUtils;
|
|
||||||
import org.briarproject.bramble.transport.TransportModule;
|
import org.briarproject.bramble.transport.TransportModule;
|
||||||
import org.briarproject.briar.api.blog.BlogFactory;
|
import org.briarproject.briar.api.blog.BlogFactory;
|
||||||
import org.briarproject.briar.api.blog.BlogPostFactory;
|
import org.briarproject.briar.api.blog.BlogPostFactory;
|
||||||
@@ -60,10 +60,11 @@ import javax.annotation.Nullable;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static junit.framework.Assert.assertNotNull;
|
import static junit.framework.Assert.assertNotNull;
|
||||||
|
import static org.briarproject.TestPluginConfigModule.MAX_LATENCY;
|
||||||
|
import static org.briarproject.TestUtils.getSecretKey;
|
||||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED;
|
import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED;
|
||||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.INVALID;
|
import static org.briarproject.bramble.api.sync.ValidationManager.State.INVALID;
|
||||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.PENDING;
|
import static org.briarproject.bramble.api.sync.ValidationManager.State.PENDING;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@@ -100,19 +101,19 @@ public abstract class BriarIntegrationTest<C extends BriarIntegrationTestCompone
|
|||||||
@Inject
|
@Inject
|
||||||
protected AuthorFactory authorFactory;
|
protected AuthorFactory authorFactory;
|
||||||
@Inject
|
@Inject
|
||||||
protected ContactGroupFactory contactGroupFactory;
|
ContactGroupFactory contactGroupFactory;
|
||||||
@Inject
|
@Inject
|
||||||
protected PrivateGroupFactory privateGroupFactory;
|
PrivateGroupFactory privateGroupFactory;
|
||||||
@Inject
|
@Inject
|
||||||
protected GroupMessageFactory groupMessageFactory;
|
GroupMessageFactory groupMessageFactory;
|
||||||
@Inject
|
@Inject
|
||||||
protected GroupInvitationFactory groupInvitationFactory;
|
GroupInvitationFactory groupInvitationFactory;
|
||||||
@Inject
|
@Inject
|
||||||
protected BlogFactory blogFactory;
|
BlogFactory blogFactory;
|
||||||
@Inject
|
@Inject
|
||||||
protected BlogPostFactory blogPostFactory;
|
BlogPostFactory blogPostFactory;
|
||||||
@Inject
|
@Inject
|
||||||
protected ForumPostFactory forumPostFactory;
|
ForumPostFactory forumPostFactory;
|
||||||
|
|
||||||
// objects accessed from background threads need to be volatile
|
// objects accessed from background threads need to be volatile
|
||||||
private volatile Waiter validationWaiter;
|
private volatile Waiter validationWaiter;
|
||||||
@@ -131,6 +132,7 @@ public abstract class BriarIntegrationTest<C extends BriarIntegrationTestCompone
|
|||||||
protected File t2Dir = new File(testDir, AUTHOR2);
|
protected File t2Dir = new File(testDir, AUTHOR2);
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
@CallSuper
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
assertTrue(testDir.mkdirs());
|
assertTrue(testDir.mkdirs());
|
||||||
createComponents();
|
createComponents();
|
||||||
@@ -325,7 +327,7 @@ public abstract class BriarIntegrationTest<C extends BriarIntegrationTestCompone
|
|||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
// Create an outgoing sync session
|
// Create an outgoing sync session
|
||||||
SyncSession sessionFrom =
|
SyncSession sessionFrom =
|
||||||
fromSync.createSimplexOutgoingSession(toId, TestPluginConfigModule.MAX_LATENCY, out);
|
fromSync.createSimplexOutgoingSession(toId, MAX_LATENCY, out);
|
||||||
// Write whatever needs to be written
|
// Write whatever needs to be written
|
||||||
sessionFrom.run();
|
sessionFrom.run();
|
||||||
out.close();
|
out.close();
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.briar.test;
|
package org.briarproject;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.client.ClientHelper;
|
import org.briarproject.bramble.api.client.ClientHelper;
|
||||||
import org.briarproject.bramble.api.contact.ContactManager;
|
import org.briarproject.bramble.api.contact.ContactManager;
|
||||||
@@ -19,9 +19,6 @@ import org.briarproject.bramble.lifecycle.LifecycleModule;
|
|||||||
import org.briarproject.bramble.properties.PropertiesModule;
|
import org.briarproject.bramble.properties.PropertiesModule;
|
||||||
import org.briarproject.bramble.sync.SyncModule;
|
import org.briarproject.bramble.sync.SyncModule;
|
||||||
import org.briarproject.bramble.system.SystemModule;
|
import org.briarproject.bramble.system.SystemModule;
|
||||||
import org.briarproject.bramble.test.TestDatabaseModule;
|
|
||||||
import org.briarproject.bramble.test.TestPluginConfigModule;
|
|
||||||
import org.briarproject.bramble.test.TestSeedProviderModule;
|
|
||||||
import org.briarproject.bramble.transport.TransportModule;
|
import org.briarproject.bramble.transport.TransportModule;
|
||||||
import org.briarproject.briar.api.blog.BlogManager;
|
import org.briarproject.briar.api.blog.BlogManager;
|
||||||
import org.briarproject.briar.api.blog.BlogSharingManager;
|
import org.briarproject.briar.api.blog.BlogSharingManager;
|
||||||
@@ -1,15 +1,13 @@
|
|||||||
package org.briarproject.briar.forum;
|
package org.briarproject;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.test.TestDatabaseModule;
|
|
||||||
import org.briarproject.briar.api.forum.Forum;
|
import org.briarproject.briar.api.forum.Forum;
|
||||||
import org.briarproject.briar.api.forum.ForumManager;
|
import org.briarproject.briar.api.forum.ForumManager;
|
||||||
import org.briarproject.briar.api.forum.ForumPost;
|
import org.briarproject.briar.api.forum.ForumPost;
|
||||||
import org.briarproject.briar.api.forum.ForumPostHeader;
|
import org.briarproject.briar.api.forum.ForumPostHeader;
|
||||||
import org.briarproject.briar.api.forum.ForumSharingManager;
|
import org.briarproject.briar.api.forum.ForumSharingManager;
|
||||||
import org.briarproject.briar.test.BriarIntegrationTest;
|
|
||||||
import org.briarproject.briar.test.BriarIntegrationTestComponent;
|
|
||||||
import org.briarproject.briar.test.DaggerBriarIntegrationTestComponent;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@@ -17,10 +15,10 @@ import java.util.Collection;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import static org.briarproject.briar.test.BriarTestUtils.assertGroupCount;
|
import static junit.framework.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static junit.framework.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static junit.framework.TestCase.assertFalse;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.briarproject.TestUtils.assertGroupCount;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class ForumManagerTest
|
public class ForumManagerTest
|
||||||
@@ -45,8 +43,7 @@ public class ForumManagerTest
|
|||||||
forum0 = forumManager0.addForum("Test Forum");
|
forum0 = forumManager0.addForum("Test Forum");
|
||||||
groupId0 = forum0.getId();
|
groupId0 = forum0.getId();
|
||||||
// share forum
|
// share forum
|
||||||
forumSharingManager0.sendInvitation(groupId0, contactId1From0, null,
|
forumSharingManager0.sendInvitation(groupId0, contactId1From0, null);
|
||||||
clock.currentTimeMillis());
|
|
||||||
sync0To1(1, true);
|
sync0To1(1, true);
|
||||||
forumSharingManager1.respondToInvitation(forum0, contact0From1, true);
|
forumSharingManager1.respondToInvitation(forum0, contact0From1, true);
|
||||||
sync1To0(1, true);
|
sync1To0(1, true);
|
||||||
@@ -113,7 +110,7 @@ public class ForumManagerTest
|
|||||||
|
|
||||||
boolean isPost1 = h.getId().equals(post1.getMessage().getId());
|
boolean isPost1 = h.getId().equals(post1.getMessage().getId());
|
||||||
boolean isPost2 = h.getId().equals(post2.getMessage().getId());
|
boolean isPost2 = h.getId().equals(post2.getMessage().getId());
|
||||||
assertTrue(isPost1 || isPost2);
|
Assert.assertTrue(isPost1 || isPost2);
|
||||||
if (isPost1) {
|
if (isPost1) {
|
||||||
assertEquals(h.getTimestamp(), ms1);
|
assertEquals(h.getTimestamp(), ms1);
|
||||||
assertEquals(body1, hBody);
|
assertEquals(body1, hBody);
|
||||||
@@ -190,8 +187,7 @@ public class ForumManagerTest
|
|||||||
// share a second forum
|
// share a second forum
|
||||||
Forum forum1 = forumManager0.addForum("Test Forum1");
|
Forum forum1 = forumManager0.addForum("Test Forum1");
|
||||||
GroupId g1 = forum1.getId();
|
GroupId g1 = forum1.getId();
|
||||||
forumSharingManager0.sendInvitation(g1, contactId1From0, null,
|
forumSharingManager0.sendInvitation(g1, contactId1From0, null);
|
||||||
clock.currentTimeMillis());
|
|
||||||
sync0To1(1, true);
|
sync0To1(1, true);
|
||||||
forumSharingManager1.respondToInvitation(forum1, contact0From1, true);
|
forumSharingManager1.respondToInvitation(forum1, contact0From1, true);
|
||||||
sync1To0(1, true);
|
sync1To0(1, true);
|
||||||
@@ -1,14 +1,19 @@
|
|||||||
package org.briarproject.briar.sharing;
|
package org.briarproject;
|
||||||
|
|
||||||
import net.jodah.concurrentunit.Waiter;
|
import net.jodah.concurrentunit.Waiter;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.Bytes;
|
||||||
import org.briarproject.bramble.api.contact.Contact;
|
import org.briarproject.bramble.api.contact.Contact;
|
||||||
|
import org.briarproject.bramble.api.data.BdfList;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
|
import org.briarproject.bramble.api.db.Metadata;
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
import org.briarproject.bramble.api.event.Event;
|
import org.briarproject.bramble.api.event.Event;
|
||||||
import org.briarproject.bramble.api.event.EventListener;
|
import org.briarproject.bramble.api.event.EventListener;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.test.TestDatabaseModule;
|
import org.briarproject.bramble.api.sync.Group;
|
||||||
|
import org.briarproject.briar.api.client.MessageQueueManager;
|
||||||
|
import org.briarproject.briar.api.client.SessionId;
|
||||||
import org.briarproject.briar.api.forum.Forum;
|
import org.briarproject.briar.api.forum.Forum;
|
||||||
import org.briarproject.briar.api.forum.ForumInvitationRequest;
|
import org.briarproject.briar.api.forum.ForumInvitationRequest;
|
||||||
import org.briarproject.briar.api.forum.ForumInvitationResponse;
|
import org.briarproject.briar.api.forum.ForumInvitationResponse;
|
||||||
@@ -20,9 +25,6 @@ import org.briarproject.briar.api.forum.event.ForumInvitationRequestReceivedEven
|
|||||||
import org.briarproject.briar.api.forum.event.ForumInvitationResponseReceivedEvent;
|
import org.briarproject.briar.api.forum.event.ForumInvitationResponseReceivedEvent;
|
||||||
import org.briarproject.briar.api.sharing.InvitationMessage;
|
import org.briarproject.briar.api.sharing.InvitationMessage;
|
||||||
import org.briarproject.briar.api.sharing.SharingInvitationItem;
|
import org.briarproject.briar.api.sharing.SharingInvitationItem;
|
||||||
import org.briarproject.briar.test.BriarIntegrationTest;
|
|
||||||
import org.briarproject.briar.test.BriarIntegrationTestComponent;
|
|
||||||
import org.briarproject.briar.test.DaggerBriarIntegrationTestComponent;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -33,7 +35,9 @@ import java.util.Collection;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static junit.framework.Assert.assertNotNull;
|
import static junit.framework.Assert.assertNotNull;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomString;
|
import static org.briarproject.briar.api.forum.ForumConstants.FORUM_SALT_LENGTH;
|
||||||
|
import static org.briarproject.briar.api.forum.ForumSharingManager.CLIENT_ID;
|
||||||
|
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_INVITATION;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
@@ -105,8 +109,7 @@ public class ForumSharingIntegrationTest
|
|||||||
|
|
||||||
// send invitation
|
// send invitation
|
||||||
forumSharingManager0
|
forumSharingManager0
|
||||||
.sendInvitation(forum0.getId(), contactId1From0, "Hi!",
|
.sendInvitation(forum0.getId(), contactId1From0, "Hi!");
|
||||||
clock.currentTimeMillis());
|
|
||||||
|
|
||||||
// sync first request message
|
// sync first request message
|
||||||
sync0To1(1, true);
|
sync0To1(1, true);
|
||||||
@@ -124,7 +127,7 @@ public class ForumSharingIntegrationTest
|
|||||||
|
|
||||||
// invitee has one invitation message from sharer
|
// invitee has one invitation message from sharer
|
||||||
List<InvitationMessage> list =
|
List<InvitationMessage> list =
|
||||||
new ArrayList<InvitationMessage>(forumSharingManager1
|
new ArrayList<>(forumSharingManager1
|
||||||
.getInvitationMessages(contactId0From1));
|
.getInvitationMessages(contactId0From1));
|
||||||
assertEquals(2, list.size());
|
assertEquals(2, list.size());
|
||||||
// check other things are alright with the forum message
|
// check other things are alright with the forum message
|
||||||
@@ -136,7 +139,6 @@ public class ForumSharingIntegrationTest
|
|||||||
assertEquals(forum0.getName(), invitation.getForumName());
|
assertEquals(forum0.getName(), invitation.getForumName());
|
||||||
assertEquals(contactId1From0, invitation.getContactId());
|
assertEquals(contactId1From0, invitation.getContactId());
|
||||||
assertEquals("Hi!", invitation.getMessage());
|
assertEquals("Hi!", invitation.getMessage());
|
||||||
assertTrue(invitation.canBeOpened());
|
|
||||||
} else {
|
} else {
|
||||||
ForumInvitationResponse response =
|
ForumInvitationResponse response =
|
||||||
(ForumInvitationResponse) m;
|
(ForumInvitationResponse) m;
|
||||||
@@ -163,8 +165,7 @@ public class ForumSharingIntegrationTest
|
|||||||
|
|
||||||
// send invitation
|
// send invitation
|
||||||
forumSharingManager0
|
forumSharingManager0
|
||||||
.sendInvitation(forum0.getId(), contactId1From0, null,
|
.sendInvitation(forum0.getId(), contactId1From0, null);
|
||||||
clock.currentTimeMillis());
|
|
||||||
|
|
||||||
// sync first request message
|
// sync first request message
|
||||||
sync0To1(1, true);
|
sync0To1(1, true);
|
||||||
@@ -184,7 +185,7 @@ public class ForumSharingIntegrationTest
|
|||||||
|
|
||||||
// invitee has one invitation message from sharer and one response
|
// invitee has one invitation message from sharer and one response
|
||||||
List<InvitationMessage> list =
|
List<InvitationMessage> list =
|
||||||
new ArrayList<InvitationMessage>(forumSharingManager1
|
new ArrayList<>(forumSharingManager1
|
||||||
.getInvitationMessages(contactId0From1));
|
.getInvitationMessages(contactId0From1));
|
||||||
assertEquals(2, list.size());
|
assertEquals(2, list.size());
|
||||||
// check things are alright with the forum message
|
// check things are alright with the forum message
|
||||||
@@ -196,7 +197,6 @@ public class ForumSharingIntegrationTest
|
|||||||
assertEquals(forum0.getName(), invitation.getForumName());
|
assertEquals(forum0.getName(), invitation.getForumName());
|
||||||
assertEquals(contactId1From0, invitation.getContactId());
|
assertEquals(contactId1From0, invitation.getContactId());
|
||||||
assertEquals(null, invitation.getMessage());
|
assertEquals(null, invitation.getMessage());
|
||||||
assertFalse(invitation.canBeOpened());
|
|
||||||
} else {
|
} else {
|
||||||
ForumInvitationResponse response =
|
ForumInvitationResponse response =
|
||||||
(ForumInvitationResponse) m;
|
(ForumInvitationResponse) m;
|
||||||
@@ -221,65 +221,7 @@ public class ForumSharingIntegrationTest
|
|||||||
|
|
||||||
// send invitation
|
// send invitation
|
||||||
forumSharingManager0
|
forumSharingManager0
|
||||||
.sendInvitation(forum0.getId(), contactId1From0, "Hi!",
|
.sendInvitation(forum0.getId(), contactId1From0, "Hi!");
|
||||||
clock.currentTimeMillis());
|
|
||||||
|
|
||||||
// sync first request message
|
|
||||||
sync0To1(1, true);
|
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
|
||||||
assertTrue(listener1.requestReceived);
|
|
||||||
|
|
||||||
// sync response back
|
|
||||||
sync1To0(1, true);
|
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
|
||||||
assertTrue(listener0.responseReceived);
|
|
||||||
|
|
||||||
// forum was added successfully
|
|
||||||
assertEquals(0, forumSharingManager0.getInvitations().size());
|
|
||||||
assertEquals(1, forumManager1.getForums().size());
|
|
||||||
assertTrue(forumManager1.getForums().contains(forum0));
|
|
||||||
|
|
||||||
// sharer shares forum with invitee
|
|
||||||
assertTrue(forumSharingManager0.getSharedWith(forum0.getId())
|
|
||||||
.contains(contact1From0));
|
|
||||||
// invitee gets forum shared by sharer
|
|
||||||
Contact contact0 = contactManager1.getContact(contactId1From0);
|
|
||||||
assertTrue(forumSharingManager1.getSharedWith(forum0.getId())
|
|
||||||
.contains(contact0));
|
|
||||||
|
|
||||||
// invitee un-subscribes from forum
|
|
||||||
forumManager1.removeForum(forum0);
|
|
||||||
|
|
||||||
// send leave message to sharer
|
|
||||||
sync1To0(1, true);
|
|
||||||
|
|
||||||
// forum is gone
|
|
||||||
assertEquals(0, forumSharingManager0.getInvitations().size());
|
|
||||||
assertEquals(0, forumManager1.getForums().size());
|
|
||||||
|
|
||||||
// sharer no longer shares forum with invitee
|
|
||||||
assertFalse(forumSharingManager0.getSharedWith(forum0.getId())
|
|
||||||
.contains(contact1From0));
|
|
||||||
// invitee no longer gets forum shared by sharer
|
|
||||||
assertFalse(forumSharingManager1.getSharedWith(forum0.getId())
|
|
||||||
.contains(contact0));
|
|
||||||
// forum can be shared again by sharer
|
|
||||||
assertTrue(forumSharingManager0
|
|
||||||
.canBeShared(forum0.getId(), contact1From0));
|
|
||||||
// invitee that left can not share again
|
|
||||||
assertFalse(forumSharingManager1
|
|
||||||
.canBeShared(forum0.getId(), contact0From1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSharerLeavesAfterFinished() throws Exception {
|
|
||||||
// initialize and let invitee accept all requests
|
|
||||||
listenToEvents(true);
|
|
||||||
|
|
||||||
// send invitation
|
|
||||||
forumSharingManager0
|
|
||||||
.sendInvitation(forum0.getId(), contactId1From0, null,
|
|
||||||
clock.currentTimeMillis());
|
|
||||||
|
|
||||||
// sync first request message
|
// sync first request message
|
||||||
sync0To1(1, true);
|
sync0To1(1, true);
|
||||||
@@ -302,7 +244,62 @@ public class ForumSharingIntegrationTest
|
|||||||
.contains(c1));
|
.contains(c1));
|
||||||
// invitee gets forum shared by sharer
|
// invitee gets forum shared by sharer
|
||||||
Contact contact0 = contactManager1.getContact(contactId1From0);
|
Contact contact0 = contactManager1.getContact(contactId1From0);
|
||||||
assertTrue(forumSharingManager1.getSharedWith(forum0.getId())
|
assertTrue(forumSharingManager1.getSharedBy(forum0.getId())
|
||||||
|
.contains(contact0));
|
||||||
|
|
||||||
|
// invitee un-subscribes from forum
|
||||||
|
forumManager1.removeForum(forum0);
|
||||||
|
|
||||||
|
// send leave message to sharer
|
||||||
|
sync1To0(1, true);
|
||||||
|
|
||||||
|
// forum is gone
|
||||||
|
assertEquals(0, forumSharingManager0.getInvitations().size());
|
||||||
|
assertEquals(0, forumManager1.getForums().size());
|
||||||
|
|
||||||
|
// sharer no longer shares forum with invitee
|
||||||
|
assertFalse(forumSharingManager0.getSharedWith(forum0.getId())
|
||||||
|
.contains(c1));
|
||||||
|
// invitee no longer gets forum shared by sharer
|
||||||
|
assertFalse(forumSharingManager1.getSharedBy(forum0.getId())
|
||||||
|
.contains(contact0));
|
||||||
|
// forum can be shared again
|
||||||
|
assertTrue(forumSharingManager0.canBeShared(forum0.getId(), c1));
|
||||||
|
Contact c0 = contactManager1.getContact(contactId0From1);
|
||||||
|
assertTrue(forumSharingManager1.canBeShared(forum0.getId(), c0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSharerLeavesAfterFinished() throws Exception {
|
||||||
|
// initialize and let invitee accept all requests
|
||||||
|
listenToEvents(true);
|
||||||
|
|
||||||
|
// send invitation
|
||||||
|
forumSharingManager0
|
||||||
|
.sendInvitation(forum0.getId(), contactId1From0, null);
|
||||||
|
|
||||||
|
// sync first request message
|
||||||
|
sync0To1(1, true);
|
||||||
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
|
assertTrue(listener1.requestReceived);
|
||||||
|
|
||||||
|
// sync response back
|
||||||
|
sync1To0(1, true);
|
||||||
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
|
assertTrue(listener0.responseReceived);
|
||||||
|
|
||||||
|
// forum was added successfully
|
||||||
|
assertEquals(0, forumSharingManager0.getInvitations().size());
|
||||||
|
assertEquals(1, forumManager1.getForums().size());
|
||||||
|
assertTrue(forumManager1.getForums().contains(forum0));
|
||||||
|
|
||||||
|
// sharer shares forum with invitee
|
||||||
|
Contact c1 = contactManager0.getContact(contactId1From0);
|
||||||
|
assertTrue(forumSharingManager0.getSharedWith(forum0.getId())
|
||||||
|
.contains(c1));
|
||||||
|
// invitee gets forum shared by sharer
|
||||||
|
Contact contact0 = contactManager1.getContact(contactId1From0);
|
||||||
|
assertTrue(forumSharingManager1.getSharedBy(forum0.getId())
|
||||||
.contains(contact0));
|
.contains(contact0));
|
||||||
|
|
||||||
// sharer un-subscribes from forum
|
// sharer un-subscribes from forum
|
||||||
@@ -320,7 +317,7 @@ public class ForumSharingIntegrationTest
|
|||||||
assertFalse(forumSharingManager1.getSharedWith(forum0.getId())
|
assertFalse(forumSharingManager1.getSharedWith(forum0.getId())
|
||||||
.contains(c0));
|
.contains(c0));
|
||||||
// sharer no longer gets forum shared by invitee
|
// sharer no longer gets forum shared by invitee
|
||||||
assertFalse(forumSharingManager1.getSharedWith(forum0.getId())
|
assertFalse(forumSharingManager1.getSharedBy(forum0.getId())
|
||||||
.contains(contact0));
|
.contains(contact0));
|
||||||
// forum can be shared again
|
// forum can be shared again
|
||||||
assertTrue(forumSharingManager1.canBeShared(forum0.getId(), c0));
|
assertTrue(forumSharingManager1.canBeShared(forum0.getId(), c0));
|
||||||
@@ -333,8 +330,7 @@ public class ForumSharingIntegrationTest
|
|||||||
|
|
||||||
// send invitation
|
// send invitation
|
||||||
forumSharingManager0
|
forumSharingManager0
|
||||||
.sendInvitation(forum0.getId(), contactId1From0, null,
|
.sendInvitation(forum0.getId(), contactId1From0, null);
|
||||||
clock.currentTimeMillis());
|
|
||||||
|
|
||||||
// sharer un-subscribes from forum
|
// sharer un-subscribes from forum
|
||||||
forumManager0.removeForum(forum0);
|
forumManager0.removeForum(forum0);
|
||||||
@@ -358,8 +354,7 @@ public class ForumSharingIntegrationTest
|
|||||||
|
|
||||||
// send invitation
|
// send invitation
|
||||||
forumSharingManager0
|
forumSharingManager0
|
||||||
.sendInvitation(forum0.getId(), contactId1From0, null,
|
.sendInvitation(forum0.getId(), contactId1From0, null);
|
||||||
clock.currentTimeMillis());
|
|
||||||
|
|
||||||
// sharer un-subscribes from forum
|
// sharer un-subscribes from forum
|
||||||
forumManager0.removeForum(forum0);
|
forumManager0.removeForum(forum0);
|
||||||
@@ -374,15 +369,14 @@ public class ForumSharingIntegrationTest
|
|||||||
assertEquals(1, forumManager1.getForums().size());
|
assertEquals(1, forumManager1.getForums().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test
|
||||||
public void testSharingSameForumWithEachOther() throws Exception {
|
public void testSessionIdReuse() throws Exception {
|
||||||
// initialize and let invitee accept all requests
|
// initialize and let invitee accept all requests
|
||||||
listenToEvents(true);
|
listenToEvents(true);
|
||||||
|
|
||||||
// send invitation
|
// send invitation
|
||||||
forumSharingManager0
|
forumSharingManager0
|
||||||
.sendInvitation(forum0.getId(), contactId1From0, "Hi!",
|
.sendInvitation(forum0.getId(), contactId1From0, "Hi!");
|
||||||
clock.currentTimeMillis());
|
|
||||||
|
|
||||||
// sync first request message
|
// sync first request message
|
||||||
sync0To1(1, true);
|
sync0To1(1, true);
|
||||||
@@ -397,11 +391,84 @@ public class ForumSharingIntegrationTest
|
|||||||
// forum was added successfully
|
// forum was added successfully
|
||||||
assertEquals(1, forumManager1.getForums().size());
|
assertEquals(1, forumManager1.getForums().size());
|
||||||
|
|
||||||
|
// reset event received state
|
||||||
|
listener1.requestReceived = false;
|
||||||
|
|
||||||
|
// get SessionId from invitation
|
||||||
|
List<InvitationMessage> list = new ArrayList<>(
|
||||||
|
forumSharingManager1
|
||||||
|
.getInvitationMessages(contactId0From1));
|
||||||
|
assertEquals(2, list.size());
|
||||||
|
InvitationMessage msg = list.get(0);
|
||||||
|
SessionId sessionId = msg.getSessionId();
|
||||||
|
assertEquals(sessionId, list.get(1).getSessionId());
|
||||||
|
|
||||||
|
// get all sorts of stuff needed to send a message
|
||||||
|
MessageQueueManager queue = c0.getMessageQueueManager();
|
||||||
|
Contact c1 = contactManager0.getContact(contactId1From0);
|
||||||
|
Group group = contactGroupFactory.createContactGroup(CLIENT_ID, c1);
|
||||||
|
long time = clock.currentTimeMillis();
|
||||||
|
BdfList bodyList = BdfList.of(SHARE_MSG_TYPE_INVITATION,
|
||||||
|
sessionId.getBytes(),
|
||||||
|
TestUtils.getRandomString(42),
|
||||||
|
TestUtils.getRandomBytes(FORUM_SALT_LENGTH)
|
||||||
|
);
|
||||||
|
byte[] body = clientHelper.toByteArray(bodyList);
|
||||||
|
|
||||||
|
// add the message to the queue
|
||||||
|
Transaction txn = db0.startTransaction(false);
|
||||||
|
try {
|
||||||
|
queue.sendMessage(txn, group, time, body, new Metadata());
|
||||||
|
db0.commitTransaction(txn);
|
||||||
|
} finally {
|
||||||
|
db0.endTransaction(txn);
|
||||||
|
}
|
||||||
|
|
||||||
|
// actually send the message
|
||||||
|
sync0To1(1, false);
|
||||||
|
// make sure there was no new request received
|
||||||
|
assertFalse(listener1.requestReceived);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSharingSameForumWithEachOther() throws Exception {
|
||||||
|
// initialize and let invitee accept all requests
|
||||||
|
listenToEvents(true);
|
||||||
|
|
||||||
|
// send invitation
|
||||||
|
forumSharingManager0
|
||||||
|
.sendInvitation(forum0.getId(), contactId1From0, "Hi!");
|
||||||
|
|
||||||
|
// sync first request message
|
||||||
|
sync0To1(1, true);
|
||||||
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
|
assertTrue(listener1.requestReceived);
|
||||||
|
|
||||||
|
// sync response back
|
||||||
|
sync1To0(1, true);
|
||||||
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
|
assertTrue(listener0.responseReceived);
|
||||||
|
|
||||||
|
// forum was added successfully
|
||||||
|
assertEquals(1, forumManager1.getForums().size());
|
||||||
|
assertEquals(2,
|
||||||
|
forumSharingManager0.getInvitationMessages(contactId1From0)
|
||||||
|
.size());
|
||||||
|
|
||||||
// invitee now shares same forum back
|
// invitee now shares same forum back
|
||||||
forumSharingManager1.sendInvitation(forum0.getId(),
|
forumSharingManager1.sendInvitation(forum0.getId(),
|
||||||
contactId0From1,
|
contactId0From1,
|
||||||
"I am re-sharing this forum with you.",
|
"I am re-sharing this forum with you.");
|
||||||
clock.currentTimeMillis());
|
|
||||||
|
// sync re-share invitation
|
||||||
|
sync1To0(1, false);
|
||||||
|
|
||||||
|
// make sure that no new request was received
|
||||||
|
assertFalse(listener0.requestReceived);
|
||||||
|
assertEquals(2,
|
||||||
|
forumSharingManager0.getInvitationMessages(contactId1From0)
|
||||||
|
.size());
|
||||||
|
assertEquals(0, forumSharingManager0.getInvitations().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -411,48 +478,62 @@ public class ForumSharingIntegrationTest
|
|||||||
|
|
||||||
// invitee adds the same forum
|
// invitee adds the same forum
|
||||||
Transaction txn = db1.startTransaction(false);
|
Transaction txn = db1.startTransaction(false);
|
||||||
forumManager1.addForum(txn, forum0);
|
db1.addGroup(txn, forum0.getGroup());
|
||||||
db1.commitTransaction(txn);
|
db1.commitTransaction(txn);
|
||||||
db1.endTransaction(txn);
|
db1.endTransaction(txn);
|
||||||
|
|
||||||
// send invitation
|
// send invitation
|
||||||
forumSharingManager0
|
forumSharingManager0
|
||||||
.sendInvitation(forum0.getId(), contactId1From0, "Hi!",
|
.sendInvitation(forum0.getId(), contactId1From0, "Hi!");
|
||||||
clock.currentTimeMillis());
|
|
||||||
|
|
||||||
// invitee now shares same forum back
|
// invitee now shares same forum back
|
||||||
forumSharingManager1.sendInvitation(forum0.getId(),
|
forumSharingManager1.sendInvitation(forum0.getId(),
|
||||||
contactId0From1, "I am re-sharing this forum with you.",
|
contactId0From1, "I am re-sharing this forum with you.");
|
||||||
clock.currentTimeMillis());
|
|
||||||
|
|
||||||
// prevent automatic responses
|
// find out who should be Alice, because of random keys
|
||||||
respond = false;
|
Bytes key0 = new Bytes(author0.getPublicKey());
|
||||||
|
Bytes key1 = new Bytes(author1.getPublicKey());
|
||||||
|
|
||||||
// only now sync first request message
|
// only now sync first request message
|
||||||
sync0To1(1, true);
|
boolean alice = key1.compareTo(key0) < 0;
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
if (alice) {
|
||||||
assertTrue(listener1.requestReceived);
|
sync0To1(1, false);
|
||||||
|
assertFalse(listener1.requestReceived);
|
||||||
|
} else {
|
||||||
|
sync0To1(1, true);
|
||||||
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
|
assertTrue(listener1.requestReceived);
|
||||||
|
}
|
||||||
|
|
||||||
// sync second invitation which counts as accept
|
// sync second invitation
|
||||||
sync1To0(1, true);
|
alice = key0.compareTo(key1) < 0;
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
if (alice) {
|
||||||
assertTrue(listener0.requestReceived);
|
sync1To0(1, false);
|
||||||
|
assertFalse(listener0.requestReceived);
|
||||||
|
|
||||||
// both peers should share the forum with each other now
|
// sharer did not receive request, but response to own request
|
||||||
assertTrue(forumSharingManager0.getSharedWith(forum0.getId())
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
.contains(contact1From0));
|
assertTrue(listener0.responseReceived);
|
||||||
assertTrue(forumSharingManager1.getSharedWith(forum0.getId())
|
|
||||||
.contains(contact0From1));
|
|
||||||
|
|
||||||
// and both have each other's invitations (and no response)
|
assertEquals(2, forumSharingManager0
|
||||||
assertEquals(2, forumSharingManager0
|
.getInvitationMessages(contactId1From0).size());
|
||||||
.getInvitationMessages(contactId1From0).size());
|
assertEquals(3, forumSharingManager1
|
||||||
assertEquals(2, forumSharingManager1
|
.getInvitationMessages(contactId0From1).size());
|
||||||
.getInvitationMessages(contactId0From1).size());
|
} else {
|
||||||
|
sync1To0(1, true);
|
||||||
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
|
assertTrue(listener0.requestReceived);
|
||||||
|
|
||||||
// there are no more open invitations
|
// send response from sharer to invitee and make sure it arrived
|
||||||
assertTrue(forumSharingManager0.getInvitations().isEmpty());
|
sync0To1(1, true);
|
||||||
assertTrue(forumSharingManager1.getInvitations().isEmpty());
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
|
assertTrue(listener1.responseReceived);
|
||||||
|
|
||||||
|
assertEquals(3, forumSharingManager0
|
||||||
|
.getInvitationMessages(contactId1From0).size());
|
||||||
|
assertEquals(2, forumSharingManager1
|
||||||
|
.getInvitationMessages(contactId0From1).size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -462,8 +543,7 @@ public class ForumSharingIntegrationTest
|
|||||||
|
|
||||||
// send invitation
|
// send invitation
|
||||||
forumSharingManager0
|
forumSharingManager0
|
||||||
.sendInvitation(forum0.getId(), contactId1From0, "Hi!",
|
.sendInvitation(forum0.getId(), contactId1From0, "Hi!");
|
||||||
clock.currentTimeMillis());
|
|
||||||
|
|
||||||
// sync first request message
|
// sync first request message
|
||||||
sync0To1(1, true);
|
sync0To1(1, true);
|
||||||
@@ -480,12 +560,18 @@ public class ForumSharingIntegrationTest
|
|||||||
assertEquals(1,
|
assertEquals(1,
|
||||||
forumSharingManager0.getSharedWith(forum0.getId()).size());
|
forumSharingManager0.getSharedWith(forum0.getId()).size());
|
||||||
|
|
||||||
|
// remember SessionId from invitation
|
||||||
|
List<InvitationMessage> list = new ArrayList<>(
|
||||||
|
forumSharingManager1
|
||||||
|
.getInvitationMessages(contactId0From1));
|
||||||
|
assertEquals(2, list.size());
|
||||||
|
InvitationMessage msg = list.get(0);
|
||||||
|
SessionId sessionId = msg.getSessionId();
|
||||||
|
assertEquals(sessionId, list.get(1).getSessionId());
|
||||||
|
|
||||||
// contacts now remove each other
|
// contacts now remove each other
|
||||||
removeAllContacts();
|
removeAllContacts();
|
||||||
|
|
||||||
// invitee still has forum
|
|
||||||
assertEquals(1, forumManager1.getForums().size());
|
|
||||||
|
|
||||||
// make sure sharer does share the forum with nobody now
|
// make sure sharer does share the forum with nobody now
|
||||||
assertEquals(0,
|
assertEquals(0,
|
||||||
forumSharingManager0.getSharedWith(forum0.getId()).size());
|
forumSharingManager0.getSharedWith(forum0.getId()).size());
|
||||||
@@ -494,30 +580,35 @@ public class ForumSharingIntegrationTest
|
|||||||
addDefaultContacts();
|
addDefaultContacts();
|
||||||
addContacts1And2();
|
addContacts1And2();
|
||||||
|
|
||||||
// forum can be shared with contacts again
|
// get all sorts of stuff needed to send a message
|
||||||
assertTrue(forumSharingManager0
|
MessageQueueManager queue = c0.getMessageQueueManager();
|
||||||
.canBeShared(forum0.getId(), contact1From0));
|
Contact c1 = contactManager0.getContact(contactId1From0);
|
||||||
assertTrue(forumSharingManager0
|
Group group = contactGroupFactory.createContactGroup(CLIENT_ID, c1);
|
||||||
.canBeShared(forum0.getId(), contact2From0));
|
long time = clock.currentTimeMillis();
|
||||||
// send invitation
|
|
||||||
forumSharingManager0
|
|
||||||
.sendInvitation(forum0.getId(), contactId1From0, "Hi!",
|
|
||||||
clock.currentTimeMillis());
|
|
||||||
|
|
||||||
// sync first request message
|
// construct a new message re-using the old SessionId
|
||||||
|
BdfList bodyList = BdfList.of(SHARE_MSG_TYPE_INVITATION,
|
||||||
|
sessionId.getBytes(),
|
||||||
|
TestUtils.getRandomString(42),
|
||||||
|
TestUtils.getRandomBytes(FORUM_SALT_LENGTH)
|
||||||
|
);
|
||||||
|
byte[] body = clientHelper.toByteArray(bodyList);
|
||||||
|
|
||||||
|
// add the message to the queue
|
||||||
|
Transaction txn = db0.startTransaction(false);
|
||||||
|
try {
|
||||||
|
queue.sendMessage(txn, group, time, body, new Metadata());
|
||||||
|
db0.commitTransaction(txn);
|
||||||
|
} finally {
|
||||||
|
db0.endTransaction(txn);
|
||||||
|
}
|
||||||
|
|
||||||
|
// actually send the message
|
||||||
sync0To1(1, true);
|
sync0To1(1, true);
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
|
// make sure the new request was received with the same sessionId
|
||||||
|
// as proof that the state got deleted along with contacts
|
||||||
assertTrue(listener1.requestReceived);
|
assertTrue(listener1.requestReceived);
|
||||||
|
|
||||||
// sync response back
|
|
||||||
sync1To0(1, true);
|
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
|
||||||
assertTrue(listener0.responseReceived);
|
|
||||||
|
|
||||||
// forum is still there
|
|
||||||
assertEquals(1, forumManager1.getForums().size());
|
|
||||||
assertEquals(1,
|
|
||||||
forumSharingManager0.getSharedWith(forum0.getId()).size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -538,16 +629,14 @@ public class ForumSharingIntegrationTest
|
|||||||
|
|
||||||
// send invitation
|
// send invitation
|
||||||
forumSharingManager0
|
forumSharingManager0
|
||||||
.sendInvitation(forum0.getId(), contactId1From0, "Hi!",
|
.sendInvitation(forum0.getId(), contactId1From0, "Hi!");
|
||||||
clock.currentTimeMillis());
|
|
||||||
// sync first request message
|
// sync first request message
|
||||||
sync0To1(1, true);
|
sync0To1(1, true);
|
||||||
|
|
||||||
// second sharer sends invitation for same forum
|
// second sharer sends invitation for same forum
|
||||||
assertTrue(contactId1From2 != null);
|
assertTrue(contactId1From2 != null);
|
||||||
forumSharingManager2
|
forumSharingManager2
|
||||||
.sendInvitation(forum0.getId(), contactId1From2, null,
|
.sendInvitation(forum0.getId(), contactId1From2, null);
|
||||||
clock.currentTimeMillis());
|
|
||||||
// sync second request message
|
// sync second request message
|
||||||
sync2To1(1, true);
|
sync2To1(1, true);
|
||||||
|
|
||||||
@@ -557,6 +646,13 @@ public class ForumSharingIntegrationTest
|
|||||||
assertEquals(1, forums.size());
|
assertEquals(1, forums.size());
|
||||||
assertEquals(2, forums.iterator().next().getNewSharers().size());
|
assertEquals(2, forums.iterator().next().getNewSharers().size());
|
||||||
assertEquals(forum0, forums.iterator().next().getShareable());
|
assertEquals(forum0, forums.iterator().next().getShareable());
|
||||||
|
assertEquals(2,
|
||||||
|
forumSharingManager1.getSharedBy(forum0.getId()).size());
|
||||||
|
|
||||||
|
// make sure both sharers actually share the forum
|
||||||
|
Collection<Contact> contacts =
|
||||||
|
forumSharingManager1.getSharedBy(forum0.getId());
|
||||||
|
assertEquals(2, contacts.size());
|
||||||
|
|
||||||
// answer second request
|
// answer second request
|
||||||
assertNotNull(contactId2From1);
|
assertNotNull(contactId2From1);
|
||||||
@@ -575,11 +671,6 @@ public class ForumSharingIntegrationTest
|
|||||||
sync1To0(1, true);
|
sync1To0(1, true);
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
assertTrue(listener0.responseReceived);
|
assertTrue(listener0.responseReceived);
|
||||||
|
|
||||||
// make sure both sharers actually share the forum
|
|
||||||
Collection<Contact> contacts =
|
|
||||||
forumSharingManager1.getSharedWith(forum0.getId());
|
|
||||||
assertEquals(2, contacts.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -589,8 +680,7 @@ public class ForumSharingIntegrationTest
|
|||||||
|
|
||||||
// send invitation
|
// send invitation
|
||||||
forumSharingManager0
|
forumSharingManager0
|
||||||
.sendInvitation(forum0.getId(), contactId1From0, "Hi!",
|
.sendInvitation(forum0.getId(), contactId1From0, "Hi!");
|
||||||
clock.currentTimeMillis());
|
|
||||||
|
|
||||||
// sync first request message
|
// sync first request message
|
||||||
sync0To1(1, true);
|
sync0To1(1, true);
|
||||||
@@ -602,7 +692,7 @@ public class ForumSharingIntegrationTest
|
|||||||
|
|
||||||
// sharer posts into the forum
|
// sharer posts into the forum
|
||||||
long time = clock.currentTimeMillis();
|
long time = clock.currentTimeMillis();
|
||||||
String body = getRandomString(42);
|
String body = TestUtils.getRandomString(42);
|
||||||
ForumPost p = forumPostFactory
|
ForumPost p = forumPostFactory
|
||||||
.createPost(forum0.getId(), time, null, author0,
|
.createPost(forum0.getId(), time, null, author0,
|
||||||
body);
|
body);
|
||||||
@@ -621,7 +711,7 @@ public class ForumSharingIntegrationTest
|
|||||||
|
|
||||||
// now invitee creates a post
|
// now invitee creates a post
|
||||||
time = clock.currentTimeMillis();
|
time = clock.currentTimeMillis();
|
||||||
body = getRandomString(42);
|
body = TestUtils.getRandomString(42);
|
||||||
p = forumPostFactory
|
p = forumPostFactory
|
||||||
.createPost(forum0.getId(), time, null, author1,
|
.createPost(forum0.getId(), time, null, author1,
|
||||||
body);
|
body);
|
||||||
@@ -651,8 +741,7 @@ public class ForumSharingIntegrationTest
|
|||||||
|
|
||||||
// send invitation again
|
// send invitation again
|
||||||
forumSharingManager0
|
forumSharingManager0
|
||||||
.sendInvitation(forum0.getId(), contactId1From0, "Hi!",
|
.sendInvitation(forum0.getId(), contactId1From0, "Hi!");
|
||||||
clock.currentTimeMillis());
|
|
||||||
|
|
||||||
// sync first request message
|
// sync first request message
|
||||||
sync0To1(1, true);
|
sync0To1(1, true);
|
||||||
@@ -664,7 +753,7 @@ public class ForumSharingIntegrationTest
|
|||||||
|
|
||||||
// now invitee creates a post
|
// now invitee creates a post
|
||||||
time = clock.currentTimeMillis();
|
time = clock.currentTimeMillis();
|
||||||
body = getRandomString(42);
|
body = TestUtils.getRandomString(42);
|
||||||
p = forumPostFactory
|
p = forumPostFactory
|
||||||
.createPost(forum0.getId(), time, null, author1,
|
.createPost(forum0.getId(), time, null, author1,
|
||||||
body);
|
body);
|
||||||
@@ -706,10 +795,8 @@ public class ForumSharingIntegrationTest
|
|||||||
requestReceived = true;
|
requestReceived = true;
|
||||||
Forum f = event.getShareable();
|
Forum f = event.getShareable();
|
||||||
try {
|
try {
|
||||||
if (respond) {
|
Contact c = contactManager0.getContact(contactId1From0);
|
||||||
Contact c = contactManager0.getContact(contactId1From0);
|
forumSharingManager0.respondToInvitation(f, c, true);
|
||||||
forumSharingManager0.respondToInvitation(f, c, true);
|
|
||||||
}
|
|
||||||
} catch (DbException ex) {
|
} catch (DbException ex) {
|
||||||
eventWaiter.rethrow(ex);
|
eventWaiter.rethrow(ex);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -723,6 +810,7 @@ public class ForumSharingIntegrationTest
|
|||||||
private class InviteeListener implements EventListener {
|
private class InviteeListener implements EventListener {
|
||||||
|
|
||||||
private volatile boolean requestReceived = false;
|
private volatile boolean requestReceived = false;
|
||||||
|
private volatile boolean responseReceived = false;
|
||||||
|
|
||||||
private final boolean accept, answer;
|
private final boolean accept, answer;
|
||||||
|
|
||||||
@@ -744,13 +832,13 @@ public class ForumSharingIntegrationTest
|
|||||||
if (!answer) return;
|
if (!answer) return;
|
||||||
Forum f = event.getShareable();
|
Forum f = event.getShareable();
|
||||||
try {
|
try {
|
||||||
|
eventWaiter.assertEquals(1,
|
||||||
|
forumSharingManager1.getInvitations().size());
|
||||||
|
SharingInvitationItem invitation =
|
||||||
|
forumSharingManager1.getInvitations().iterator()
|
||||||
|
.next();
|
||||||
|
eventWaiter.assertEquals(f, invitation.getShareable());
|
||||||
if (respond) {
|
if (respond) {
|
||||||
eventWaiter.assertEquals(1,
|
|
||||||
forumSharingManager1.getInvitations().size());
|
|
||||||
SharingInvitationItem invitation =
|
|
||||||
forumSharingManager1.getInvitations().iterator()
|
|
||||||
.next();
|
|
||||||
eventWaiter.assertEquals(f, invitation.getShareable());
|
|
||||||
Contact c =
|
Contact c =
|
||||||
contactManager1
|
contactManager1
|
||||||
.getContact(event.getContactId());
|
.getContact(event.getContactId());
|
||||||
@@ -767,6 +855,7 @@ public class ForumSharingIntegrationTest
|
|||||||
ForumInvitationResponseReceivedEvent event =
|
ForumInvitationResponseReceivedEvent event =
|
||||||
(ForumInvitationResponseReceivedEvent) e;
|
(ForumInvitationResponseReceivedEvent) e;
|
||||||
eventWaiter.assertEquals(contactId0From1, event.getContactId());
|
eventWaiter.assertEquals(contactId0From1, event.getContactId());
|
||||||
|
responseReceived = true;
|
||||||
eventWaiter.resume();
|
eventWaiter.resume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
package org.briarproject.briar.privategroup.invitation;
|
package org.briarproject;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.sync.Group;
|
import org.briarproject.bramble.api.sync.Group;
|
||||||
import org.briarproject.bramble.test.TestDatabaseModule;
|
|
||||||
import org.briarproject.briar.api.client.ProtocolStateException;
|
import org.briarproject.briar.api.client.ProtocolStateException;
|
||||||
import org.briarproject.briar.api.privategroup.GroupMessage;
|
import org.briarproject.briar.api.privategroup.GroupMessage;
|
||||||
import org.briarproject.briar.api.privategroup.PrivateGroup;
|
import org.briarproject.briar.api.privategroup.PrivateGroup;
|
||||||
@@ -12,10 +11,6 @@ import org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager
|
|||||||
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationRequest;
|
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationRequest;
|
||||||
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationResponse;
|
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationResponse;
|
||||||
import org.briarproject.briar.api.sharing.InvitationMessage;
|
import org.briarproject.briar.api.sharing.InvitationMessage;
|
||||||
import org.briarproject.briar.api.sharing.InvitationResponse;
|
|
||||||
import org.briarproject.briar.test.BriarIntegrationTest;
|
|
||||||
import org.briarproject.briar.test.BriarIntegrationTestComponent;
|
|
||||||
import org.briarproject.briar.test.DaggerBriarIntegrationTestComponent;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@@ -23,11 +18,11 @@ import java.util.Collection;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import static org.briarproject.briar.test.BriarTestUtils.assertGroupCount;
|
import static junit.framework.TestCase.fail;
|
||||||
|
import static org.briarproject.TestUtils.assertGroupCount;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
|
|
||||||
public class GroupInvitationIntegrationTest
|
public class GroupInvitationIntegrationTest
|
||||||
extends BriarIntegrationTest<BriarIntegrationTestComponent> {
|
extends BriarIntegrationTest<BriarIntegrationTestComponent> {
|
||||||
@@ -98,13 +93,12 @@ public class GroupInvitationIntegrationTest
|
|||||||
GroupInvitationRequest request =
|
GroupInvitationRequest request =
|
||||||
(GroupInvitationRequest) messages.iterator().next();
|
(GroupInvitationRequest) messages.iterator().next();
|
||||||
assertEquals(msg, request.getMessage());
|
assertEquals(msg, request.getMessage());
|
||||||
assertEquals(author0, request.getShareable().getCreator());
|
assertEquals(author0, request.getCreator());
|
||||||
assertEquals(timestamp, request.getTimestamp());
|
assertEquals(timestamp, request.getTimestamp());
|
||||||
assertEquals(contactId0From1, request.getContactId());
|
assertEquals(contactId0From1, request.getContactId());
|
||||||
assertEquals(privateGroup0.getName(), request.getShareable().getName());
|
assertEquals(privateGroup0.getName(), request.getGroupName());
|
||||||
assertFalse(request.isLocal());
|
assertFalse(request.isLocal());
|
||||||
assertFalse(request.isRead());
|
assertFalse(request.isRead());
|
||||||
assertFalse(request.canBeOpened());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -125,7 +119,7 @@ public class GroupInvitationIntegrationTest
|
|||||||
for (InvitationMessage m : messages) {
|
for (InvitationMessage m : messages) {
|
||||||
if (m instanceof GroupInvitationResponse) {
|
if (m instanceof GroupInvitationResponse) {
|
||||||
foundResponse = true;
|
foundResponse = true;
|
||||||
InvitationResponse response = (GroupInvitationResponse) m;
|
GroupInvitationResponse response = (GroupInvitationResponse) m;
|
||||||
assertEquals(contactId0From1, response.getContactId());
|
assertEquals(contactId0From1, response.getContactId());
|
||||||
assertTrue(response.isLocal());
|
assertTrue(response.isLocal());
|
||||||
assertFalse(response.wasAccepted());
|
assertFalse(response.wasAccepted());
|
||||||
@@ -142,7 +136,7 @@ public class GroupInvitationIntegrationTest
|
|||||||
for (InvitationMessage m : messages) {
|
for (InvitationMessage m : messages) {
|
||||||
if (m instanceof GroupInvitationResponse) {
|
if (m instanceof GroupInvitationResponse) {
|
||||||
foundResponse = true;
|
foundResponse = true;
|
||||||
InvitationResponse response = (GroupInvitationResponse) m;
|
GroupInvitationResponse response = (GroupInvitationResponse) m;
|
||||||
assertEquals(contactId0From1, response.getContactId());
|
assertEquals(contactId0From1, response.getContactId());
|
||||||
assertFalse(response.isLocal());
|
assertFalse(response.isLocal());
|
||||||
assertFalse(response.wasAccepted());
|
assertFalse(response.wasAccepted());
|
||||||
@@ -174,10 +168,8 @@ public class GroupInvitationIntegrationTest
|
|||||||
for (InvitationMessage m : messages) {
|
for (InvitationMessage m : messages) {
|
||||||
if (m instanceof GroupInvitationResponse) {
|
if (m instanceof GroupInvitationResponse) {
|
||||||
foundResponse = true;
|
foundResponse = true;
|
||||||
InvitationResponse response = (GroupInvitationResponse) m;
|
GroupInvitationResponse response = (GroupInvitationResponse) m;
|
||||||
assertTrue(response.wasAccepted());
|
assertTrue(response.wasAccepted());
|
||||||
} else {
|
|
||||||
assertTrue(((GroupInvitationRequest) m).canBeOpened());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assertTrue(foundResponse);
|
assertTrue(foundResponse);
|
||||||
@@ -191,7 +183,7 @@ public class GroupInvitationIntegrationTest
|
|||||||
for (InvitationMessage m : messages) {
|
for (InvitationMessage m : messages) {
|
||||||
if (m instanceof GroupInvitationResponse) {
|
if (m instanceof GroupInvitationResponse) {
|
||||||
foundResponse = true;
|
foundResponse = true;
|
||||||
InvitationResponse response = (GroupInvitationResponse) m;
|
GroupInvitationResponse response = (GroupInvitationResponse) m;
|
||||||
assertTrue(response.wasAccepted());
|
assertTrue(response.wasAccepted());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -333,9 +325,6 @@ public class GroupInvitationIntegrationTest
|
|||||||
// Creator's leave message is delivered to invitee
|
// Creator's leave message is delivered to invitee
|
||||||
sync0To1(1, true);
|
sync0To1(1, true);
|
||||||
|
|
||||||
// invitee should have no more open invitations
|
|
||||||
assertTrue(groupInvitationManager1.getInvitations().isEmpty());
|
|
||||||
|
|
||||||
// Invitee declines invitation, but it's no longer open - no exception
|
// Invitee declines invitation, but it's no longer open - no exception
|
||||||
// as the action has succeeded
|
// as the action has succeeded
|
||||||
assertEquals(0, groupManager1.getPrivateGroups().size());
|
assertEquals(0, groupManager1.getPrivateGroups().size());
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.briar.messaging;
|
package org.briarproject;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.UniqueId;
|
import org.briarproject.bramble.api.UniqueId;
|
||||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
@@ -8,22 +8,19 @@ import org.briarproject.bramble.api.identity.LocalAuthor;
|
|||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.bramble.system.SystemModule;
|
import org.briarproject.bramble.system.SystemModule;
|
||||||
import org.briarproject.bramble.test.TestUtils;
|
|
||||||
import org.briarproject.bramble.util.StringUtils;
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
import org.briarproject.briar.api.forum.ForumConstants;
|
import org.briarproject.briar.api.forum.ForumConstants;
|
||||||
import org.briarproject.briar.api.forum.ForumPost;
|
import org.briarproject.briar.api.forum.ForumPost;
|
||||||
import org.briarproject.briar.api.forum.ForumPostFactory;
|
import org.briarproject.briar.api.forum.ForumPostFactory;
|
||||||
import org.briarproject.briar.api.messaging.PrivateMessage;
|
import org.briarproject.briar.api.messaging.PrivateMessage;
|
||||||
import org.briarproject.briar.api.messaging.PrivateMessageFactory;
|
import org.briarproject.briar.api.messaging.PrivateMessageFactory;
|
||||||
import org.briarproject.briar.test.BriarTestCase;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_PACKET_PAYLOAD_LENGTH;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_RECORD_PAYLOAD_LENGTH;
|
|
||||||
import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_POST_BODY_LENGTH;
|
import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_POST_BODY_LENGTH;
|
||||||
import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH;
|
import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
@@ -49,7 +46,7 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testPrivateMessageFitsIntoPacket() throws Exception {
|
public void testPrivateMessageFitsIntoPacket() throws Exception {
|
||||||
// Create a maximum-length private message
|
// Create a maximum-length private message
|
||||||
GroupId groupId = new GroupId(getRandomId());
|
GroupId groupId = new GroupId(TestUtils.getRandomId());
|
||||||
long timestamp = Long.MAX_VALUE;
|
long timestamp = Long.MAX_VALUE;
|
||||||
String body =
|
String body =
|
||||||
StringUtils.fromUtf8(new byte[MAX_PRIVATE_MESSAGE_BODY_LENGTH]);
|
StringUtils.fromUtf8(new byte[MAX_PRIVATE_MESSAGE_BODY_LENGTH]);
|
||||||
@@ -59,7 +56,7 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
|
|||||||
int length = message.getMessage().getRaw().length;
|
int length = message.getMessage().getRaw().length;
|
||||||
assertTrue(
|
assertTrue(
|
||||||
length > UniqueId.LENGTH + 8 + MAX_PRIVATE_MESSAGE_BODY_LENGTH);
|
length > UniqueId.LENGTH + 8 + MAX_PRIVATE_MESSAGE_BODY_LENGTH);
|
||||||
assertTrue(length <= MAX_RECORD_PAYLOAD_LENGTH);
|
assertTrue(length <= MAX_PACKET_PAYLOAD_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -73,9 +70,9 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
|
|||||||
.createLocalAuthor(authorName, authorPublic,
|
.createLocalAuthor(authorName, authorPublic,
|
||||||
privateKey.getEncoded());
|
privateKey.getEncoded());
|
||||||
// Create a maximum-length forum post
|
// Create a maximum-length forum post
|
||||||
GroupId groupId = new GroupId(getRandomId());
|
GroupId groupId = new GroupId(TestUtils.getRandomId());
|
||||||
long timestamp = Long.MAX_VALUE;
|
long timestamp = Long.MAX_VALUE;
|
||||||
MessageId parent = new MessageId(getRandomId());
|
MessageId parent = new MessageId(TestUtils.getRandomId());
|
||||||
String body = TestUtils.getRandomString(MAX_FORUM_POST_BODY_LENGTH);
|
String body = TestUtils.getRandomString(MAX_FORUM_POST_BODY_LENGTH);
|
||||||
ForumPost post = forumPostFactory.createPost(groupId,
|
ForumPost post = forumPostFactory.createPost(groupId,
|
||||||
timestamp, parent, author, body);
|
timestamp, parent, author, body);
|
||||||
@@ -85,7 +82,7 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
|
|||||||
+ MAX_AUTHOR_NAME_LENGTH + MAX_PUBLIC_KEY_LENGTH
|
+ MAX_AUTHOR_NAME_LENGTH + MAX_PUBLIC_KEY_LENGTH
|
||||||
+ ForumConstants.MAX_CONTENT_TYPE_LENGTH
|
+ ForumConstants.MAX_CONTENT_TYPE_LENGTH
|
||||||
+ MAX_FORUM_POST_BODY_LENGTH);
|
+ MAX_FORUM_POST_BODY_LENGTH);
|
||||||
assertTrue(length <= MAX_RECORD_PAYLOAD_LENGTH);
|
assertTrue(length <= MAX_PACKET_PAYLOAD_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void injectEagerSingletons(
|
private static void injectEagerSingletons(
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.briar.messaging;
|
package org.briarproject;
|
||||||
|
|
||||||
import org.briarproject.bramble.client.ClientModule;
|
import org.briarproject.bramble.client.ClientModule;
|
||||||
import org.briarproject.bramble.crypto.CryptoModule;
|
import org.briarproject.bramble.crypto.CryptoModule;
|
||||||
@@ -8,11 +8,9 @@ import org.briarproject.bramble.event.EventModule;
|
|||||||
import org.briarproject.bramble.identity.IdentityModule;
|
import org.briarproject.bramble.identity.IdentityModule;
|
||||||
import org.briarproject.bramble.sync.SyncModule;
|
import org.briarproject.bramble.sync.SyncModule;
|
||||||
import org.briarproject.bramble.system.SystemModule;
|
import org.briarproject.bramble.system.SystemModule;
|
||||||
import org.briarproject.bramble.test.TestDatabaseModule;
|
|
||||||
import org.briarproject.bramble.test.TestLifecycleModule;
|
|
||||||
import org.briarproject.bramble.test.TestSeedProviderModule;
|
|
||||||
import org.briarproject.briar.client.BriarClientModule;
|
import org.briarproject.briar.client.BriarClientModule;
|
||||||
import org.briarproject.briar.forum.ForumModule;
|
import org.briarproject.briar.forum.ForumModule;
|
||||||
|
import org.briarproject.briar.messaging.MessagingModule;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.briar.privategroup;
|
package org.briarproject;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.contact.Contact;
|
import org.briarproject.bramble.api.contact.Contact;
|
||||||
import org.briarproject.bramble.api.contact.ContactId;
|
import org.briarproject.bramble.api.contact.ContactId;
|
||||||
@@ -6,7 +6,6 @@ import org.briarproject.bramble.api.db.DbException;
|
|||||||
import org.briarproject.bramble.api.identity.AuthorId;
|
import org.briarproject.bramble.api.identity.AuthorId;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.bramble.test.TestDatabaseModule;
|
|
||||||
import org.briarproject.briar.api.privategroup.GroupMember;
|
import org.briarproject.briar.api.privategroup.GroupMember;
|
||||||
import org.briarproject.briar.api.privategroup.GroupMessage;
|
import org.briarproject.briar.api.privategroup.GroupMessage;
|
||||||
import org.briarproject.briar.api.privategroup.GroupMessageHeader;
|
import org.briarproject.briar.api.privategroup.GroupMessageHeader;
|
||||||
@@ -14,9 +13,6 @@ import org.briarproject.briar.api.privategroup.JoinMessageHeader;
|
|||||||
import org.briarproject.briar.api.privategroup.PrivateGroup;
|
import org.briarproject.briar.api.privategroup.PrivateGroup;
|
||||||
import org.briarproject.briar.api.privategroup.PrivateGroupManager;
|
import org.briarproject.briar.api.privategroup.PrivateGroupManager;
|
||||||
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager;
|
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager;
|
||||||
import org.briarproject.briar.test.BriarIntegrationTest;
|
|
||||||
import org.briarproject.briar.test.BriarIntegrationTestComponent;
|
|
||||||
import org.briarproject.briar.test.DaggerBriarIntegrationTestComponent;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
package org.briarproject.briar.privategroup;
|
package org.briarproject;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.contact.Contact;
|
import org.briarproject.bramble.api.contact.Contact;
|
||||||
import org.briarproject.bramble.api.data.BdfList;
|
import org.briarproject.bramble.api.data.BdfList;
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.bramble.test.TestDatabaseModule;
|
|
||||||
import org.briarproject.briar.api.client.MessageTracker.GroupCount;
|
import org.briarproject.briar.api.client.MessageTracker.GroupCount;
|
||||||
import org.briarproject.briar.api.privategroup.GroupMember;
|
import org.briarproject.briar.api.privategroup.GroupMember;
|
||||||
import org.briarproject.briar.api.privategroup.GroupMessage;
|
import org.briarproject.briar.api.privategroup.GroupMessage;
|
||||||
@@ -13,18 +12,14 @@ import org.briarproject.briar.api.privategroup.GroupMessageHeader;
|
|||||||
import org.briarproject.briar.api.privategroup.JoinMessageHeader;
|
import org.briarproject.briar.api.privategroup.JoinMessageHeader;
|
||||||
import org.briarproject.briar.api.privategroup.PrivateGroup;
|
import org.briarproject.briar.api.privategroup.PrivateGroup;
|
||||||
import org.briarproject.briar.api.privategroup.PrivateGroupManager;
|
import org.briarproject.briar.api.privategroup.PrivateGroupManager;
|
||||||
import org.briarproject.briar.test.BriarIntegrationTest;
|
|
||||||
import org.briarproject.briar.test.BriarIntegrationTestComponent;
|
|
||||||
import org.briarproject.briar.test.DaggerBriarIntegrationTestComponent;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import static org.briarproject.TestUtils.getRandomBytes;
|
||||||
import static org.briarproject.bramble.api.identity.Author.Status.VERIFIED;
|
import static org.briarproject.bramble.api.identity.Author.Status.VERIFIED;
|
||||||
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
|
||||||
import static org.briarproject.briar.api.privategroup.Visibility.INVISIBLE;
|
import static org.briarproject.briar.api.privategroup.Visibility.INVISIBLE;
|
||||||
import static org.briarproject.briar.api.privategroup.Visibility.REVEALED_BY_CONTACT;
|
import static org.briarproject.briar.api.privategroup.Visibility.REVEALED_BY_CONTACT;
|
||||||
import static org.briarproject.briar.api.privategroup.Visibility.REVEALED_BY_US;
|
import static org.briarproject.briar.api.privategroup.Visibility.REVEALED_BY_US;
|
||||||
@@ -34,7 +29,7 @@ import static org.junit.Assert.assertEquals;
|
|||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class PrivateGroupManagerIntegrationTest
|
public class PrivateGroupManagerTest
|
||||||
extends BriarIntegrationTest<BriarIntegrationTestComponent> {
|
extends BriarIntegrationTest<BriarIntegrationTestComponent> {
|
||||||
|
|
||||||
private PrivateGroup privateGroup0;
|
private PrivateGroup privateGroup0;
|
||||||
@@ -42,7 +37,6 @@ public class PrivateGroupManagerIntegrationTest
|
|||||||
private PrivateGroupManager groupManager0, groupManager1, groupManager2;
|
private PrivateGroupManager groupManager0, groupManager1, groupManager2;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@Override
|
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
|
|
||||||
@@ -133,7 +127,7 @@ public class PrivateGroupManagerIntegrationTest
|
|||||||
assertEquals(2, groupManager1.getHeaders(groupId0).size());
|
assertEquals(2, groupManager1.getHeaders(groupId0).size());
|
||||||
|
|
||||||
// create and add test message with random previousMsgId
|
// create and add test message with random previousMsgId
|
||||||
MessageId previousMsgId = new MessageId(getRandomId());
|
MessageId previousMsgId = new MessageId(TestUtils.getRandomId());
|
||||||
msg = groupMessageFactory
|
msg = groupMessageFactory
|
||||||
.createGroupMessage(groupId0, clock.currentTimeMillis(), null,
|
.createGroupMessage(groupId0, clock.currentTimeMillis(), null,
|
||||||
author0, "test", previousMsgId);
|
author0, "test", previousMsgId);
|
||||||
@@ -164,7 +158,7 @@ public class PrivateGroupManagerIntegrationTest
|
|||||||
addGroup();
|
addGroup();
|
||||||
|
|
||||||
// create and add test message with random parentMsgId
|
// create and add test message with random parentMsgId
|
||||||
MessageId parentMsgId = new MessageId(getRandomId());
|
MessageId parentMsgId = new MessageId(TestUtils.getRandomId());
|
||||||
MessageId previousMsgId = groupManager0.getPreviousMsgId(groupId0);
|
MessageId previousMsgId = groupManager0.getPreviousMsgId(groupId0);
|
||||||
GroupMessage msg = groupMessageFactory
|
GroupMessage msg = groupMessageFactory
|
||||||
.createGroupMessage(groupId0, clock.currentTimeMillis(),
|
.createGroupMessage(groupId0, clock.currentTimeMillis(),
|
||||||
@@ -442,9 +436,6 @@ public class PrivateGroupManagerIntegrationTest
|
|||||||
Collection<GroupMember> members2 = groupManager2.getMembers(groupId0);
|
Collection<GroupMember> members2 = groupManager2.getMembers(groupId0);
|
||||||
assertEquals(3, members2.size());
|
assertEquals(3, members2.size());
|
||||||
|
|
||||||
// 1 and 2 add each other
|
|
||||||
addContacts1And2();
|
|
||||||
|
|
||||||
// assert that contact relationship is not revealed initially
|
// assert that contact relationship is not revealed initially
|
||||||
for (GroupMember m : members1) {
|
for (GroupMember m : members1) {
|
||||||
if (m.getAuthor().equals(author2)) {
|
if (m.getAuthor().equals(author2)) {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.briar.messaging;
|
package org.briarproject;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.contact.ContactId;
|
import org.briarproject.bramble.api.contact.ContactId;
|
||||||
import org.briarproject.bramble.api.contact.ContactManager;
|
import org.briarproject.bramble.api.contact.ContactManager;
|
||||||
@@ -20,12 +20,10 @@ import org.briarproject.bramble.api.transport.StreamContext;
|
|||||||
import org.briarproject.bramble.api.transport.StreamReaderFactory;
|
import org.briarproject.bramble.api.transport.StreamReaderFactory;
|
||||||
import org.briarproject.bramble.api.transport.StreamWriterFactory;
|
import org.briarproject.bramble.api.transport.StreamWriterFactory;
|
||||||
import org.briarproject.bramble.system.SystemModule;
|
import org.briarproject.bramble.system.SystemModule;
|
||||||
import org.briarproject.bramble.test.TestDatabaseModule;
|
|
||||||
import org.briarproject.bramble.test.TestUtils;
|
|
||||||
import org.briarproject.briar.api.messaging.MessagingManager;
|
import org.briarproject.briar.api.messaging.MessagingManager;
|
||||||
import org.briarproject.briar.api.messaging.PrivateMessage;
|
import org.briarproject.briar.api.messaging.PrivateMessage;
|
||||||
import org.briarproject.briar.api.messaging.PrivateMessageFactory;
|
import org.briarproject.briar.api.messaging.PrivateMessageFactory;
|
||||||
import org.briarproject.briar.test.BriarTestCase;
|
import org.briarproject.briar.messaging.MessagingModule;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -36,10 +34,10 @@ import java.io.File;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import static org.briarproject.TestPluginConfigModule.MAX_LATENCY;
|
||||||
|
import static org.briarproject.TestPluginConfigModule.TRANSPORT_ID;
|
||||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||||
import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
|
import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
|
||||||
import static org.briarproject.bramble.test.TestPluginConfigModule.MAX_LATENCY;
|
|
||||||
import static org.briarproject.bramble.test.TestPluginConfigModule.TRANSPORT_ID;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.briar.messaging;
|
package org.briarproject;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.contact.ContactManager;
|
import org.briarproject.bramble.api.contact.ContactManager;
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
@@ -18,13 +18,11 @@ import org.briarproject.bramble.identity.IdentityModule;
|
|||||||
import org.briarproject.bramble.lifecycle.LifecycleModule;
|
import org.briarproject.bramble.lifecycle.LifecycleModule;
|
||||||
import org.briarproject.bramble.sync.SyncModule;
|
import org.briarproject.bramble.sync.SyncModule;
|
||||||
import org.briarproject.bramble.system.SystemModule;
|
import org.briarproject.bramble.system.SystemModule;
|
||||||
import org.briarproject.bramble.test.TestDatabaseModule;
|
|
||||||
import org.briarproject.bramble.test.TestPluginConfigModule;
|
|
||||||
import org.briarproject.bramble.test.TestSeedProviderModule;
|
|
||||||
import org.briarproject.bramble.transport.TransportModule;
|
import org.briarproject.bramble.transport.TransportModule;
|
||||||
import org.briarproject.briar.api.messaging.MessagingManager;
|
import org.briarproject.briar.api.messaging.MessagingManager;
|
||||||
import org.briarproject.briar.api.messaging.PrivateMessageFactory;
|
import org.briarproject.briar.api.messaging.PrivateMessageFactory;
|
||||||
import org.briarproject.briar.client.BriarClientModule;
|
import org.briarproject.briar.client.BriarClientModule;
|
||||||
|
import org.briarproject.briar.messaging.MessagingModule;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.bramble.sync;
|
package org.briarproject;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.contact.ContactId;
|
import org.briarproject.bramble.api.contact.ContactId;
|
||||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
@@ -12,16 +12,14 @@ import org.briarproject.bramble.api.sync.Message;
|
|||||||
import org.briarproject.bramble.api.sync.MessageFactory;
|
import org.briarproject.bramble.api.sync.MessageFactory;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.bramble.api.sync.Offer;
|
import org.briarproject.bramble.api.sync.Offer;
|
||||||
import org.briarproject.bramble.api.sync.RecordReader;
|
import org.briarproject.bramble.api.sync.PacketReader;
|
||||||
import org.briarproject.bramble.api.sync.RecordReaderFactory;
|
import org.briarproject.bramble.api.sync.PacketReaderFactory;
|
||||||
import org.briarproject.bramble.api.sync.RecordWriter;
|
import org.briarproject.bramble.api.sync.PacketWriter;
|
||||||
import org.briarproject.bramble.api.sync.RecordWriterFactory;
|
import org.briarproject.bramble.api.sync.PacketWriterFactory;
|
||||||
import org.briarproject.bramble.api.sync.Request;
|
import org.briarproject.bramble.api.sync.Request;
|
||||||
import org.briarproject.bramble.api.transport.StreamContext;
|
import org.briarproject.bramble.api.transport.StreamContext;
|
||||||
import org.briarproject.bramble.api.transport.StreamReaderFactory;
|
import org.briarproject.bramble.api.transport.StreamReaderFactory;
|
||||||
import org.briarproject.bramble.api.transport.StreamWriterFactory;
|
import org.briarproject.bramble.api.transport.StreamWriterFactory;
|
||||||
import org.briarproject.bramble.test.BrambleTestCase;
|
|
||||||
import org.briarproject.bramble.test.TestUtils;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
@@ -33,14 +31,13 @@ import java.util.Collection;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
|
|
||||||
import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
|
import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class SyncIntegrationTest extends BrambleTestCase {
|
public class SyncIntegrationTest extends BriarTestCase {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
GroupFactory groupFactory;
|
GroupFactory groupFactory;
|
||||||
@@ -51,9 +48,9 @@ public class SyncIntegrationTest extends BrambleTestCase {
|
|||||||
@Inject
|
@Inject
|
||||||
StreamWriterFactory streamWriterFactory;
|
StreamWriterFactory streamWriterFactory;
|
||||||
@Inject
|
@Inject
|
||||||
RecordReaderFactory recordReaderFactory;
|
PacketReaderFactory packetReaderFactory;
|
||||||
@Inject
|
@Inject
|
||||||
RecordWriterFactory recordWriterFactory;
|
PacketWriterFactory packetWriterFactory;
|
||||||
@Inject
|
@Inject
|
||||||
CryptoComponent crypto;
|
CryptoComponent crypto;
|
||||||
|
|
||||||
@@ -78,7 +75,7 @@ public class SyncIntegrationTest extends BrambleTestCase {
|
|||||||
streamNumber = 123;
|
streamNumber = 123;
|
||||||
// Create a group
|
// Create a group
|
||||||
ClientId clientId = new ClientId(TestUtils.getRandomString(5));
|
ClientId clientId = new ClientId(TestUtils.getRandomString(5));
|
||||||
byte[] descriptor = new byte[MAX_GROUP_DESCRIPTOR_LENGTH];
|
byte[] descriptor = new byte[0];
|
||||||
Group group = groupFactory.createGroup(clientId, descriptor);
|
Group group = groupFactory.createGroup(clientId, descriptor);
|
||||||
// Add two messages to the group
|
// Add two messages to the group
|
||||||
long timestamp = System.currentTimeMillis();
|
long timestamp = System.currentTimeMillis();
|
||||||
@@ -99,14 +96,14 @@ public class SyncIntegrationTest extends BrambleTestCase {
|
|||||||
headerKey, streamNumber);
|
headerKey, streamNumber);
|
||||||
OutputStream streamWriter = streamWriterFactory.createStreamWriter(out,
|
OutputStream streamWriter = streamWriterFactory.createStreamWriter(out,
|
||||||
ctx);
|
ctx);
|
||||||
RecordWriter recordWriter = recordWriterFactory.createRecordWriter(
|
PacketWriter packetWriter = packetWriterFactory.createPacketWriter(
|
||||||
streamWriter);
|
streamWriter);
|
||||||
|
|
||||||
recordWriter.writeAck(new Ack(messageIds));
|
packetWriter.writeAck(new Ack(messageIds));
|
||||||
recordWriter.writeMessage(message.getRaw());
|
packetWriter.writeMessage(message.getRaw());
|
||||||
recordWriter.writeMessage(message1.getRaw());
|
packetWriter.writeMessage(message1.getRaw());
|
||||||
recordWriter.writeOffer(new Offer(messageIds));
|
packetWriter.writeOffer(new Offer(messageIds));
|
||||||
recordWriter.writeRequest(new Request(messageIds));
|
packetWriter.writeRequest(new Request(messageIds));
|
||||||
|
|
||||||
streamWriter.flush();
|
streamWriter.flush();
|
||||||
return out.toByteArray();
|
return out.toByteArray();
|
||||||
@@ -128,31 +125,31 @@ public class SyncIntegrationTest extends BrambleTestCase {
|
|||||||
headerKey, streamNumber);
|
headerKey, streamNumber);
|
||||||
InputStream streamReader = streamReaderFactory.createStreamReader(in,
|
InputStream streamReader = streamReaderFactory.createStreamReader(in,
|
||||||
ctx);
|
ctx);
|
||||||
RecordReader recordReader = recordReaderFactory.createRecordReader(
|
PacketReader packetReader = packetReaderFactory.createPacketReader(
|
||||||
streamReader);
|
streamReader);
|
||||||
|
|
||||||
// Read the ack
|
// Read the ack
|
||||||
assertTrue(recordReader.hasAck());
|
assertTrue(packetReader.hasAck());
|
||||||
Ack a = recordReader.readAck();
|
Ack a = packetReader.readAck();
|
||||||
assertEquals(messageIds, a.getMessageIds());
|
assertEquals(messageIds, a.getMessageIds());
|
||||||
|
|
||||||
// Read the messages
|
// Read the messages
|
||||||
assertTrue(recordReader.hasMessage());
|
assertTrue(packetReader.hasMessage());
|
||||||
Message m = recordReader.readMessage();
|
Message m = packetReader.readMessage();
|
||||||
checkMessageEquality(message, m);
|
checkMessageEquality(message, m);
|
||||||
assertTrue(recordReader.hasMessage());
|
assertTrue(packetReader.hasMessage());
|
||||||
m = recordReader.readMessage();
|
m = packetReader.readMessage();
|
||||||
checkMessageEquality(message1, m);
|
checkMessageEquality(message1, m);
|
||||||
assertFalse(recordReader.hasMessage());
|
assertFalse(packetReader.hasMessage());
|
||||||
|
|
||||||
// Read the offer
|
// Read the offer
|
||||||
assertTrue(recordReader.hasOffer());
|
assertTrue(packetReader.hasOffer());
|
||||||
Offer o = recordReader.readOffer();
|
Offer o = packetReader.readOffer();
|
||||||
assertEquals(messageIds, o.getMessageIds());
|
assertEquals(messageIds, o.getMessageIds());
|
||||||
|
|
||||||
// Read the request
|
// Read the request
|
||||||
assertTrue(recordReader.hasRequest());
|
assertTrue(packetReader.hasRequest());
|
||||||
Request req = recordReader.readRequest();
|
Request req = packetReader.readRequest();
|
||||||
assertEquals(messageIds, req.getMessageIds());
|
assertEquals(messageIds, req.getMessageIds());
|
||||||
|
|
||||||
in.close();
|
in.close();
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package org.briarproject.bramble.sync;
|
package org.briarproject;
|
||||||
|
|
||||||
import org.briarproject.bramble.crypto.CryptoModule;
|
import org.briarproject.bramble.crypto.CryptoModule;
|
||||||
import org.briarproject.bramble.test.TestSeedProviderModule;
|
import org.briarproject.bramble.sync.SyncModule;
|
||||||
import org.briarproject.bramble.transport.TransportModule;
|
import org.briarproject.bramble.transport.TransportModule;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.bramble.test;
|
package org.briarproject;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.db.DatabaseConfig;
|
import org.briarproject.bramble.api.db.DatabaseConfig;
|
||||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.bramble.test;
|
package org.briarproject;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
@@ -18,7 +18,7 @@ import dagger.Module;
|
|||||||
import dagger.Provides;
|
import dagger.Provides;
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
public class TestLifecycleModule {
|
class TestLifecycleModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
LifecycleManager provideLifecycleManager() {
|
LifecycleManager provideLifecycleManager() {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.bramble.test;
|
package org.briarproject;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.PluginConfig;
|
import org.briarproject.bramble.api.plugin.PluginConfig;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.bramble.test;
|
package org.briarproject;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.system.SeedProvider;
|
import org.briarproject.bramble.api.system.SeedProvider;
|
||||||
|
|
||||||
@@ -2,6 +2,9 @@ package org.briarproject.briar.introduction;
|
|||||||
|
|
||||||
import net.jodah.concurrentunit.Waiter;
|
import net.jodah.concurrentunit.Waiter;
|
||||||
|
|
||||||
|
import org.briarproject.BriarIntegrationTest;
|
||||||
|
import org.briarproject.TestDatabaseModule;
|
||||||
|
import org.briarproject.TestUtils;
|
||||||
import org.briarproject.bramble.api.FormatException;
|
import org.briarproject.bramble.api.FormatException;
|
||||||
import org.briarproject.bramble.api.client.ClientHelper;
|
import org.briarproject.bramble.api.client.ClientHelper;
|
||||||
import org.briarproject.bramble.api.contact.Contact;
|
import org.briarproject.bramble.api.contact.Contact;
|
||||||
@@ -24,8 +27,6 @@ import org.briarproject.bramble.api.properties.TransportPropertyManager;
|
|||||||
import org.briarproject.bramble.api.sync.Group;
|
import org.briarproject.bramble.api.sync.Group;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.bramble.test.TestDatabaseModule;
|
|
||||||
import org.briarproject.bramble.test.TestUtils;
|
|
||||||
import org.briarproject.briar.api.client.SessionId;
|
import org.briarproject.briar.api.client.SessionId;
|
||||||
import org.briarproject.briar.api.introduction.IntroductionManager;
|
import org.briarproject.briar.api.introduction.IntroductionManager;
|
||||||
import org.briarproject.briar.api.introduction.IntroductionMessage;
|
import org.briarproject.briar.api.introduction.IntroductionMessage;
|
||||||
@@ -34,7 +35,6 @@ import org.briarproject.briar.api.introduction.event.IntroductionAbortedEvent;
|
|||||||
import org.briarproject.briar.api.introduction.event.IntroductionRequestReceivedEvent;
|
import org.briarproject.briar.api.introduction.event.IntroductionRequestReceivedEvent;
|
||||||
import org.briarproject.briar.api.introduction.event.IntroductionResponseReceivedEvent;
|
import org.briarproject.briar.api.introduction.event.IntroductionResponseReceivedEvent;
|
||||||
import org.briarproject.briar.api.introduction.event.IntroductionSucceededEvent;
|
import org.briarproject.briar.api.introduction.event.IntroductionSucceededEvent;
|
||||||
import org.briarproject.briar.test.BriarIntegrationTest;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@@ -51,8 +51,9 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static org.briarproject.TestPluginConfigModule.TRANSPORT_ID;
|
||||||
|
import static org.briarproject.TestUtils.assertGroupCount;
|
||||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||||
import static org.briarproject.bramble.test.TestPluginConfigModule.TRANSPORT_ID;
|
|
||||||
import static org.briarproject.briar.api.client.MessageQueueManager.QUEUE_STATE_KEY;
|
import static org.briarproject.briar.api.client.MessageQueueManager.QUEUE_STATE_KEY;
|
||||||
import static org.briarproject.briar.api.introduction.IntroductionConstants.E_PUBLIC_KEY;
|
import static org.briarproject.briar.api.introduction.IntroductionConstants.E_PUBLIC_KEY;
|
||||||
import static org.briarproject.briar.api.introduction.IntroductionConstants.GROUP_ID;
|
import static org.briarproject.briar.api.introduction.IntroductionConstants.GROUP_ID;
|
||||||
@@ -69,7 +70,6 @@ import static org.briarproject.briar.api.introduction.IntroductionConstants.TYPE
|
|||||||
import static org.briarproject.briar.api.introduction.IntroductionConstants.TYPE_REQUEST;
|
import static org.briarproject.briar.api.introduction.IntroductionConstants.TYPE_REQUEST;
|
||||||
import static org.briarproject.briar.api.introduction.IntroductionConstants.TYPE_RESPONSE;
|
import static org.briarproject.briar.api.introduction.IntroductionConstants.TYPE_RESPONSE;
|
||||||
import static org.briarproject.briar.introduction.IntroduceeManager.SIGNING_LABEL_RESPONSE;
|
import static org.briarproject.briar.introduction.IntroduceeManager.SIGNING_LABEL_RESPONSE;
|
||||||
import static org.briarproject.briar.test.BriarTestUtils.assertGroupCount;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
@@ -454,7 +454,7 @@ public class IntroductionIntegrationTest
|
|||||||
assertTrue(listener1.requestReceived);
|
assertTrue(listener1.requestReceived);
|
||||||
|
|
||||||
// get SessionId
|
// get SessionId
|
||||||
List<IntroductionMessage> list = new ArrayList<IntroductionMessage>(
|
List<IntroductionMessage> list = new ArrayList<>(
|
||||||
introductionManager1.getIntroductionMessages(contactId0From1));
|
introductionManager1.getIntroductionMessages(contactId0From1));
|
||||||
assertEquals(2, list.size());
|
assertEquals(2, list.size());
|
||||||
assertTrue(list.get(0) instanceof IntroductionRequest);
|
assertTrue(list.get(0) instanceof IntroductionRequest);
|
||||||
@@ -906,9 +906,7 @@ public class IntroductionIntegrationTest
|
|||||||
time);
|
time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (DbException exception) {
|
} catch (DbException | IOException exception) {
|
||||||
eventWaiter.rethrow(exception);
|
|
||||||
} catch (FormatException exception) {
|
|
||||||
eventWaiter.rethrow(exception);
|
eventWaiter.rethrow(exception);
|
||||||
} finally {
|
} finally {
|
||||||
eventWaiter.resume();
|
eventWaiter.resume();
|
||||||
@@ -1,5 +1,9 @@
|
|||||||
package org.briarproject.briar.introduction;
|
package org.briarproject.briar.introduction;
|
||||||
|
|
||||||
|
import org.briarproject.BriarIntegrationTestComponent;
|
||||||
|
import org.briarproject.TestDatabaseModule;
|
||||||
|
import org.briarproject.TestPluginConfigModule;
|
||||||
|
import org.briarproject.TestSeedProviderModule;
|
||||||
import org.briarproject.bramble.client.ClientModule;
|
import org.briarproject.bramble.client.ClientModule;
|
||||||
import org.briarproject.bramble.contact.ContactModule;
|
import org.briarproject.bramble.contact.ContactModule;
|
||||||
import org.briarproject.bramble.crypto.CryptoModule;
|
import org.briarproject.bramble.crypto.CryptoModule;
|
||||||
@@ -11,9 +15,6 @@ import org.briarproject.bramble.lifecycle.LifecycleModule;
|
|||||||
import org.briarproject.bramble.properties.PropertiesModule;
|
import org.briarproject.bramble.properties.PropertiesModule;
|
||||||
import org.briarproject.bramble.sync.SyncModule;
|
import org.briarproject.bramble.sync.SyncModule;
|
||||||
import org.briarproject.bramble.system.SystemModule;
|
import org.briarproject.bramble.system.SystemModule;
|
||||||
import org.briarproject.bramble.test.TestDatabaseModule;
|
|
||||||
import org.briarproject.bramble.test.TestPluginConfigModule;
|
|
||||||
import org.briarproject.bramble.test.TestSeedProviderModule;
|
|
||||||
import org.briarproject.bramble.transport.TransportModule;
|
import org.briarproject.bramble.transport.TransportModule;
|
||||||
import org.briarproject.briar.blog.BlogModule;
|
import org.briarproject.briar.blog.BlogModule;
|
||||||
import org.briarproject.briar.client.BriarClientModule;
|
import org.briarproject.briar.client.BriarClientModule;
|
||||||
@@ -22,7 +23,6 @@ import org.briarproject.briar.messaging.MessagingModule;
|
|||||||
import org.briarproject.briar.privategroup.PrivateGroupModule;
|
import org.briarproject.briar.privategroup.PrivateGroupModule;
|
||||||
import org.briarproject.briar.privategroup.invitation.GroupInvitationModule;
|
import org.briarproject.briar.privategroup.invitation.GroupInvitationModule;
|
||||||
import org.briarproject.briar.sharing.SharingModule;
|
import org.briarproject.briar.sharing.SharingModule;
|
||||||
import org.briarproject.briar.test.BriarIntegrationTestComponent;
|
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
@@ -1,157 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
version="1.1"
|
|
||||||
id="Ebene_1"
|
|
||||||
x="0px"
|
|
||||||
y="0px"
|
|
||||||
viewBox="0 0 330.00001 330.00001"
|
|
||||||
xml:space="preserve"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="logo_circle.svg"
|
|
||||||
width="330"
|
|
||||||
height="330"><metadata
|
|
||||||
id="metadata61"><rdf:RDF><cc:Work
|
|
||||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
|
||||||
id="defs59" /><sodipodi:namedview
|
|
||||||
pagecolor="#000000"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1"
|
|
||||||
objecttolerance="10"
|
|
||||||
gridtolerance="10"
|
|
||||||
guidetolerance="10"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1021"
|
|
||||||
id="namedview57"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:zoom="1.4333435"
|
|
||||||
inkscape:cx="137.64067"
|
|
||||||
inkscape:cy="223.06028"
|
|
||||||
inkscape:window-x="1440"
|
|
||||||
inkscape:window-y="23"
|
|
||||||
inkscape:window-maximized="0"
|
|
||||||
inkscape:current-layer="Ebene_1" /><style
|
|
||||||
type="text/css"
|
|
||||||
id="style3">
|
|
||||||
.st0{fill:#FFFFFF;}
|
|
||||||
.st1{display:none;fill:#87C214;}
|
|
||||||
.st2{fill:#87C214;}
|
|
||||||
.st3{display:none;fill:#FFFFFF;}
|
|
||||||
.st4{fill:#95D220;}
|
|
||||||
.st5{display:none;fill:#95D220;}
|
|
||||||
</style><circle
|
|
||||||
style="fill:#ffffff"
|
|
||||||
id="circle7"
|
|
||||||
cy="165"
|
|
||||||
cx="165"
|
|
||||||
class="st0"
|
|
||||||
r="165" /><g
|
|
||||||
id="g4214"
|
|
||||||
transform="translate(0.2999939,1.2000061)"><g
|
|
||||||
id="g9"><g
|
|
||||||
id="g11"><rect
|
|
||||||
x="94"
|
|
||||||
y="93.800003"
|
|
||||||
class="st1"
|
|
||||||
width="43.700001"
|
|
||||||
height="43.700001"
|
|
||||||
id="rect13"
|
|
||||||
style="display:none;fill:#87c214" /><path
|
|
||||||
class="st2"
|
|
||||||
d="M 94,144.5 94,264 c 0,9.7 7.9,17.7 17.7,17.7 l 8.3,0 c 9.7,0 17.7,-8 17.7,-17.7 l 0,-119.5 -43.7,0 z"
|
|
||||||
id="path15"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="fill:#87c214" /><path
|
|
||||||
class="st2"
|
|
||||||
d="m 137.7,86.8 0,-22.5 c 0,-9.7 -8,-17.7 -17.7,-17.7 l -8.3,0 C 102,46.6 94,54.6 94,64.3 l 0,22.5 43.7,0 z"
|
|
||||||
id="path17"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="fill:#87c214" /></g><path
|
|
||||||
class="st3"
|
|
||||||
d="m 120,46.7 c 9.7,0 17.7,8 17.7,17.7 l 0,199.6 c 0,9.7 -8,17.7 -17.7,17.7 l -8.3,0 C 102,281.7 94,273.7 94,264 L 94,64.3 c 0,-9.7 7.9,-17.7 17.7,-17.7 l 8.3,0 m 0,-6.9 -8.3,0 C 98.1,39.7 87,50.7 87,64.3 L 87,264 c 0,13.6 11.1,24.7 24.7,24.7 l 8.3,0 c 13.6,0 24.7,-11.1 24.7,-24.7 l 0,-199.7 C 144.7,50.7 133.6,39.7 120,39.7 l 0,0 z"
|
|
||||||
id="path19"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="display:none;fill:#ffffff" /></g><g
|
|
||||||
id="g21"><g
|
|
||||||
id="g23"><path
|
|
||||||
class="st2"
|
|
||||||
d="m 234.7,183.8 0,-119.5 c 0,-9.7 -7.9,-17.7 -17.7,-17.7 l -8.3,0 c -9.7,0 -17.7,8 -17.7,17.7 l 0,119.5 43.7,0 z"
|
|
||||||
id="path25"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="fill:#87c214" /><rect
|
|
||||||
x="191"
|
|
||||||
y="190.8"
|
|
||||||
class="st1"
|
|
||||||
width="43.700001"
|
|
||||||
height="43.700001"
|
|
||||||
id="rect27"
|
|
||||||
style="display:none;fill:#87c214" /><path
|
|
||||||
class="st2"
|
|
||||||
d="m 191,241.5 0,22.5 c 0,9.7 8,17.7 17.7,17.7 l 8.3,0 c 9.7,0 17.7,-8 17.7,-17.7 l 0,-22.5 -43.7,0 z"
|
|
||||||
id="path29"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="fill:#87c214" /></g><path
|
|
||||||
class="st3"
|
|
||||||
d="m 217,46.7 c 9.7,0 17.7,8 17.7,17.7 l 0,199.6 c 0,9.7 -7.9,17.7 -17.7,17.7 l -8.3,0 c -9.7,0 -17.7,-8 -17.7,-17.7 l 0,-199.7 c 0,-9.7 8,-17.7 17.7,-17.7 l 8.3,0 m 0,-6.9 -8.3,0 C 195.1,39.7 184,50.8 184,64.4 l 0,199.6 c 0,13.6 11.1,24.7 24.7,24.7 l 8.3,0 c 13.6,0 24.7,-11.1 24.7,-24.7 l 0,-199.7 C 241.7,50.7 230.6,39.7 217,39.7 l 0,0 z"
|
|
||||||
id="path31"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="display:none;fill:#ffffff" /></g><g
|
|
||||||
id="g33"><g
|
|
||||||
id="g35"><path
|
|
||||||
class="st4"
|
|
||||||
d="m 87,190.8 -22.5,0 c -9.7,0 -17.7,7.9 -17.7,17.7 l 0,8.3 c 0,9.7 7.9,17.7 17.7,17.7 l 22.5,0 0,-43.7 z"
|
|
||||||
id="path37"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="fill:#95d220" /><rect
|
|
||||||
x="94"
|
|
||||||
y="190.8"
|
|
||||||
class="st5"
|
|
||||||
width="43.700001"
|
|
||||||
height="43.700001"
|
|
||||||
id="rect39"
|
|
||||||
style="display:none;fill:#95d220" /><path
|
|
||||||
class="st4"
|
|
||||||
d="m 264.2,190.8 -119.5,0 0,43.7 119.5,0 c 9.7,0 17.7,-8 17.7,-17.7 l 0,-8.3 c -0.1,-9.7 -8,-17.7 -17.7,-17.7 z"
|
|
||||||
id="path41"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="fill:#95d220" /></g><path
|
|
||||||
class="st3"
|
|
||||||
d="m 264.2,190.8 c 9.7,0 17.7,7.9 17.7,17.7 l 0,8.3 c 0,9.7 -8,17.7 -17.7,17.7 l -199.7,0 c -9.7,0 -17.7,-8 -17.7,-17.7 l 0,-8.3 c 0,-9.7 7.9,-17.7 17.7,-17.7 l 199.7,0 m 0,-7 -199.7,0 c -13.6,0 -24.7,11.1 -24.7,24.7 l 0,8.3 c 0,13.6 11.1,24.7 24.7,24.7 l 199.7,0 c 13.6,0 24.7,-11.1 24.7,-24.7 l 0,-8.3 c -0.1,-13.6 -11.1,-24.7 -24.7,-24.7 l 0,0 z"
|
|
||||||
id="path43"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="display:none;fill:#ffffff" /></g><g
|
|
||||||
id="g45"><g
|
|
||||||
id="g47"><rect
|
|
||||||
x="191"
|
|
||||||
y="93.800003"
|
|
||||||
class="st5"
|
|
||||||
width="43.700001"
|
|
||||||
height="43.700001"
|
|
||||||
id="rect49"
|
|
||||||
style="display:none;fill:#95d220" /><path
|
|
||||||
class="st4"
|
|
||||||
d="m 184,93.8 -119.5,0 c -9.7,0 -17.7,7.9 -17.7,17.7 l 0,8.3 c 0,9.7 7.9,17.7 17.7,17.7 l 119.5,0 0,-43.7 z"
|
|
||||||
id="path51"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="fill:#95d220" /><path
|
|
||||||
class="st4"
|
|
||||||
d="m 264.2,93.8 -22.5,0 0,43.7 22.5,0 c 9.7,0 17.7,-7.9 17.7,-17.7 l 0,-8.3 c -0.1,-9.7 -8,-17.7 -17.7,-17.7 z"
|
|
||||||
id="path53"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="fill:#95d220" /></g><path
|
|
||||||
class="st3"
|
|
||||||
d="m 264.2,93.8 c 9.7,0 17.7,7.9 17.7,17.7 l 0,8.3 c 0,9.7 -8,17.7 -17.7,17.7 l -199.7,0 c -9.7,0 -17.7,-7.9 -17.7,-17.7 l 0,-8.3 c 0,-9.7 7.9,-17.7 17.7,-17.7 l 199.7,0 m 0,-7 -199.7,0 c -13.6,0 -24.7,11.1 -24.7,24.7 l 0,8.3 c 0,13.6 11.1,24.7 24.7,24.7 l 199.7,0 c 13.6,0 24.7,-11.1 24.7,-24.7 l 0,-8.3 C 288.8,97.9 277.8,86.8 264.2,86.8 l 0,0 z"
|
|
||||||
id="path55"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="display:none;fill:#ffffff" /></g></g></svg>
|
|
||||||
|
Before Width: | Height: | Size: 6.8 KiB |
@@ -1,118 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
version="1.1"
|
|
||||||
id="Ebene_1"
|
|
||||||
x="0px"
|
|
||||||
y="0px"
|
|
||||||
xml:space="preserve"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="logo_horizontal_white.svg"
|
|
||||||
width="138"
|
|
||||||
height="50"><metadata
|
|
||||||
id="metadata71"><rdf:RDF><cc:Work
|
|
||||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
|
|
||||||
id="defs69" /><sodipodi:namedview
|
|
||||||
pagecolor="#000000"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1"
|
|
||||||
objecttolerance="10"
|
|
||||||
gridtolerance="10"
|
|
||||||
guidetolerance="10"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1021"
|
|
||||||
id="namedview67"
|
|
||||||
showgrid="false"
|
|
||||||
fit-margin-top="0"
|
|
||||||
fit-margin-left="0"
|
|
||||||
fit-margin-right="0"
|
|
||||||
fit-margin-bottom="0"
|
|
||||||
inkscape:zoom="1.410079"
|
|
||||||
inkscape:cx="96.786606"
|
|
||||||
inkscape:cy="117.77539"
|
|
||||||
inkscape:window-x="1443"
|
|
||||||
inkscape:window-y="23"
|
|
||||||
inkscape:window-maximized="0"
|
|
||||||
inkscape:current-layer="Ebene_1" /><style
|
|
||||||
type="text/css"
|
|
||||||
id="style3">
|
|
||||||
.st0{display:none;fill:#87C214;}
|
|
||||||
.st1{fill:#87C214;}
|
|
||||||
.st2{display:none;fill:#FFFFFF;}
|
|
||||||
.st3{fill:#95D220;}
|
|
||||||
.st4{display:none;fill:#95D220;}
|
|
||||||
.st5{fill:#FFFFFF;}
|
|
||||||
</style><rect
|
|
||||||
style="display:none;fill:#87c214"
|
|
||||||
id="rect11"
|
|
||||||
height="9.279274"
|
|
||||||
width="9.279274"
|
|
||||||
class="st0"
|
|
||||||
y="214.00124"
|
|
||||||
x="230.02246" /><path
|
|
||||||
class="st2"
|
|
||||||
d="m 235.54331,203.97877 c 2.05971,0 3.75843,1.69872 3.75843,3.75842 l 0,42.40437 c 0,2.05971 -1.69872,3.75843 -3.75843,3.75843 l -1.76242,0 c -2.0597,0 -3.75843,-1.69872 -3.75843,-3.75843 l 0,-42.40437 c 0,-2.0597 1.67749,-3.75842 3.73719,-3.75842 l 1.78366,0 m 0,-1.48638 -1.76242,0 c -2.90906,0 -5.24481,2.35697 -5.24481,5.2448 l 0,42.40437 c 0,2.88783 2.35698,5.24481 5.24481,5.24481 l 1.76242,0 c 2.88783,0 5.24481,-2.35698 5.24481,-5.24481 l 0,-42.40437 c -0.0212,-2.88783 -2.35698,-5.2448 -5.24481,-5.2448 l 0,0 z"
|
|
||||||
id="path17"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="display:none;fill:#ffffff" /><rect
|
|
||||||
style="display:none;fill:#87c214"
|
|
||||||
id="rect25"
|
|
||||||
height="9.279274"
|
|
||||||
width="9.279274"
|
|
||||||
class="st0"
|
|
||||||
y="234.59825"
|
|
||||||
x="250.61948" /><path
|
|
||||||
class="st2"
|
|
||||||
d="m 256.14033,203.97877 c 2.0597,0 3.75842,1.69872 3.75842,3.75842 l 0,42.40437 c 0,2.05971 -1.67749,3.75843 -3.75842,3.75843 l -1.76243,0 c -2.0597,0 -3.75842,-1.69872 -3.75842,-3.75843 l 0,-42.40437 c 0,-2.0597 1.69872,-3.75842 3.75842,-3.75842 l 1.76243,0 m 0,-1.48638 -1.76243,0 c -2.88783,0 -5.2448,2.35697 -5.2448,5.2448 l 0,42.40437 c 0,2.88783 2.35697,5.24481 5.2448,5.24481 l 1.76243,0 c 2.88783,0 5.24481,-2.35698 5.24481,-5.24481 l 0,-42.40437 c -0.0212,-2.88783 -2.35698,-5.2448 -5.24481,-5.2448 l 0,0 z"
|
|
||||||
id="path29"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="display:none;fill:#ffffff" /><rect
|
|
||||||
style="display:none;fill:#95d220"
|
|
||||||
id="rect37"
|
|
||||||
height="9.279274"
|
|
||||||
width="9.279274"
|
|
||||||
class="st4"
|
|
||||||
y="234.59825"
|
|
||||||
x="230.02246" /><path
|
|
||||||
class="st2"
|
|
||||||
d="m 266.14156,234.59825 c 2.0597,0 3.75842,1.67749 3.75842,3.75842 l 0,1.76243 c 0,2.0597 -1.69872,3.75842 -3.75842,3.75842 l -42.38314,0 c -2.0597,0 -3.75842,-1.69872 -3.75842,-3.75842 l 0,-1.76243 c 0,-2.0597 1.67749,-3.75842 3.75842,-3.75842 l 42.38314,0 m 0,-1.48638 -42.38314,0 c -2.88783,0 -5.2448,2.33574 -5.2448,5.22357 l 0,1.76242 c 0,2.88783 2.35697,5.24481 5.2448,5.24481 l 42.40437,0 c 2.88783,0 5.24481,-2.35698 5.24481,-5.24481 l 0,-1.76242 c -0.0212,-2.88783 -2.37821,-5.22357 -5.26604,-5.22357 l 0,0 z"
|
|
||||||
id="path41"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="display:none;fill:#ffffff" /><rect
|
|
||||||
style="display:none;fill:#95d220"
|
|
||||||
id="rect47"
|
|
||||||
height="9.279274"
|
|
||||||
width="9.279274"
|
|
||||||
class="st4"
|
|
||||||
y="214.00124"
|
|
||||||
x="250.61948" /><path
|
|
||||||
class="st2"
|
|
||||||
d="m 266.14156,214.00123 c 2.0597,0 3.75842,1.67749 3.75842,3.75843 l 0,1.76242 c 0,2.05971 -1.69872,3.75843 -3.75842,3.75843 l -42.38314,0 C 221.67749,223.25927 220,221.58179 220,219.52208 l 0,-1.76242 c 0,-2.0597 1.67749,-3.75843 3.75842,-3.75843 l 42.38314,0 m 0,-1.48638 -42.38314,0 c -2.88783,0 -5.2448,2.33575 -5.2448,5.22357 l 0,1.76243 c 0,2.88783 2.35697,5.24481 5.2448,5.24481 l 42.40437,0 c 2.88783,0 5.24481,-2.35698 5.24481,-5.24481 l 0,-1.76243 c -0.0212,-2.88782 -2.37821,-5.22357 -5.26604,-5.22357 l 0,0 z"
|
|
||||||
id="path53"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="display:none;fill:#ffffff" /><path
|
|
||||||
style="fill:#ffffff"
|
|
||||||
d="m 57.097656,30.69922 0,19.30078 9.06836,0 c 4.22557,0 6.474893,-2.12355 6.496093,-5.47852 0,-2.14464 -1.017672,-3.78004 -3.013671,-4.67187 l 0,-0.041 c 1.507609,-0.9343 2.166015,-2.10331 2.166015,-3.9082 0,-2.73919 -1.848098,-5.20117 -5.861328,-5.20117 l -8.855469,0 z m 18.75,0 0,19.30078 2.271485,0 0,-7.72852 -0.232422,-0.23437 4.585937,0 c 2.54808,0 4.012966,0.91391 4.947266,2.88867 L 89.820312,50 92.367188,50 89.4375,43.96875 c -0.63702,-1.35898 -1.614284,-2.20763 -2.527344,-2.58984 l 0,-0.043 c 2.1234,-0.55208 3.865235,-2.42042 3.865235,-4.94727 0,-3.80089 -2.951713,-5.68945 -6.476563,-5.68945 l -8.451172,0 z m 18.876953,0 0,19.30078 2.273438,0 0,-19.30078 -2.273438,0 z m 13.419921,0 L 99.650391,50 l 2.484379,0 2.03906,-4.65039 -0.12695,-0.23438 10.57421,0 -0.12695,0.23438 2.03906,4.65039 2.48438,0 -8.47266,-19.30078 -2.40039,0 z m 13.33594,0 0,19.30078 2.27148,0 0,-7.72852 -0.23437,-0.23437 4.58789,0 c 2.54808,0 4.01296,0.91391 4.94726,2.88867 L 135.45117,50 138,50 135.07031,43.96875 c -0.63702,-1.35898 -1.61427,-2.20763 -2.52734,-2.58984 l 0,-0.043 c 2.12341,-0.55208 3.86523,-2.42042 3.86523,-4.94727 0,-3.80089 -2.95171,-5.68945 -6.47656,-5.68945 l -8.45117,0 z m -62.322267,2.14453 6.560547,0 c 2.46315,0 3.759766,0.9967 3.759766,3.03516 0,1.71996 -0.999336,3.10156 -3.759766,3.10156 l -6.560547,0 0.234375,-0.23438 0,-5.66992 -0.234375,-0.23242 z m 18.728516,0 6.433593,0 c 2.378211,0 4.14091,0.97535 4.16211,3.52344 0,2.03846 -1.634356,3.5039 -4.416016,3.5039 l -6.179687,0 0.232422,-0.23242 0,-6.5625 -0.232422,-0.23242 z m 45.652341,0 6.4336,0 c 2.35698,0 4.14062,0.97535 4.14062,3.52344 0,2.03846 -1.61288,3.5039 -4.39453,3.5039 l -6.17969,0 0.23438,-0.23242 0,-6.5625 -0.23438,-0.23242 z m -14.20508,0.21094 0.043,0 0.57227,1.93359 3.39844,7.75 0.23242,0.23242 -8.4707,0 0.23242,-0.23242 3.39843,-7.75 0.59375,-1.93359 z m -50.197261,8.07031 7.007812,0 c 2.84536,0 4.16211,1.3153 4.16211,3.375 0,2.14464 -1.189095,3.33398 -4.140625,3.33398 l -7.029297,0 0.234375,-0.23437 0,-6.24219 -0.234375,-0.23242 z"
|
|
||||||
id="path57"
|
|
||||||
inkscape:connector-curvature="0" /><g
|
|
||||||
id="g4770"
|
|
||||||
transform="matrix(0.21276595,0,0,0.21276595,32.24269,18.624329)"><path
|
|
||||||
id="path13-3"
|
|
||||||
d="m -86.640255,-87.534339 c -9.7,0 -17.701175,7.999219 -17.701175,17.699219 l 0,22.5 43.601565,0 0,-22.5 c 0,-9.7 -7.901562,-17.699219 -17.601562,-17.699219 l -8.298828,0 z m 96.999999,0 c -9.69999995,0 -17.7011699,7.999219 -17.7011699,17.699219 l 0,119.500001 43.6015599,0 0,-119.500001 c 0,-9.7 -7.90156,-17.699219 -17.60156,-17.699219 l -8.29883,0 z m -114.701174,97.800781 0,119.499998 c 0,9.7 7.901175,17.69922 17.701175,17.69922 l 8.298828,0 c 9.7,0 17.701172,-7.99922 17.701172,-17.69922 l 0,-119.499998 -43.701175,0 z m 97.0000041,96.999998 0,22.5 c 0,9.7 8.00116995,17.69922 17.7011699,17.69922 l 8.29883,0 c 9.7,0 17.70117,-7.99922 17.70117,-17.69922 l 0,-22.5 -43.7011699,0 z"
|
|
||||||
style="fill:#87c214"
|
|
||||||
inkscape:connector-curvature="0" /><path
|
|
||||||
id="path35"
|
|
||||||
d="m -133.84143,-40.33512 c -9.7,0 -17.69922,7.901172 -17.69922,17.701172 l 0,8.298828 c 0,9.7000005 7.89922,17.7011725 17.69922,17.7011725 l 119.500004,0 0,-43.7011725 -119.500004,0 z m 177.101564,0 0,43.7011725 22.5,0 c 9.7,0 17.69922,-7.901172 17.69922,-17.7011725 l 0,-8.298828 c 0,-9.8 -7.99922,-17.701172 -17.69922,-17.701172 l -22.5,0 z M -133.84143,56.664881 c -9.7,0 -17.69922,7.90117 -17.69922,17.70117 l 0,8.29883 c 0,9.7 7.89922,17.701169 17.69922,17.701169 l 22.5,0 0,-43.701169 -22.5,0 z m 80.101565,0 0,43.701169 119.499999,0 c 9.7,0 17.69922,-8.001169 17.69922,-17.701169 l 0,-8.29883 c 0,-9.8 -7.99922,-17.70117 -17.69922,-17.70117 l -119.499999,0 z"
|
|
||||||
style="fill:#95d220"
|
|
||||||
inkscape:connector-curvature="0" /></g></svg>
|
|
||||||
|
Before Width: | Height: | Size: 8.7 KiB |
@@ -1,154 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
version="1.1"
|
|
||||||
id="Ebene_1"
|
|
||||||
x="0px"
|
|
||||||
y="0px"
|
|
||||||
viewBox="0 0 235 234.99999"
|
|
||||||
xml:space="preserve"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="logo_no_text.svg"
|
|
||||||
width="235"
|
|
||||||
height="235"><metadata
|
|
||||||
id="metadata71"><rdf:RDF><cc:Work
|
|
||||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
|
||||||
id="defs69" /><sodipodi:namedview
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1"
|
|
||||||
objecttolerance="10"
|
|
||||||
gridtolerance="10"
|
|
||||||
guidetolerance="10"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1021"
|
|
||||||
id="namedview67"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:zoom="2"
|
|
||||||
inkscape:cx="42.80241"
|
|
||||||
inkscape:cy="93.181868"
|
|
||||||
inkscape:window-x="1443"
|
|
||||||
inkscape:window-y="23"
|
|
||||||
inkscape:window-maximized="0"
|
|
||||||
inkscape:current-layer="Ebene_1"
|
|
||||||
fit-margin-top="0"
|
|
||||||
fit-margin-left="0"
|
|
||||||
fit-margin-right="0"
|
|
||||||
fit-margin-bottom="0" /><style
|
|
||||||
type="text/css"
|
|
||||||
id="style3">
|
|
||||||
.st0{display:none;fill:#87C214;}
|
|
||||||
.st1{fill:#87C214;}
|
|
||||||
.st2{display:none;fill:#FFFFFF;}
|
|
||||||
.st3{fill:#95D220;}
|
|
||||||
.st4{display:none;fill:#95D220;}
|
|
||||||
</style><g
|
|
||||||
id="g5"
|
|
||||||
transform="translate(-0.5,0)"><g
|
|
||||||
id="g7"><g
|
|
||||||
id="g9"><rect
|
|
||||||
x="47.700001"
|
|
||||||
y="47.200001"
|
|
||||||
class="st0"
|
|
||||||
width="43.700001"
|
|
||||||
height="43.700001"
|
|
||||||
id="rect11"
|
|
||||||
style="display:none;fill:#87c214" /><path
|
|
||||||
class="st1"
|
|
||||||
d="m 47.7,97.8 0,119.5 c 0,9.7 7.9,17.7 17.7,17.7 l 8.3,0 c 9.7,0 17.7,-8 17.7,-17.7 l 0,-119.5 -43.7,0 z"
|
|
||||||
id="path13"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="fill:#87c214" /><path
|
|
||||||
class="st1"
|
|
||||||
d="m 91.3,40.2 0,-22.5 C 91.3,8 83.4,0 73.7,0 L 65.4,0 C 55.7,0 47.7,8 47.7,17.7 l 0,22.5 43.6,0 z"
|
|
||||||
id="path15"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="fill:#87c214" /></g><path
|
|
||||||
class="st2"
|
|
||||||
d="m 73.7,0 c 9.7,0 17.7,8 17.7,17.7 l 0,199.7 c 0,9.7 -8,17.7 -17.7,17.7 l -8.3,0 c -9.7,0 -17.7,-8 -17.7,-17.7 l 0,-199.7 C 47.7,8 55.6,0 65.3,0 l 8.4,0 m 0,-7 -8.3,0 C 51.7,-7 40.7,4.1 40.7,17.7 l 0,199.7 c 0,13.6 11.1,24.7 24.7,24.7 l 8.3,0 c 13.6,0 24.7,-11.1 24.7,-24.7 l 0,-199.7 C 98.3,4.1 87.3,-7 73.7,-7 l 0,0 z"
|
|
||||||
id="path17"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="display:none;fill:#ffffff" /></g><g
|
|
||||||
id="g19"><g
|
|
||||||
id="g21"><path
|
|
||||||
class="st1"
|
|
||||||
d="m 188.3,137.2 0,-119.5 C 188.3,8 180.4,0 170.7,0 l -8.3,0 c -9.7,0 -17.7,8 -17.7,17.7 l 0,119.5 43.6,0 z"
|
|
||||||
id="path23"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="fill:#87c214" /><rect
|
|
||||||
x="144.7"
|
|
||||||
y="144.2"
|
|
||||||
class="st0"
|
|
||||||
width="43.700001"
|
|
||||||
height="43.700001"
|
|
||||||
id="rect25"
|
|
||||||
style="display:none;fill:#87c214" /><path
|
|
||||||
class="st1"
|
|
||||||
d="m 144.7,194.8 0,22.5 c 0,9.7 8,17.7 17.7,17.7 l 8.3,0 c 9.7,0 17.7,-8 17.7,-17.7 l 0,-22.5 -43.7,0 z"
|
|
||||||
id="path27"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="fill:#87c214" /></g><path
|
|
||||||
class="st2"
|
|
||||||
d="m 170.7,0 c 9.7,0 17.7,8 17.7,17.7 l 0,199.7 c 0,9.7 -7.9,17.7 -17.7,17.7 l -8.3,0 c -9.7,0 -17.7,-8 -17.7,-17.7 l 0,-199.7 C 144.7,8 152.7,0 162.4,0 l 8.3,0 m 0,-7 -8.3,0 c -13.6,0 -24.7,11.1 -24.7,24.7 l 0,199.7 c 0,13.6 11.1,24.7 24.7,24.7 l 8.3,0 c 13.6,0 24.7,-11.1 24.7,-24.7 l 0,-199.7 C 195.3,4.1 184.3,-7 170.7,-7 l 0,0 z"
|
|
||||||
id="path29"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="display:none;fill:#ffffff" /></g><g
|
|
||||||
id="g31"><g
|
|
||||||
id="g33"><path
|
|
||||||
class="st3"
|
|
||||||
d="m 40.7,144.2 -22.5,0 c -9.7,0 -17.7,7.9 -17.7,17.7 l 0,8.3 c 0,9.7 7.9,17.7 17.7,17.7 l 22.5,0 0,-43.7 z"
|
|
||||||
id="path35"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="fill:#95d220" /><rect
|
|
||||||
x="47.700001"
|
|
||||||
y="144.2"
|
|
||||||
class="st4"
|
|
||||||
width="43.700001"
|
|
||||||
height="43.700001"
|
|
||||||
id="rect37"
|
|
||||||
style="display:none;fill:#95d220" /><path
|
|
||||||
class="st3"
|
|
||||||
d="m 217.8,144.2 -119.5,0 0,43.7 119.5,0 c 9.7,0 17.7,-8 17.7,-17.7 l 0,-8.3 c 0,-9.8 -8,-17.7 -17.7,-17.7 z"
|
|
||||||
id="path39"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="fill:#95d220" /></g><path
|
|
||||||
class="st2"
|
|
||||||
d="m 217.8,144.2 c 9.7,0 17.7,7.9 17.7,17.7 l 0,8.3 c 0,9.7 -8,17.7 -17.7,17.7 l -199.6,0 c -9.7,0 -17.7,-8 -17.7,-17.7 l 0,-8.3 c 0,-9.7 7.9,-17.7 17.7,-17.7 l 199.6,0 m 0,-7 -199.6,0 c -13.6,0 -24.7,11.1 -24.7,24.7 l 0,8.3 c 0,13.6 11.1,24.7 24.7,24.7 l 199.7,0 c 13.6,0 24.7,-11.1 24.7,-24.7 l 0,-8.3 c -0.1,-13.7 -11.2,-24.7 -24.8,-24.7 l 0,0 z"
|
|
||||||
id="path41"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="display:none;fill:#ffffff" /></g><g
|
|
||||||
id="g43"><g
|
|
||||||
id="g45"><rect
|
|
||||||
x="144.7"
|
|
||||||
y="47.200001"
|
|
||||||
class="st4"
|
|
||||||
width="43.700001"
|
|
||||||
height="43.700001"
|
|
||||||
id="rect47"
|
|
||||||
style="display:none;fill:#95d220" /><path
|
|
||||||
class="st3"
|
|
||||||
d="m 137.7,47.2 -119.5,0 C 8.5,47.2 0.5,55.1 0.5,64.9 l 0,8.3 c 0,9.7 7.9,17.7 17.7,17.7 l 119.5,0 0,-43.7 z"
|
|
||||||
id="path49"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="fill:#95d220" /><path
|
|
||||||
class="st3"
|
|
||||||
d="m 217.8,47.2 -22.5,0 0,43.7 22.5,0 c 9.7,0 17.7,-7.9 17.7,-17.7 l 0,-8.3 c 0,-9.8 -8,-17.7 -17.7,-17.7 z"
|
|
||||||
id="path51"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="fill:#95d220" /></g><path
|
|
||||||
class="st2"
|
|
||||||
d="m 217.8,47.2 c 9.7,0 17.7,7.9 17.7,17.7 l 0,8.3 c 0,9.7 -8,17.7 -17.7,17.7 l -199.6,0 C 8.5,90.9 0.5,83 0.5,73.2 l 0,-8.3 c 0,-9.7 7.9,-17.7 17.7,-17.7 l 199.6,0 m 0,-7 -199.6,0 c -13.6,0 -24.7,11 -24.7,24.6 l 0,8.3 c 0,13.6 11.1,24.7 24.7,24.7 l 199.7,0 c 13.6,0 24.7,-11.1 24.7,-24.7 l 0,-8.3 C 242.5,51.2 231.4,40.2 217.8,40.2 l 0,0 z"
|
|
||||||
id="path53"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="display:none;fill:#ffffff" /></g></g></svg>
|
|
||||||
|
Before Width: | Height: | Size: 6.7 KiB |
@@ -1,108 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
version="1.1"
|
|
||||||
id="Ebene_1"
|
|
||||||
x="0px"
|
|
||||||
y="0px"
|
|
||||||
viewBox="0 0 235 309.99999"
|
|
||||||
xml:space="preserve"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="logo_vertical_black.svg"
|
|
||||||
width="235"
|
|
||||||
height="310"><metadata
|
|
||||||
id="metadata71"><rdf:RDF><cc:Work
|
|
||||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
|
||||||
id="defs69" /><sodipodi:namedview
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1"
|
|
||||||
objecttolerance="10"
|
|
||||||
gridtolerance="10"
|
|
||||||
guidetolerance="10"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1021"
|
|
||||||
id="namedview67"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:zoom="2"
|
|
||||||
inkscape:cx="44.30241"
|
|
||||||
inkscape:cy="167.18188"
|
|
||||||
inkscape:window-x="1440"
|
|
||||||
inkscape:window-y="23"
|
|
||||||
inkscape:window-maximized="0"
|
|
||||||
inkscape:current-layer="Ebene_1" /><style
|
|
||||||
type="text/css"
|
|
||||||
id="style3">
|
|
||||||
.st0{display:none;fill:#87C214;}
|
|
||||||
.st1{fill:#87C214;}
|
|
||||||
.st2{display:none;fill:#FFFFFF;}
|
|
||||||
.st3{fill:#95D220;}
|
|
||||||
.st4{display:none;fill:#95D220;}
|
|
||||||
</style><rect
|
|
||||||
style="display:none;fill:#87c214"
|
|
||||||
id="rect11"
|
|
||||||
height="43.700001"
|
|
||||||
width="43.700001"
|
|
||||||
class="st0"
|
|
||||||
y="47.199989"
|
|
||||||
x="47.200001" /><path
|
|
||||||
style="fill:#87c214"
|
|
||||||
d="M 64.900391 0 C 55.200391 0 47.199219 7.9992183 47.199219 17.699219 L 47.199219 40.199219 L 90.800781 40.199219 L 90.800781 17.699219 C 90.800781 7.9992183 82.899219 -4.7369516e-15 73.199219 0 L 64.900391 0 z M 161.90039 0 C 152.20039 0 144.19922 7.9992183 144.19922 17.699219 L 144.19922 137.19922 L 187.80078 137.19922 L 187.80078 17.699219 C 187.80078 7.9992183 179.89922 -4.7369516e-15 170.19922 0 L 161.90039 0 z M 47.199219 97.800781 L 47.199219 217.30078 C 47.199219 227.00078 55.100391 235 64.900391 235 L 73.199219 235 C 82.899219 235 90.900391 227.00078 90.900391 217.30078 L 90.900391 97.800781 L 47.199219 97.800781 z M 144.19922 194.80078 L 144.19922 217.30078 C 144.19922 227.00078 152.20039 235 161.90039 235 L 170.19922 235 C 179.89922 235 187.90039 227.00078 187.90039 217.30078 L 187.90039 194.80078 L 144.19922 194.80078 z "
|
|
||||||
id="path13" /><path
|
|
||||||
class="st2"
|
|
||||||
d="m 73.2,-1.221e-5 c 9.7,0 17.7,8.00000001 17.7,17.70000021 l 0,199.700002 c 0,9.7 -8,17.7 -17.7,17.7 l -8.3,0 c -9.7,0 -17.7,-8 -17.7,-17.7 l 0,-199.700002 C 47.2,7.9999878 55.1,-1.221e-5 64.8,-1.221e-5 l 8.4,0 m 0,-6.99999999 -8.3,0 c -13.7,0 -24.7,11.1 -24.7,24.7000002 l 0,199.700002 c 0,13.6 11.1,24.7 24.7,24.7 l 8.3,0 c 13.6,0 24.7,-11.1 24.7,-24.7 l 0,-199.700002 C 97.8,4.0999878 86.8,-7.0000122 73.2,-7.0000122 l 0,0 z"
|
|
||||||
id="path17"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="display:none;fill:#ffffff" /><rect
|
|
||||||
style="display:none;fill:#87c214"
|
|
||||||
id="rect25"
|
|
||||||
height="43.700001"
|
|
||||||
width="43.700001"
|
|
||||||
class="st0"
|
|
||||||
y="144.19998"
|
|
||||||
x="144.2" /><path
|
|
||||||
class="st2"
|
|
||||||
d="m 170.2,-1.221e-5 c 9.7,0 17.7,8.00000001 17.7,17.70000021 l 0,199.700002 c 0,9.7 -7.9,17.7 -17.7,17.7 l -8.3,0 c -9.7,0 -17.7,-8 -17.7,-17.7 l 0,-199.700002 c 0,-9.7000002 8,-17.70000021 17.7,-17.70000021 l 8.3,0 m 0,-6.99999999 -8.3,0 c -13.6,0 -24.7,11.1 -24.7,24.7000002 l 0,199.700002 c 0,13.6 11.1,24.7 24.7,24.7 l 8.3,0 c 13.6,0 24.7,-11.1 24.7,-24.7 l 0,-199.700002 C 194.8,4.0999878 183.8,-7.0000122 170.2,-7.0000122 l 0,0 z"
|
|
||||||
id="path29"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="display:none;fill:#ffffff" /><path
|
|
||||||
style="fill:#95d220"
|
|
||||||
d="M 17.699219 47.199219 C 7.9992186 47.199219 2.3684758e-15 55.100391 0 64.900391 L 0 73.199219 C 0 82.899219 7.8992186 90.900391 17.699219 90.900391 L 137.19922 90.900391 L 137.19922 47.199219 L 17.699219 47.199219 z M 194.80078 47.199219 L 194.80078 90.900391 L 217.30078 90.900391 C 227.00078 90.900391 235 82.999219 235 73.199219 L 235 64.900391 C 235 55.100391 227.00078 47.199219 217.30078 47.199219 L 194.80078 47.199219 z M 17.699219 144.19922 C 7.9992186 144.19922 2.3684758e-15 152.10039 0 161.90039 L 0 170.19922 C 0 179.89922 7.8992186 187.90039 17.699219 187.90039 L 40.199219 187.90039 L 40.199219 144.19922 L 17.699219 144.19922 z M 97.800781 144.19922 L 97.800781 187.90039 L 217.30078 187.90039 C 227.00078 187.90039 235 179.89922 235 170.19922 L 235 161.90039 C 235 152.10039 227.00078 144.19922 217.30078 144.19922 L 97.800781 144.19922 z "
|
|
||||||
id="path35" /><rect
|
|
||||||
style="display:none;fill:#95d220"
|
|
||||||
id="rect37"
|
|
||||||
height="43.700001"
|
|
||||||
width="43.700001"
|
|
||||||
class="st4"
|
|
||||||
y="144.19998"
|
|
||||||
x="47.200001" /><path
|
|
||||||
class="st2"
|
|
||||||
d="m 217.3,144.19999 c 9.7,0 17.7,7.9 17.7,17.7 l 0,8.3 c 0,9.7 -8,17.7 -17.7,17.7 l -199.6,0 c -9.7,0 -17.7,-8 -17.7,-17.7 l 0,-8.3 c 0,-9.7 7.9,-17.7 17.7,-17.7 l 199.6,0 m 0,-7 -199.6,0 c -13.6,0 -24.7,11.1 -24.7,24.7 l 0,8.3 c 0,13.6 11.1,24.7 24.7,24.7 l 199.7,0 c 13.6,0 24.7,-11.1 24.7,-24.7 l 0,-8.3 c -0.1,-13.7 -11.2,-24.7 -24.8,-24.7 l 0,0 z"
|
|
||||||
id="path41"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="display:none;fill:#ffffff" /><rect
|
|
||||||
style="display:none;fill:#95d220"
|
|
||||||
id="rect47"
|
|
||||||
height="43.700001"
|
|
||||||
width="43.700001"
|
|
||||||
class="st4"
|
|
||||||
y="47.199989"
|
|
||||||
x="144.2" /><path
|
|
||||||
class="st2"
|
|
||||||
d="m 217.3,47.199988 c 9.7,0 17.7,7.9 17.7,17.7 l 0,8.3 c 0,9.7 -8,17.7 -17.7,17.7 l -199.6,0 c -9.7,0 -17.7,-7.9 -17.7,-17.7 l 0,-8.3 c 0,-9.7 7.9,-17.7 17.7,-17.7 l 199.6,0 m 0,-7 -199.6,0 c -13.6,0 -24.7,11 -24.7,24.6 l 0,8.3 c 0,13.6 11.1,24.7 24.7,24.7 l 199.7,0 c 13.6,0 24.7,-11.1 24.7,-24.7 l 0,-8.3 c -0.1,-13.6 -11.2,-24.6 -24.8,-24.6 l 0,0 z"
|
|
||||||
id="path53"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="display:none;fill:#ffffff" /><path
|
|
||||||
d="M 0 253.90039 L 0 310 L 26.265625 310 C 38.649816 310 45.142578 303.79961 45.142578 294.09961 C 45.142578 287.79961 42.24573 283.1 36.453125 280.5 L 36.453125 280.40039 C 40.847515 277.70039 42.746094 274.3 42.746094 269 C 42.746094 261 37.25318 253.90039 25.667969 253.90039 L 0 253.90039 z M 54.53125 253.90039 L 54.53125 310 L 61.121094 310 L 61.121094 287.5 L 60.423828 286.80078 L 73.705078 286.80078 C 81.095643 286.80078 85.291724 289.39922 87.988281 295.19922 L 94.978516 310 L 102.36914 310 L 94.080078 292.5 C 92.282373 288.6 89.385747 286.1 86.789062 285 L 86.789062 284.90039 C 92.881286 283.30039 97.974609 277.8 97.974609 270.5 C 97.974609 259.4 89.386477 253.90039 79.099609 253.90039 L 54.53125 253.90039 z M 109.25977 253.90039 L 109.25977 310 L 115.85156 310 L 115.85156 253.90039 L 109.25977 253.90039 z M 148.01172 253.90039 L 123.3418 310 L 130.5332 310 L 136.52539 296.5 L 136.22656 295.80078 L 166.88672 295.80078 L 166.58789 296.5 L 172.58008 310 L 179.77148 310 L 155.00195 253.90039 L 148.01172 253.90039 z M 187.16016 253.90039 L 187.16016 310 L 193.75195 310 L 193.75195 287.5 L 193.05273 286.80078 L 206.33594 286.80078 C 213.72651 286.80078 217.92258 289.39922 220.61914 295.19922 L 227.60938 310 L 235 310 L 226.71094 292.5 C 224.91324 288.6 222.0166 286.1 219.41992 285 L 219.41992 284.90039 C 225.51214 283.30039 230.60547 277.8 230.60547 270.5 C 230.60547 259.4 222.01733 253.90039 211.73047 253.90039 L 187.16016 253.90039 z M 5.8925781 260.09961 L 24.96875 260.09961 C 32.15957 260.09961 35.953125 263 35.953125 269 C 35.953125 274 32.95855 278 24.96875 278 L 5.8925781 278 L 6.5917969 277.30078 L 6.5917969 260.80078 L 5.8925781 260.09961 z M 60.423828 260.09961 L 79.099609 260.09961 C 85.89094 260.09961 91.083724 262.90039 91.183594 270.40039 C 91.183594 276.40039 86.490064 280.59961 78.400391 280.59961 L 60.423828 280.59961 L 61.121094 279.90039 L 61.121094 260.80078 L 60.423828 260.09961 z M 192.95312 260.09961 L 211.62891 260.09961 C 218.52012 260.09961 223.71484 262.90039 223.71484 270.40039 C 223.71484 276.40039 219.02131 280.59961 210.93164 280.59961 L 192.95312 280.59961 L 193.65234 279.90039 L 193.65234 260.80078 L 192.95312 260.09961 z M 151.60547 260.80078 L 151.70703 260.80078 L 153.4043 266.40039 L 163.29102 288.90039 L 163.99023 289.59961 L 139.32227 289.59961 L 140.02148 288.90039 L 149.9082 266.40039 L 151.60547 260.80078 z M 5.8925781 284.19922 L 26.265625 284.19922 C 34.555043 284.19922 38.351562 287.99961 38.351562 294.09961 C 38.351562 300.29961 34.854661 303.80078 26.265625 303.80078 L 5.8925781 303.80078 L 6.5917969 303.09961 L 6.5917969 284.90039 L 5.8925781 284.19922 z "
|
|
||||||
id="path57" /></svg>
|
|
||||||
|
Before Width: | Height: | Size: 8.8 KiB |
@@ -1,5 +1,6 @@
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
apply plugin: 'witness'
|
apply plugin: 'witness'
|
||||||
|
apply plugin: 'com.neenbedankt.android-apt'
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
def supportVersion = '23.2.1'
|
def supportVersion = '23.2.1'
|
||||||
@@ -29,12 +30,16 @@ dependencies {
|
|||||||
compile 'info.guardianproject.trustedintents:trustedintents:0.2'
|
compile 'info.guardianproject.trustedintents:trustedintents:0.2'
|
||||||
compile 'de.hdodenhof:circleimageview:2.1.0'
|
compile 'de.hdodenhof:circleimageview:2.1.0'
|
||||||
compile 'com.google.zxing:core:3.2.1'
|
compile 'com.google.zxing:core:3.2.1'
|
||||||
|
apt 'com.google.dagger:dagger-compiler:2.0.2'
|
||||||
provided 'javax.annotation:jsr250-api:1.0'
|
provided 'javax.annotation:jsr250-api:1.0'
|
||||||
compile 'com.jpardogo.materialtabstrip:library:1.1.0'
|
compile 'com.jpardogo.materialtabstrip:library:1.1.0'
|
||||||
compile 'com.github.bumptech.glide:glide:3.7.0'
|
compile 'com.github.bumptech.glide:glide:3.7.0'
|
||||||
compile 'uk.co.samuelwall:material-tap-target-prompt:1.3.0'
|
compile 'uk.co.samuelwall:material-tap-target-prompt:1.3.0'
|
||||||
|
|
||||||
testCompile project(path: ':bramble-core', configuration: 'testOutput')
|
testCompile 'junit:junit:4.12'
|
||||||
|
testCompile 'net.jodah:concurrentunit:0.4.2'
|
||||||
|
testApt 'com.google.dagger:dagger-compiler:2.0.2'
|
||||||
|
testCompile project(path: ':briar-tests')
|
||||||
testCompile 'org.robolectric:robolectric:3.0'
|
testCompile 'org.robolectric:robolectric:3.0'
|
||||||
testCompile 'org.mockito:mockito-core:1.10.19'
|
testCompile 'org.mockito:mockito-core:1.10.19'
|
||||||
}
|
}
|
||||||
@@ -62,19 +67,6 @@ dependencyVerification {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
def getGitHash = { ->
|
|
||||||
def stdout = new ByteArrayOutputStream()
|
|
||||||
try {
|
|
||||||
exec {
|
|
||||||
commandLine 'git', 'rev-parse', '--short', 'HEAD'
|
|
||||||
standardOutput = stdout
|
|
||||||
}
|
|
||||||
return stdout.toString().trim()
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
return "No commit hash"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 23
|
compileSdkVersion 23
|
||||||
buildToolsVersion "23.0.3"
|
buildToolsVersion "23.0.3"
|
||||||
@@ -83,7 +75,6 @@ android {
|
|||||||
minSdkVersion 14
|
minSdkVersion 14
|
||||||
targetSdkVersion 22
|
targetSdkVersion 22
|
||||||
resValue "string", "app_package", "org.briarproject.briar"
|
resValue "string", "app_package", "org.briarproject.briar"
|
||||||
buildConfigField "String", "GitHash", "\"${getGitHash()}\""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
|
|||||||
@@ -2,9 +2,12 @@
|
|||||||
<manifest
|
<manifest
|
||||||
package="org.briarproject.briar"
|
package="org.briarproject.briar"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:versionCode="13"
|
android:versionCode="13"
|
||||||
android:versionName="0.13">
|
android:versionName="0.13">
|
||||||
|
|
||||||
|
<uses-sdk tools:overrideLibrary="android.support.v14.preference"/>
|
||||||
|
|
||||||
<uses-feature android:name="android.hardware.bluetooth"/>
|
<uses-feature android:name="android.hardware.bluetooth"/>
|
||||||
<uses-feature android:name="android.hardware.camera" />
|
<uses-feature android:name="android.hardware.camera" />
|
||||||
|
|
||||||
@@ -25,7 +28,7 @@
|
|||||||
android:allowBackup="false"
|
android:allowBackup="false"
|
||||||
android:icon="@drawable/ic_launcher"
|
android:icon="@drawable/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:logo="@mipmap/ic_launcher_round"
|
android:logo="@drawable/logo"
|
||||||
android:theme="@style/BriarTheme">
|
android:theme="@style/BriarTheme">
|
||||||
|
|
||||||
<service
|
<service
|
||||||
@@ -44,7 +47,7 @@
|
|||||||
android:label="@string/crash_report_title"
|
android:label="@string/crash_report_title"
|
||||||
android:launchMode="singleInstance"
|
android:launchMode="singleInstance"
|
||||||
android:process=":briar_error_handler"
|
android:process=":briar_error_handler"
|
||||||
android:theme="@style/BriarTheme.NoActionBar"
|
android:theme="@style/BriarThemeNoActionBar.Default"
|
||||||
android:windowSoftInputMode="stateHidden">
|
android:windowSoftInputMode="stateHidden">
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
@@ -67,7 +70,7 @@
|
|||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".android.splash.SplashScreenActivity"
|
android:name=".android.splash.SplashScreenActivity"
|
||||||
android:theme="@style/BriarTheme.NoActionBar"
|
android:theme="@style/BriarThemeNoActionBar.Default"
|
||||||
android:label="@string/app_name">
|
android:label="@string/app_name">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
@@ -77,14 +80,14 @@
|
|||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".android.navdrawer.NavDrawerActivity"
|
android:name=".android.navdrawer.NavDrawerActivity"
|
||||||
android:theme="@style/BriarTheme.NoActionBar"
|
android:theme="@style/BriarThemeNoActionBar.Default"
|
||||||
android:launchMode="singleTop">
|
android:launchMode="singleTop">
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".android.contact.ConversationActivity"
|
android:name=".android.contact.ConversationActivity"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:theme="@style/BriarTheme.NoActionBar"
|
android:theme="@style/BriarThemeNoActionBar.Default"
|
||||||
android:parentActivityName=".android.navdrawer.NavDrawerActivity"
|
android:parentActivityName=".android.navdrawer.NavDrawerActivity"
|
||||||
android:windowSoftInputMode="stateHidden|adjustResize">
|
android:windowSoftInputMode="stateHidden|adjustResize">
|
||||||
<meta-data
|
<meta-data
|
||||||
@@ -108,7 +111,6 @@
|
|||||||
android:name=".android.privategroup.conversation.GroupActivity"
|
android:name=".android.privategroup.conversation.GroupActivity"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:parentActivityName=".android.navdrawer.NavDrawerActivity"
|
android:parentActivityName=".android.navdrawer.NavDrawerActivity"
|
||||||
android:theme="@style/BriarTheme.NoActionBar"
|
|
||||||
android:windowSoftInputMode="adjustResize|stateHidden">
|
android:windowSoftInputMode="adjustResize|stateHidden">
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
@@ -192,7 +194,6 @@
|
|||||||
android:name=".android.forum.ForumActivity"
|
android:name=".android.forum.ForumActivity"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:parentActivityName=".android.navdrawer.NavDrawerActivity"
|
android:parentActivityName=".android.navdrawer.NavDrawerActivity"
|
||||||
android:theme="@style/BriarTheme.NoActionBar"
|
|
||||||
android:windowSoftInputMode="adjustResize|stateHidden">
|
android:windowSoftInputMode="adjustResize|stateHidden">
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
@@ -244,11 +245,11 @@
|
|||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".android.blog.BlogActivity"
|
android:name=".android.blog.BlogActivity"
|
||||||
android:parentActivityName=".android.navdrawer.NavDrawerActivity"
|
android:parentActivityName=".android.navdrawer.NavDrawerActivity">
|
||||||
android:theme="@style/BriarTheme.NoActionBar">
|
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
android:value=".android.navdrawer.NavDrawerActivity"/>
|
android:value=".android.navdrawer.NavDrawerActivity"
|
||||||
|
/>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
@@ -307,7 +308,7 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".android.keyagreement.KeyAgreementActivity"
|
android:name=".android.keyagreement.KeyAgreementActivity"
|
||||||
android:label="@string/add_contact_title"
|
android:label="@string/add_contact_title"
|
||||||
android:theme="@style/BriarTheme.NoActionBar"
|
android:theme="@style/BriarThemeNoActionBar.Default"
|
||||||
android:parentActivityName=".android.navdrawer.NavDrawerActivity">
|
android:parentActivityName=".android.navdrawer.NavDrawerActivity">
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 29 KiB |
@@ -12,7 +12,6 @@ import android.os.Build;
|
|||||||
import android.support.annotation.UiThread;
|
import android.support.annotation.UiThread;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.support.v4.app.TaskStackBuilder;
|
import android.support.v4.app.TaskStackBuilder;
|
||||||
import android.support.v4.content.ContextCompat;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.contact.ContactId;
|
import org.briarproject.bramble.api.contact.ContactId;
|
||||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||||
@@ -328,8 +327,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
|||||||
} else if (settings.getBoolean("notifyPrivateMessages", true)) {
|
} else if (settings.getBoolean("notifyPrivateMessages", true)) {
|
||||||
NotificationCompat.Builder b =
|
NotificationCompat.Builder b =
|
||||||
new NotificationCompat.Builder(appContext);
|
new NotificationCompat.Builder(appContext);
|
||||||
b.setSmallIcon(R.drawable.notification_private_message);
|
b.setSmallIcon(R.drawable.message_notification_icon);
|
||||||
b.setColor(ContextCompat.getColor(appContext, R.color.briar_primary));
|
|
||||||
b.setContentTitle(appContext.getText(R.string.app_name));
|
b.setContentTitle(appContext.getText(R.string.app_name));
|
||||||
b.setContentText(appContext.getResources().getQuantityString(
|
b.setContentText(appContext.getResources().getQuantityString(
|
||||||
R.plurals.private_message_notification_text, contactTotal,
|
R.plurals.private_message_notification_text, contactTotal,
|
||||||
@@ -437,8 +435,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
|||||||
} else if (settings.getBoolean(PREF_NOTIFY_GROUP, true)) {
|
} else if (settings.getBoolean(PREF_NOTIFY_GROUP, true)) {
|
||||||
NotificationCompat.Builder b =
|
NotificationCompat.Builder b =
|
||||||
new NotificationCompat.Builder(appContext);
|
new NotificationCompat.Builder(appContext);
|
||||||
b.setSmallIcon(R.drawable.notification_private_group);
|
b.setSmallIcon(R.drawable.message_notification_icon);
|
||||||
b.setColor(ContextCompat.getColor(appContext, R.color.briar_primary));
|
|
||||||
b.setContentTitle(appContext.getText(R.string.app_name));
|
b.setContentTitle(appContext.getText(R.string.app_name));
|
||||||
b.setContentText(appContext.getResources().getQuantityString(
|
b.setContentText(appContext.getResources().getQuantityString(
|
||||||
R.plurals.group_message_notification_text, groupTotal,
|
R.plurals.group_message_notification_text, groupTotal,
|
||||||
@@ -533,8 +530,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
|||||||
} else if (settings.getBoolean("notifyForumPosts", true)) {
|
} else if (settings.getBoolean("notifyForumPosts", true)) {
|
||||||
NotificationCompat.Builder b =
|
NotificationCompat.Builder b =
|
||||||
new NotificationCompat.Builder(appContext);
|
new NotificationCompat.Builder(appContext);
|
||||||
b.setSmallIcon(R.drawable.notification_forum);
|
b.setSmallIcon(R.drawable.message_notification_icon);
|
||||||
b.setColor(ContextCompat.getColor(appContext, R.color.briar_primary));
|
|
||||||
b.setContentTitle(appContext.getText(R.string.app_name));
|
b.setContentTitle(appContext.getText(R.string.app_name));
|
||||||
b.setContentText(appContext.getResources().getQuantityString(
|
b.setContentText(appContext.getResources().getQuantityString(
|
||||||
R.plurals.forum_post_notification_text, forumTotal,
|
R.plurals.forum_post_notification_text, forumTotal,
|
||||||
@@ -629,8 +625,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
|||||||
} else if (settings.getBoolean(PREF_NOTIFY_BLOG, true)) {
|
} else if (settings.getBoolean(PREF_NOTIFY_BLOG, true)) {
|
||||||
NotificationCompat.Builder b =
|
NotificationCompat.Builder b =
|
||||||
new NotificationCompat.Builder(appContext);
|
new NotificationCompat.Builder(appContext);
|
||||||
b.setSmallIcon(R.drawable.notification_blog);
|
b.setSmallIcon(R.drawable.message_notification_icon);
|
||||||
b.setColor(ContextCompat.getColor(appContext, R.color.briar_primary));
|
|
||||||
b.setContentTitle(appContext.getText(R.string.app_name));
|
b.setContentTitle(appContext.getText(R.string.app_name));
|
||||||
b.setContentText(appContext.getResources().getQuantityString(
|
b.setContentText(appContext.getResources().getQuantityString(
|
||||||
R.plurals.blog_post_notification_text, blogTotal,
|
R.plurals.blog_post_notification_text, blogTotal,
|
||||||
@@ -690,8 +685,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
|||||||
private void updateIntroductionNotification() {
|
private void updateIntroductionNotification() {
|
||||||
NotificationCompat.Builder b =
|
NotificationCompat.Builder b =
|
||||||
new NotificationCompat.Builder(appContext);
|
new NotificationCompat.Builder(appContext);
|
||||||
b.setSmallIcon(R.drawable.notification_introduction);
|
b.setSmallIcon(R.drawable.introduction_notification);
|
||||||
b.setColor(ContextCompat.getColor(appContext, R.color.briar_primary));
|
|
||||||
b.setContentTitle(appContext.getText(R.string.app_name));
|
b.setContentTitle(appContext.getText(R.string.app_name));
|
||||||
b.setContentText(appContext.getResources().getQuantityString(
|
b.setContentText(appContext.getResources().getQuantityString(
|
||||||
R.plurals.introduction_notification_text, introductionTotal,
|
R.plurals.introduction_notification_text, introductionTotal,
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import android.os.Binder;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.support.v4.content.ContextCompat;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.db.DatabaseConfig;
|
import org.briarproject.bramble.api.db.DatabaseConfig;
|
||||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
@@ -76,8 +75,7 @@ public class BriarService extends Service {
|
|||||||
}
|
}
|
||||||
// Show an ongoing notification that the service is running
|
// Show an ongoing notification that the service is running
|
||||||
NotificationCompat.Builder b = new NotificationCompat.Builder(this);
|
NotificationCompat.Builder b = new NotificationCompat.Builder(this);
|
||||||
b.setSmallIcon(R.drawable.notification_ongoing);
|
b.setSmallIcon(R.drawable.ongoing_notification_icon);
|
||||||
b.setColor(ContextCompat.getColor(this, R.color.briar_primary));
|
|
||||||
b.setContentTitle(getText(R.string.ongoing_notification_title));
|
b.setContentTitle(getText(R.string.ongoing_notification_title));
|
||||||
b.setContentText(getText(R.string.ongoing_notification_text));
|
b.setContentText(getText(R.string.ongoing_notification_text));
|
||||||
b.setWhen(0); // Don't show the time
|
b.setWhen(0); // Don't show the time
|
||||||
|
|||||||
@@ -2,12 +2,10 @@ package org.briarproject.briar.android.activity;
|
|||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.support.annotation.UiThread;
|
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
|
||||||
import org.briarproject.briar.android.AndroidComponent;
|
import org.briarproject.briar.android.AndroidComponent;
|
||||||
import org.briarproject.briar.android.BriarApplication;
|
import org.briarproject.briar.android.BriarApplication;
|
||||||
import org.briarproject.briar.android.DestroyableContext;
|
import org.briarproject.briar.android.DestroyableContext;
|
||||||
@@ -118,10 +116,4 @@ public abstract class BaseActivity extends AppCompatActivity
|
|||||||
Object o = getSystemService(INPUT_METHOD_SERVICE);
|
Object o = getSystemService(INPUT_METHOD_SERVICE);
|
||||||
((InputMethodManager) o).hideSoftInputFromWindow(token, 0);
|
((InputMethodManager) o).hideSoftInputFromWindow(token, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@UiThread
|
|
||||||
public void handleDbException(DbException e) {
|
|
||||||
supportFinishAfterTransition();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,19 +3,10 @@ package org.briarproject.briar.android.activity;
|
|||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.v7.app.ActionBar;
|
|
||||||
import android.support.v7.widget.Toolbar;
|
|
||||||
import android.transition.Slide;
|
|
||||||
import android.transition.Transition;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.Window;
|
|
||||||
|
|
||||||
import org.briarproject.briar.R;
|
|
||||||
import org.briarproject.briar.android.controller.BriarController;
|
import org.briarproject.briar.android.controller.BriarController;
|
||||||
import org.briarproject.briar.android.controller.DbController;
|
import org.briarproject.briar.android.controller.DbController;
|
||||||
import org.briarproject.briar.android.controller.handler.UiResultHandler;
|
import org.briarproject.briar.android.controller.handler.UiResultHandler;
|
||||||
import org.briarproject.briar.android.fragment.BaseFragment;
|
|
||||||
import org.briarproject.briar.android.login.PasswordActivity;
|
import org.briarproject.briar.android.login.PasswordActivity;
|
||||||
import org.briarproject.briar.android.panic.ExitActivity;
|
import org.briarproject.briar.android.panic.ExitActivity;
|
||||||
|
|
||||||
@@ -28,7 +19,6 @@ import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
|
|||||||
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
||||||
import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
|
import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
|
||||||
import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
|
import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
|
||||||
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PASSWORD;
|
|
||||||
|
|
||||||
@SuppressLint("Registered")
|
@SuppressLint("Registered")
|
||||||
public abstract class BriarActivity extends BaseActivity {
|
public abstract class BriarActivity extends BaseActivity {
|
||||||
@@ -37,6 +27,8 @@ public abstract class BriarActivity extends BaseActivity {
|
|||||||
public static final String GROUP_ID = "briar.GROUP_ID";
|
public static final String GROUP_ID = "briar.GROUP_ID";
|
||||||
public static final String GROUP_NAME = "briar.GROUP_NAME";
|
public static final String GROUP_NAME = "briar.GROUP_NAME";
|
||||||
|
|
||||||
|
public static final int REQUEST_PASSWORD = 1;
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(BriarActivity.class.getName());
|
Logger.getLogger(BriarActivity.class.getName());
|
||||||
|
|
||||||
@@ -52,7 +44,7 @@ public abstract class BriarActivity extends BaseActivity {
|
|||||||
super.onActivityResult(request, result, data);
|
super.onActivityResult(request, result, data);
|
||||||
if (request == REQUEST_PASSWORD) {
|
if (request == REQUEST_PASSWORD) {
|
||||||
if (result == RESULT_OK) briarController.startAndBindService();
|
if (result == RESULT_OK) briarController.startAndBindService();
|
||||||
else supportFinishAfterTransition();
|
else finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,62 +53,11 @@ public abstract class BriarActivity extends BaseActivity {
|
|||||||
super.onStart();
|
super.onStart();
|
||||||
if (!briarController.hasEncryptionKey() && !isFinishing()) {
|
if (!briarController.hasEncryptionKey() && !isFinishing()) {
|
||||||
Intent i = new Intent(this, PasswordActivity.class);
|
Intent i = new Intent(this, PasswordActivity.class);
|
||||||
i.setFlags(FLAG_ACTIVITY_SINGLE_TOP);
|
i.setFlags(FLAG_ACTIVITY_NO_ANIMATION | FLAG_ACTIVITY_SINGLE_TOP);
|
||||||
startActivityForResult(i, REQUEST_PASSWORD);
|
startActivityForResult(i, REQUEST_PASSWORD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void showInitialFragment(BaseFragment f) {
|
|
||||||
getSupportFragmentManager().beginTransaction()
|
|
||||||
.replace(R.id.fragmentContainer, f, f.getUniqueTag())
|
|
||||||
.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void showNextFragment(BaseFragment f) {
|
|
||||||
getSupportFragmentManager().beginTransaction()
|
|
||||||
.setCustomAnimations(R.anim.step_next_in,
|
|
||||||
R.anim.step_previous_out, R.anim.step_previous_in,
|
|
||||||
R.anim.step_next_out)
|
|
||||||
.replace(R.id.fragmentContainer, f, f.getUniqueTag())
|
|
||||||
.addToBackStack(f.getUniqueTag())
|
|
||||||
.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSceneTransitionAnimation() {
|
|
||||||
if (Build.VERSION.SDK_INT < 21) return;
|
|
||||||
Transition slide = new Slide(Gravity.RIGHT);
|
|
||||||
slide.excludeTarget(android.R.id.statusBarBackground, true);
|
|
||||||
slide.excludeTarget(android.R.id.navigationBarBackground, true);
|
|
||||||
Window window = getWindow();
|
|
||||||
window.requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
|
|
||||||
window.setExitTransition(slide);
|
|
||||||
window.setEnterTransition(slide);
|
|
||||||
window.setTransitionBackgroundFadeDuration(getResources()
|
|
||||||
.getInteger(android.R.integer.config_longAnimTime));
|
|
||||||
window.setBackgroundDrawableResource(android.R.color.transparent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This should be called after the content view has been added in onCreate()
|
|
||||||
*
|
|
||||||
* @param ownLayout true if the custom toolbar brings its own layout
|
|
||||||
* @return the Toolbar object or null if content view did not contain one
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
protected Toolbar setUpCustomToolbar(boolean ownLayout) {
|
|
||||||
// Custom Toolbar
|
|
||||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
|
||||||
setSupportActionBar(toolbar);
|
|
||||||
ActionBar ab = getSupportActionBar();
|
|
||||||
if (ab != null) {
|
|
||||||
ab.setDisplayShowHomeEnabled(true);
|
|
||||||
ab.setDisplayHomeAsUpEnabled(true);
|
|
||||||
ab.setDisplayShowCustomEnabled(ownLayout);
|
|
||||||
ab.setDisplayShowTitleEnabled(!ownLayout);
|
|
||||||
}
|
|
||||||
return toolbar;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void signOut(final boolean removeFromRecentApps) {
|
protected void signOut(final boolean removeFromRecentApps) {
|
||||||
briarController.signOut(new UiResultHandler<Void>(this) {
|
briarController.signOut(new UiResultHandler<Void>(this) {
|
||||||
@Override
|
@Override
|
||||||
@@ -142,7 +83,7 @@ public abstract class BriarActivity extends BaseActivity {
|
|||||||
|
|
||||||
private void finishAndExit() {
|
private void finishAndExit() {
|
||||||
if (Build.VERSION.SDK_INT >= 21) finishAndRemoveTask();
|
if (Build.VERSION.SDK_INT >= 21) finishAndRemoveTask();
|
||||||
else supportFinishAfterTransition();
|
else finish();
|
||||||
LOG.info("Exiting");
|
LOG.info("Exiting");
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
@@ -157,7 +98,7 @@ public abstract class BriarActivity extends BaseActivity {
|
|||||||
runOnUiThreadUnlessDestroyed(new Runnable() {
|
runOnUiThreadUnlessDestroyed(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
supportFinishAfterTransition();
|
finish();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package org.briarproject.briar.android.activity;
|
||||||
|
|
||||||
|
import android.support.annotation.AnimRes;
|
||||||
|
import android.support.v4.app.FragmentTransaction;
|
||||||
|
import android.support.v7.app.AlertDialog;
|
||||||
|
|
||||||
|
import org.briarproject.briar.R;
|
||||||
|
import org.briarproject.briar.android.contact.ContactListFragment;
|
||||||
|
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||||
|
import org.briarproject.briar.android.navdrawer.NavDrawerActivity;
|
||||||
|
|
||||||
|
import static android.support.v4.app.FragmentManager.POP_BACK_STACK_INCLUSIVE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class should be extended by classes that wish to utilise fragments in
|
||||||
|
* Briar, it encapsulates all fragment related code.
|
||||||
|
*/
|
||||||
|
public abstract class BriarFragmentActivity extends BriarActivity {
|
||||||
|
|
||||||
|
protected void clearBackStack() {
|
||||||
|
getSupportFragmentManager().popBackStackImmediate(null,
|
||||||
|
POP_BACK_STACK_INCLUSIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
if (this instanceof NavDrawerActivity &&
|
||||||
|
getSupportFragmentManager().getBackStackEntryCount() == 0 &&
|
||||||
|
getSupportFragmentManager()
|
||||||
|
.findFragmentByTag(ContactListFragment.TAG) == null) {
|
||||||
|
/*
|
||||||
|
This Makes sure that the first fragment (ContactListFragment) the
|
||||||
|
user sees is the same as the last fragment the user sees before
|
||||||
|
exiting. This models the typical Google navigation behaviour such
|
||||||
|
as in Gmail/Inbox.
|
||||||
|
*/
|
||||||
|
startFragment(ContactListFragment.newInstance());
|
||||||
|
} else {
|
||||||
|
super.onBackPressed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onFragmentCreated(String tag) {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void startFragment(BaseFragment fragment) {
|
||||||
|
if (getSupportFragmentManager().getBackStackEntryCount() == 0)
|
||||||
|
startFragment(fragment, false);
|
||||||
|
else startFragment(fragment, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void showMessageDialog(int titleStringId, int msgStringId) {
|
||||||
|
// TODO replace with custom dialog fragment ?
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(this,
|
||||||
|
R.style.BriarDialogTheme);
|
||||||
|
builder.setTitle(titleStringId);
|
||||||
|
builder.setMessage(msgStringId);
|
||||||
|
builder.setPositiveButton(R.string.ok, null);
|
||||||
|
AlertDialog dialog = builder.create();
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startFragment(BaseFragment fragment,
|
||||||
|
boolean isAddedToBackStack) {
|
||||||
|
startFragment(fragment, 0, 0, isAddedToBackStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startFragment(BaseFragment fragment,
|
||||||
|
@AnimRes int inAnimation, @AnimRes int outAnimation,
|
||||||
|
boolean isAddedToBackStack) {
|
||||||
|
FragmentTransaction trans =
|
||||||
|
getSupportFragmentManager().beginTransaction();
|
||||||
|
if (inAnimation != 0 && outAnimation != 0) {
|
||||||
|
trans.setCustomAnimations(inAnimation, 0, 0, outAnimation);
|
||||||
|
}
|
||||||
|
trans.replace(R.id.content_fragment, fragment, fragment.getUniqueTag());
|
||||||
|
if (isAddedToBackStack) {
|
||||||
|
trans.addToBackStack(fragment.getUniqueTag());
|
||||||
|
}
|
||||||
|
trans.commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
package org.briarproject.briar.android.activity;
|
|
||||||
|
|
||||||
public interface RequestCodes {
|
|
||||||
|
|
||||||
int REQUEST_PASSWORD = 1;
|
|
||||||
int REQUEST_BLUETOOTH = 2;
|
|
||||||
int REQUEST_INTRODUCTION = 3;
|
|
||||||
int REQUEST_GROUP_INVITE = 4;
|
|
||||||
int REQUEST_SHARE_FORUM = 5;
|
|
||||||
int REQUEST_WRITE_BLOG_POST = 6;
|
|
||||||
int REQUEST_SHARE_BLOG = 7;
|
|
||||||
int REQUEST_RINGTONE = 8;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
package org.briarproject.briar.android.blog;
|
package org.briarproject.briar.android.blog;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Looper;
|
|
||||||
import android.support.annotation.CallSuper;
|
import android.support.annotation.CallSuper;
|
||||||
import android.support.annotation.UiThread;
|
import android.support.annotation.UiThread;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@@ -12,7 +10,6 @@ import android.widget.ProgressBar;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.fragment.BaseFragment;
|
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||||
|
|
||||||
@@ -22,7 +19,7 @@ import javax.annotation.Nullable;
|
|||||||
|
|
||||||
import static android.view.View.INVISIBLE;
|
import static android.view.View.INVISIBLE;
|
||||||
import static android.view.View.VISIBLE;
|
import static android.view.View.VISIBLE;
|
||||||
import static org.briarproject.briar.android.util.UiUtils.MIN_DATE_RESOLUTION;
|
import static org.briarproject.briar.android.util.UiUtils.MIN_RESOLUTION;
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@@ -34,9 +31,7 @@ abstract class BasePostFragment extends BaseFragment {
|
|||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(BasePostFragment.class.getName());
|
Logger.getLogger(BasePostFragment.class.getName());
|
||||||
|
|
||||||
private final Handler handler = new Handler(Looper.getMainLooper());
|
private View view;
|
||||||
|
|
||||||
protected MessageId postId;
|
|
||||||
private ProgressBar progressBar;
|
private ProgressBar progressBar;
|
||||||
private BlogPostViewHolder ui;
|
private BlogPostViewHolder ui;
|
||||||
private BlogPostItem post;
|
private BlogPostItem post;
|
||||||
@@ -48,12 +43,7 @@ abstract class BasePostFragment extends BaseFragment {
|
|||||||
public View onCreateView(LayoutInflater inflater,
|
public View onCreateView(LayoutInflater inflater,
|
||||||
@Nullable ViewGroup container,
|
@Nullable ViewGroup container,
|
||||||
@Nullable Bundle savedInstanceState) {
|
@Nullable Bundle savedInstanceState) {
|
||||||
// retrieve MessageId of blog post from arguments
|
view = inflater.inflate(R.layout.fragment_blog_post, container,
|
||||||
byte[] p = getArguments().getByteArray(POST_ID);
|
|
||||||
if (p == null) throw new IllegalStateException("No post ID in args");
|
|
||||||
postId = new MessageId(p);
|
|
||||||
|
|
||||||
View view = inflater.inflate(R.layout.fragment_blog_post, container,
|
|
||||||
false);
|
false);
|
||||||
progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
|
progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
|
||||||
progressBar.setVisibility(VISIBLE);
|
progressBar.setVisibility(VISIBLE);
|
||||||
@@ -86,19 +76,21 @@ abstract class BasePostFragment extends BaseFragment {
|
|||||||
refresher = new Runnable() {
|
refresher = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
if (ui == null) return;
|
||||||
LOG.info("Updating Content...");
|
LOG.info("Updating Content...");
|
||||||
|
|
||||||
ui.updateDate(post.getTimestamp());
|
ui.updateDate(post.getTimestamp());
|
||||||
handler.postDelayed(refresher, MIN_DATE_RESOLUTION);
|
view.postDelayed(refresher, MIN_RESOLUTION);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
LOG.info("Adding Handler Callback");
|
LOG.info("Adding Handler Callback");
|
||||||
handler.postDelayed(refresher, MIN_DATE_RESOLUTION);
|
view.postDelayed(refresher, MIN_RESOLUTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stopPeriodicUpdate() {
|
private void stopPeriodicUpdate() {
|
||||||
if (refresher != null) {
|
if (refresher != null && ui != null) {
|
||||||
LOG.info("Removing Handler Callback");
|
LOG.info("Removing Handler Callback");
|
||||||
handler.removeCallbacks(refresher);
|
view.removeCallbacks(refresher);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,59 +2,43 @@ package org.briarproject.briar.android.blog;
|
|||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.v7.widget.Toolbar;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||||
import org.briarproject.briar.android.activity.BriarActivity;
|
import org.briarproject.briar.android.activity.BriarActivity;
|
||||||
|
import org.briarproject.briar.android.blog.BlogPostAdapter.OnBlogPostClickListener;
|
||||||
import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener;
|
import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener;
|
||||||
import org.briarproject.briar.android.sharing.BlogSharingStatusActivity;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
public class BlogActivity extends BriarActivity implements
|
||||||
@ParametersNotNullByDefault
|
OnBlogPostClickListener, BaseFragmentListener {
|
||||||
public class BlogActivity extends BriarActivity
|
|
||||||
implements BaseFragmentListener {
|
static final int REQUEST_WRITE_POST = 1;
|
||||||
|
static final int REQUEST_SHARE = 2;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
BlogController blogController;
|
BlogController blogController;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable Bundle state) {
|
public void onCreate(Bundle state) {
|
||||||
super.onCreate(state);
|
super.onCreate(state);
|
||||||
|
|
||||||
// GroupId from Intent
|
// GroupId from Intent
|
||||||
Intent i = getIntent();
|
Intent i = getIntent();
|
||||||
byte[] b = i.getByteArrayExtra(GROUP_ID);
|
byte[] b = i.getByteArrayExtra(GROUP_ID);
|
||||||
if (b == null) throw new IllegalStateException("No group ID in intent");
|
if (b == null) throw new IllegalStateException("No group ID in intent");
|
||||||
final GroupId groupId = new GroupId(b);
|
GroupId groupId = new GroupId(b);
|
||||||
blogController.setGroupId(groupId);
|
blogController.setGroupId(groupId);
|
||||||
|
|
||||||
setContentView(R.layout.activity_fragment_container_toolbar);
|
setContentView(R.layout.activity_fragment_container);
|
||||||
Toolbar toolbar = setUpCustomToolbar(false);
|
|
||||||
|
|
||||||
// Open Sharing Status on Toolbar click
|
|
||||||
if (toolbar != null) {
|
|
||||||
toolbar.setOnClickListener(
|
|
||||||
new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
Intent i = new Intent(BlogActivity.this,
|
|
||||||
BlogSharingStatusActivity.class);
|
|
||||||
i.putExtra(GROUP_ID, groupId.getBytes());
|
|
||||||
startActivity(i);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state == null) {
|
if (state == null) {
|
||||||
showInitialFragment(BlogFragment.newInstance(groupId));
|
BlogFragment f = BlogFragment.newInstance(groupId);
|
||||||
|
getSupportFragmentManager().beginTransaction()
|
||||||
|
.replace(R.id.fragmentContainer, f, f.getUniqueTag())
|
||||||
|
.commit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,4 +47,16 @@ public class BlogActivity extends BriarActivity
|
|||||||
component.inject(this);
|
component.inject(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBlogPostClick(BlogPostItem post) {
|
||||||
|
BlogPostFragment f = BlogPostFragment.newInstance(post.getId());
|
||||||
|
getSupportFragmentManager().beginTransaction()
|
||||||
|
.replace(R.id.fragmentContainer, f, f.getUniqueTag())
|
||||||
|
.addToBackStack(f.getUniqueTag())
|
||||||
|
.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFragmentCreated(String tag) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
package org.briarproject.briar.android.blog;
|
package org.briarproject.briar.android.blog;
|
||||||
|
|
||||||
import android.support.annotation.UiThread;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.contact.ContactId;
|
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
@@ -16,8 +13,6 @@ public interface BlogController extends BaseController {
|
|||||||
|
|
||||||
void setGroupId(GroupId g);
|
void setGroupId(GroupId g);
|
||||||
|
|
||||||
void setBlogSharingListener(BlogSharingListener listener);
|
|
||||||
|
|
||||||
void loadBlogPosts(
|
void loadBlogPosts(
|
||||||
ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler);
|
ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler);
|
||||||
|
|
||||||
@@ -28,15 +23,4 @@ public interface BlogController extends BaseController {
|
|||||||
|
|
||||||
void deleteBlog(ResultExceptionHandler<Void, DbException> handler);
|
void deleteBlog(ResultExceptionHandler<Void, DbException> handler);
|
||||||
|
|
||||||
void loadSharingContacts(
|
|
||||||
ResultExceptionHandler<Collection<ContactId>, DbException> handler);
|
|
||||||
|
|
||||||
interface BlogSharingListener extends BlogListener {
|
|
||||||
@UiThread
|
|
||||||
void onBlogInvitationAccepted(ContactId c);
|
|
||||||
|
|
||||||
@UiThread
|
|
||||||
void onBlogLeft(ContactId c);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ package org.briarproject.briar.android.blog;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.contact.Contact;
|
|
||||||
import org.briarproject.bramble.api.contact.ContactId;
|
|
||||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.event.Event;
|
import org.briarproject.bramble.api.event.Event;
|
||||||
@@ -22,13 +20,8 @@ import org.briarproject.briar.android.controller.handler.ResultExceptionHandler;
|
|||||||
import org.briarproject.briar.api.android.AndroidNotificationManager;
|
import org.briarproject.briar.api.android.AndroidNotificationManager;
|
||||||
import org.briarproject.briar.api.blog.Blog;
|
import org.briarproject.briar.api.blog.Blog;
|
||||||
import org.briarproject.briar.api.blog.BlogManager;
|
import org.briarproject.briar.api.blog.BlogManager;
|
||||||
import org.briarproject.briar.api.blog.BlogSharingManager;
|
|
||||||
import org.briarproject.briar.api.blog.event.BlogInvitationResponseReceivedEvent;
|
|
||||||
import org.briarproject.briar.api.blog.event.BlogPostAddedEvent;
|
import org.briarproject.briar.api.blog.event.BlogPostAddedEvent;
|
||||||
import org.briarproject.briar.api.sharing.InvitationResponse;
|
|
||||||
import org.briarproject.briar.api.sharing.event.ContactLeftShareableEvent;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@@ -46,19 +39,15 @@ class BlogControllerImpl extends BaseControllerImpl
|
|||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(BlogControllerImpl.class.getName());
|
Logger.getLogger(BlogControllerImpl.class.getName());
|
||||||
|
|
||||||
private final BlogSharingManager blogSharingManager;
|
|
||||||
private volatile GroupId groupId = null;
|
private volatile GroupId groupId = null;
|
||||||
private volatile BlogSharingListener listener;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
BlogControllerImpl(@DatabaseExecutor Executor dbExecutor,
|
BlogControllerImpl(@DatabaseExecutor Executor dbExecutor,
|
||||||
LifecycleManager lifecycleManager, EventBus eventBus,
|
LifecycleManager lifecycleManager, EventBus eventBus,
|
||||||
AndroidNotificationManager notificationManager,
|
AndroidNotificationManager notificationManager,
|
||||||
IdentityManager identityManager, BlogManager blogManager,
|
IdentityManager identityManager, BlogManager blogManager) {
|
||||||
BlogSharingManager blogSharingManager) {
|
|
||||||
super(dbExecutor, lifecycleManager, eventBus, notificationManager,
|
super(dbExecutor, lifecycleManager, eventBus, notificationManager,
|
||||||
identityManager, blogManager);
|
identityManager, blogManager);
|
||||||
this.blogSharingManager = blogSharingManager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -87,12 +76,6 @@ class BlogControllerImpl extends BaseControllerImpl
|
|||||||
groupId = g;
|
groupId = g;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBlogSharingListener(BlogSharingListener listener) {
|
|
||||||
super.setBlogListener(listener);
|
|
||||||
this.listener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void eventOccurred(Event e) {
|
public void eventOccurred(Event e) {
|
||||||
if (groupId == null) throw new IllegalStateException();
|
if (groupId == null) throw new IllegalStateException();
|
||||||
@@ -102,20 +85,6 @@ class BlogControllerImpl extends BaseControllerImpl
|
|||||||
LOG.info("Blog post added");
|
LOG.info("Blog post added");
|
||||||
onBlogPostAdded(b.getHeader(), b.isLocal());
|
onBlogPostAdded(b.getHeader(), b.isLocal());
|
||||||
}
|
}
|
||||||
} else if (e instanceof BlogInvitationResponseReceivedEvent) {
|
|
||||||
BlogInvitationResponseReceivedEvent b =
|
|
||||||
(BlogInvitationResponseReceivedEvent) e;
|
|
||||||
InvitationResponse r = b.getResponse();
|
|
||||||
if (r.getGroupId().equals(groupId) && r.wasAccepted()) {
|
|
||||||
LOG.info("Blog invitation accepted");
|
|
||||||
onBlogInvitationAccepted(b.getContactId());
|
|
||||||
}
|
|
||||||
} else if (e instanceof ContactLeftShareableEvent) {
|
|
||||||
ContactLeftShareableEvent s = (ContactLeftShareableEvent) e;
|
|
||||||
if (s.getGroupId().equals(groupId)) {
|
|
||||||
LOG.info("Blog left by contact");
|
|
||||||
onBlogLeft(s.getContactId());
|
|
||||||
}
|
|
||||||
} else if (e instanceof GroupRemovedEvent) {
|
} else if (e instanceof GroupRemovedEvent) {
|
||||||
GroupRemovedEvent g = (GroupRemovedEvent) e;
|
GroupRemovedEvent g = (GroupRemovedEvent) e;
|
||||||
if (g.getGroup().getId().equals(groupId)) {
|
if (g.getGroup().getId().equals(groupId)) {
|
||||||
@@ -125,24 +94,6 @@ class BlogControllerImpl extends BaseControllerImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onBlogInvitationAccepted(final ContactId c) {
|
|
||||||
listener.runOnUiThreadUnlessDestroyed(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
listener.onBlogInvitationAccepted(c);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onBlogLeft(final ContactId c) {
|
|
||||||
listener.runOnUiThreadUnlessDestroyed(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
listener.onBlogLeft(c);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadBlogPosts(
|
public void loadBlogPosts(
|
||||||
final ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) {
|
final ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) {
|
||||||
@@ -208,27 +159,4 @@ class BlogControllerImpl extends BaseControllerImpl
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadSharingContacts(
|
|
||||||
final ResultExceptionHandler<Collection<ContactId>, DbException> handler) {
|
|
||||||
if (groupId == null) throw new IllegalStateException();
|
|
||||||
runOnDbThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
Collection<Contact> contacts =
|
|
||||||
blogSharingManager.getSharedWith(groupId);
|
|
||||||
Collection<ContactId> contactIds =
|
|
||||||
new ArrayList<>(contacts.size());
|
|
||||||
for (Contact c : contacts) contactIds.add(c.getId());
|
|
||||||
handler.onResult(contactIds);
|
|
||||||
} catch (DbException e) {
|
|
||||||
if (LOG.isLoggable(WARNING))
|
|
||||||
LOG.log(WARNING, e.toString(), e);
|
|
||||||
handler.onException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import android.content.Intent;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.UiThread;
|
import android.support.annotation.UiThread;
|
||||||
import android.support.design.widget.Snackbar;
|
import android.support.design.widget.Snackbar;
|
||||||
|
import android.support.v4.app.ActivityOptionsCompat;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.support.v7.app.ActionBar;
|
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@@ -17,7 +17,6 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.contact.ContactId;
|
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
@@ -25,10 +24,8 @@ import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
|||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||||
import org.briarproject.briar.android.activity.BriarActivity;
|
import org.briarproject.briar.android.blog.BaseController.BlogListener;
|
||||||
import org.briarproject.briar.android.blog.BlogController.BlogSharingListener;
|
|
||||||
import org.briarproject.briar.android.blog.BlogPostAdapter.OnBlogPostClickListener;
|
import org.briarproject.briar.android.blog.BlogPostAdapter.OnBlogPostClickListener;
|
||||||
import org.briarproject.briar.android.controller.SharingController;
|
|
||||||
import org.briarproject.briar.android.controller.handler.UiResultExceptionHandler;
|
import org.briarproject.briar.android.controller.handler.UiResultExceptionHandler;
|
||||||
import org.briarproject.briar.android.fragment.BaseFragment;
|
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||||
import org.briarproject.briar.android.sharing.BlogSharingStatusActivity;
|
import org.briarproject.briar.android.sharing.BlogSharingStatusActivity;
|
||||||
@@ -44,25 +41,22 @@ import javax.inject.Inject;
|
|||||||
import static android.app.Activity.RESULT_OK;
|
import static android.app.Activity.RESULT_OK;
|
||||||
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
|
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
|
||||||
import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
|
import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
|
||||||
|
import static android.support.v4.app.ActivityOptionsCompat.makeCustomAnimation;
|
||||||
import static android.widget.Toast.LENGTH_SHORT;
|
import static android.widget.Toast.LENGTH_SHORT;
|
||||||
import static org.briarproject.briar.android.activity.BriarActivity.GROUP_ID;
|
import static org.briarproject.briar.android.activity.BriarActivity.GROUP_ID;
|
||||||
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_SHARE_BLOG;
|
import static org.briarproject.briar.android.blog.BlogActivity.REQUEST_SHARE;
|
||||||
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_WRITE_BLOG_POST;
|
import static org.briarproject.briar.android.blog.BlogActivity.REQUEST_WRITE_POST;
|
||||||
import static org.briarproject.briar.android.controller.SharingController.SharingListener;
|
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
public class BlogFragment extends BaseFragment
|
public class BlogFragment extends BaseFragment implements
|
||||||
implements BlogSharingListener, SharingListener,
|
BlogListener {
|
||||||
OnBlogPostClickListener {
|
|
||||||
|
|
||||||
private final static String TAG = BlogFragment.class.getName();
|
private final static String TAG = BlogFragment.class.getName();
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
BlogController blogController;
|
BlogController blogController;
|
||||||
@Inject
|
|
||||||
SharingController sharingController;
|
|
||||||
|
|
||||||
private GroupId groupId;
|
private GroupId groupId;
|
||||||
private BlogPostAdapter adapter;
|
private BlogPostAdapter adapter;
|
||||||
@@ -93,7 +87,8 @@ public class BlogFragment extends BaseFragment
|
|||||||
|
|
||||||
View v = inflater.inflate(R.layout.fragment_blog, container, false);
|
View v = inflater.inflate(R.layout.fragment_blog, container, false);
|
||||||
|
|
||||||
adapter = new BlogPostAdapter(getActivity(), this);
|
adapter = new BlogPostAdapter(getActivity(),
|
||||||
|
(OnBlogPostClickListener) getActivity());
|
||||||
list = (BriarRecyclerView) v.findViewById(R.id.postList);
|
list = (BriarRecyclerView) v.findViewById(R.id.postList);
|
||||||
list.setLayoutManager(new LinearLayoutManager(getActivity()));
|
list.setLayoutManager(new LinearLayoutManager(getActivity()));
|
||||||
list.setAdapter(adapter);
|
list.setAdapter(adapter);
|
||||||
@@ -106,16 +101,13 @@ public class BlogFragment extends BaseFragment
|
|||||||
@Override
|
@Override
|
||||||
public void injectFragment(ActivityComponent component) {
|
public void injectFragment(ActivityComponent component) {
|
||||||
component.inject(this);
|
component.inject(this);
|
||||||
blogController.setBlogSharingListener(this);
|
blogController.setBlogListener(this);
|
||||||
sharingController.setSharingListener(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
sharingController.onStart();
|
|
||||||
loadBlog();
|
loadBlog();
|
||||||
loadSharedContacts();
|
|
||||||
loadBlogPosts(false);
|
loadBlogPosts(false);
|
||||||
list.startPeriodicUpdate();
|
list.startPeriodicUpdate();
|
||||||
}
|
}
|
||||||
@@ -123,7 +115,6 @@ public class BlogFragment extends BaseFragment
|
|||||||
@Override
|
@Override
|
||||||
public void onStop() {
|
public void onStop() {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
sharingController.onStop();
|
|
||||||
list.stopPeriodicUpdate();
|
list.stopPeriodicUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,25 +131,30 @@ public class BlogFragment extends BaseFragment
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||||
|
ActivityOptionsCompat options =
|
||||||
|
makeCustomAnimation(getActivity(),
|
||||||
|
android.R.anim.slide_in_left,
|
||||||
|
android.R.anim.slide_out_right);
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.action_write_blog_post:
|
case R.id.action_write_blog_post:
|
||||||
Intent i = new Intent(getActivity(),
|
Intent i = new Intent(getActivity(),
|
||||||
WriteBlogPostActivity.class);
|
WriteBlogPostActivity.class);
|
||||||
i.putExtra(GROUP_ID, groupId.getBytes());
|
i.putExtra(GROUP_ID, groupId.getBytes());
|
||||||
startActivityForResult(i, REQUEST_WRITE_BLOG_POST);
|
startActivityForResult(i, REQUEST_WRITE_POST,
|
||||||
|
options.toBundle());
|
||||||
return true;
|
return true;
|
||||||
case R.id.action_blog_share:
|
case R.id.action_blog_share:
|
||||||
Intent i2 = new Intent(getActivity(), ShareBlogActivity.class);
|
Intent i2 = new Intent(getActivity(), ShareBlogActivity.class);
|
||||||
i2.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP);
|
i2.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP);
|
||||||
i2.putExtra(GROUP_ID, groupId.getBytes());
|
i2.putExtra(GROUP_ID, groupId.getBytes());
|
||||||
startActivityForResult(i2, REQUEST_SHARE_BLOG);
|
startActivityForResult(i2, REQUEST_SHARE, options.toBundle());
|
||||||
return true;
|
return true;
|
||||||
case R.id.action_blog_sharing_status:
|
case R.id.action_blog_sharing_status:
|
||||||
Intent i3 = new Intent(getActivity(),
|
Intent i3 = new Intent(getActivity(),
|
||||||
BlogSharingStatusActivity.class);
|
BlogSharingStatusActivity.class);
|
||||||
i3.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP);
|
i3.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP);
|
||||||
i3.putExtra(GROUP_ID, groupId.getBytes());
|
i3.putExtra(GROUP_ID, groupId.getBytes());
|
||||||
startActivity(i3);
|
startActivity(i3, options.toBundle());
|
||||||
return true;
|
return true;
|
||||||
case R.id.action_blog_delete:
|
case R.id.action_blog_delete:
|
||||||
showDeleteDialog();
|
showDeleteDialog();
|
||||||
@@ -172,10 +168,10 @@ public class BlogFragment extends BaseFragment
|
|||||||
public void onActivityResult(int request, int result, Intent data) {
|
public void onActivityResult(int request, int result, Intent data) {
|
||||||
super.onActivityResult(request, result, data);
|
super.onActivityResult(request, result, data);
|
||||||
|
|
||||||
if (request == REQUEST_WRITE_BLOG_POST && result == RESULT_OK) {
|
if (request == REQUEST_WRITE_POST && result == RESULT_OK) {
|
||||||
displaySnackbar(R.string.blogs_blog_post_created, true);
|
displaySnackbar(R.string.blogs_blog_post_created, true);
|
||||||
loadBlogPosts(true);
|
loadBlogPosts(true);
|
||||||
} else if (request == REQUEST_SHARE_BLOG && result == RESULT_OK) {
|
} else if (request == REQUEST_SHARE && result == RESULT_OK) {
|
||||||
displaySnackbar(R.string.blogs_sharing_snackbar, false);
|
displaySnackbar(R.string.blogs_sharing_snackbar, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -205,18 +201,13 @@ public class BlogFragment extends BaseFragment
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExceptionUi(DbException exception) {
|
public void onExceptionUi(DbException exception) {
|
||||||
handleDbException(exception);
|
// TODO: Decide how to handle errors in the UI
|
||||||
|
finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBlogPostClick(BlogPostItem post) {
|
|
||||||
BlogPostFragment f = BlogPostFragment.newInstance(post.getId());
|
|
||||||
showNextFragment(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadBlogPosts(final boolean reload) {
|
private void loadBlogPosts(final boolean reload) {
|
||||||
blogController.loadBlogPosts(
|
blogController.loadBlogPosts(
|
||||||
new UiResultExceptionHandler<Collection<BlogPostItem>, DbException>(
|
new UiResultExceptionHandler<Collection<BlogPostItem>, DbException>(
|
||||||
@@ -233,7 +224,8 @@ public class BlogFragment extends BaseFragment
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExceptionUi(DbException exception) {
|
public void onExceptionUi(DbException exception) {
|
||||||
handleDbException(exception);
|
// TODO: Decide how to handle errors in the UI
|
||||||
|
finish();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -252,7 +244,8 @@ public class BlogFragment extends BaseFragment
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExceptionUi(DbException exception) {
|
public void onExceptionUi(DbException exception) {
|
||||||
handleDbException(exception);
|
// TODO: Decide how to handle errors in the UI
|
||||||
|
finish();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -262,51 +255,6 @@ public class BlogFragment extends BaseFragment
|
|||||||
getActivity().setTitle(title);
|
getActivity().setTitle(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadSharedContacts() {
|
|
||||||
blogController.loadSharingContacts(
|
|
||||||
new UiResultExceptionHandler<Collection<ContactId>, DbException>(this) {
|
|
||||||
@Override
|
|
||||||
public void onResultUi(Collection<ContactId> contacts) {
|
|
||||||
sharingController.addAll(contacts);
|
|
||||||
int online = sharingController.getOnlineCount();
|
|
||||||
setToolbarSubTitle(contacts.size(), online);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onExceptionUi(DbException exception) {
|
|
||||||
handleDbException(exception);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBlogInvitationAccepted(ContactId c) {
|
|
||||||
sharingController.add(c);
|
|
||||||
setToolbarSubTitle(sharingController.getTotalCount(),
|
|
||||||
sharingController.getOnlineCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBlogLeft(ContactId c) {
|
|
||||||
sharingController.remove(c);
|
|
||||||
setToolbarSubTitle(sharingController.getTotalCount(),
|
|
||||||
sharingController.getOnlineCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSharingInfoUpdated(int total, int online) {
|
|
||||||
setToolbarSubTitle(total, online);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setToolbarSubTitle(int total, int online) {
|
|
||||||
ActionBar actionBar =
|
|
||||||
((BriarActivity) getActivity()).getSupportActionBar();
|
|
||||||
if (actionBar != null) {
|
|
||||||
actionBar.setSubtitle(
|
|
||||||
getString(R.string.shared_with, total, online));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showWriteButton() {
|
private void showWriteButton() {
|
||||||
isMyBlog = true;
|
isMyBlog = true;
|
||||||
if (writeButton != null)
|
if (writeButton != null)
|
||||||
@@ -369,7 +317,8 @@ public class BlogFragment extends BaseFragment
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExceptionUi(DbException exception) {
|
public void onExceptionUi(DbException exception) {
|
||||||
handleDbException(exception);
|
// TODO: Decide how to handle errors in the UI
|
||||||
|
finish();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -378,5 +327,4 @@ public class BlogFragment extends BaseFragment
|
|||||||
public void onBlogRemoved() {
|
public void onBlogRemoved() {
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ package org.briarproject.briar.android.blog;
|
|||||||
|
|
||||||
import org.briarproject.briar.android.activity.ActivityScope;
|
import org.briarproject.briar.android.activity.ActivityScope;
|
||||||
import org.briarproject.briar.android.activity.BaseActivity;
|
import org.briarproject.briar.android.activity.BaseActivity;
|
||||||
import org.briarproject.briar.android.controller.SharingController;
|
|
||||||
import org.briarproject.briar.android.controller.SharingControllerImpl;
|
|
||||||
|
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
import dagger.Provides;
|
import dagger.Provides;
|
||||||
@@ -24,12 +22,4 @@ public class BlogModule {
|
|||||||
FeedController provideFeedController(FeedControllerImpl feedController) {
|
FeedController provideFeedController(FeedControllerImpl feedController) {
|
||||||
return feedController;
|
return feedController;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ActivityScope
|
|
||||||
@Provides
|
|
||||||
SharingController provideSharingController(
|
|
||||||
SharingControllerImpl sharingController) {
|
|
||||||
return sharingController;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ package org.briarproject.briar.android.blog;
|
|||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.UiThread;
|
import android.support.annotation.UiThread;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
@@ -10,6 +13,7 @@ import org.briarproject.bramble.api.sync.MessageId;
|
|||||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||||
import org.briarproject.briar.android.controller.handler.UiResultExceptionHandler;
|
import org.briarproject.briar.android.controller.handler.UiResultExceptionHandler;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
@@ -19,6 +23,8 @@ public class BlogPostFragment extends BasePostFragment {
|
|||||||
|
|
||||||
private static final String TAG = BlogPostFragment.class.getName();
|
private static final String TAG = BlogPostFragment.class.getName();
|
||||||
|
|
||||||
|
private MessageId postId;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
BlogController blogController;
|
BlogController blogController;
|
||||||
|
|
||||||
@@ -32,6 +38,20 @@ public class BlogPostFragment extends BasePostFragment {
|
|||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater,
|
||||||
|
@Nullable ViewGroup container,
|
||||||
|
@Nullable Bundle savedInstanceState) {
|
||||||
|
|
||||||
|
Bundle args = getArguments();
|
||||||
|
byte[] p = args.getByteArray(POST_ID);
|
||||||
|
if (p == null) throw new IllegalStateException("No post ID in args");
|
||||||
|
postId = new MessageId(p);
|
||||||
|
|
||||||
|
return super.onCreateView(inflater, container, savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUniqueTag() {
|
public String getUniqueTag() {
|
||||||
return TAG;
|
return TAG;
|
||||||
@@ -55,7 +75,8 @@ public class BlogPostFragment extends BasePostFragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExceptionUi(DbException exception) {
|
public void onExceptionUi(DbException exception) {
|
||||||
handleDbException(exception);
|
// TODO: Decide how to handle errors in the UI
|
||||||
|
finish();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,14 +137,15 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
|
|||||||
i.putExtra(GROUP_ID, item.getGroupId().getBytes());
|
i.putExtra(GROUP_ID, item.getGroupId().getBytes());
|
||||||
i.putExtra(POST_ID, item.getId().getBytes());
|
i.putExtra(POST_ID, item.getId().getBytes());
|
||||||
|
|
||||||
|
// work-around for android bug #224270
|
||||||
if (Build.VERSION.SDK_INT >= 23) {
|
if (Build.VERSION.SDK_INT >= 23) {
|
||||||
ActivityOptionsCompat options =
|
ActivityOptionsCompat options =
|
||||||
makeSceneTransitionAnimation((Activity) ctx, layout,
|
makeSceneTransitionAnimation((Activity) ctx, layout,
|
||||||
getTransitionName(item.getId()));
|
getTransitionName(item.getId()));
|
||||||
ActivityCompat.startActivity((Activity) ctx, i,
|
ActivityCompat
|
||||||
options.toBundle());
|
.startActivity((Activity) ctx, i,
|
||||||
|
options.toBundle());
|
||||||
} else {
|
} else {
|
||||||
// work-around for android bug #224270
|
|
||||||
ctx.startActivity(i);
|
ctx.startActivity(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -166,7 +167,6 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
|
|||||||
reblogger.setDate(item.getTimestamp());
|
reblogger.setDate(item.getTimestamp());
|
||||||
reblogger.setBlogLink(item.getGroupId());
|
reblogger.setBlogLink(item.getGroupId());
|
||||||
reblogger.setVisibility(VISIBLE);
|
reblogger.setVisibility(VISIBLE);
|
||||||
reblogger.setPersona(AuthorView.REBLOGGER);
|
|
||||||
|
|
||||||
author.setPersona(AuthorView.COMMENTER);
|
author.setPersona(AuthorView.COMMENTER);
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import android.content.Intent;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.UiThread;
|
import android.support.annotation.UiThread;
|
||||||
import android.support.design.widget.Snackbar;
|
import android.support.design.widget.Snackbar;
|
||||||
|
import android.support.v4.app.ActivityOptionsCompat;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@@ -35,8 +36,9 @@ import javax.inject.Inject;
|
|||||||
|
|
||||||
import static android.app.Activity.RESULT_OK;
|
import static android.app.Activity.RESULT_OK;
|
||||||
import static android.support.design.widget.Snackbar.LENGTH_LONG;
|
import static android.support.design.widget.Snackbar.LENGTH_LONG;
|
||||||
|
import static android.support.v4.app.ActivityOptionsCompat.makeCustomAnimation;
|
||||||
import static org.briarproject.briar.android.activity.BriarActivity.GROUP_ID;
|
import static org.briarproject.briar.android.activity.BriarActivity.GROUP_ID;
|
||||||
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_WRITE_BLOG_POST;
|
import static org.briarproject.briar.android.blog.BlogActivity.REQUEST_WRITE_POST;
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@@ -70,8 +72,6 @@ public class FeedFragment extends BaseFragment implements
|
|||||||
@Nullable ViewGroup container,
|
@Nullable ViewGroup container,
|
||||||
@Nullable Bundle savedInstanceState) {
|
@Nullable Bundle savedInstanceState) {
|
||||||
|
|
||||||
getActivity().setTitle(R.string.blogs_button);
|
|
||||||
|
|
||||||
View v = inflater.inflate(R.layout.fragment_blog, container, false);
|
View v = inflater.inflate(R.layout.fragment_blog, container, false);
|
||||||
|
|
||||||
adapter = new BlogPostAdapter(getActivity(), this);
|
adapter = new BlogPostAdapter(getActivity(), this);
|
||||||
@@ -96,7 +96,7 @@ public class FeedFragment extends BaseFragment implements
|
|||||||
super.onActivityResult(requestCode, resultCode, data);
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
|
||||||
// The BlogPostAddedEvent arrives when the controller is not listening
|
// The BlogPostAddedEvent arrives when the controller is not listening
|
||||||
if (requestCode == REQUEST_WRITE_BLOG_POST && resultCode == RESULT_OK) {
|
if (requestCode == REQUEST_WRITE_POST && resultCode == RESULT_OK) {
|
||||||
showSnackBar(R.string.blogs_blog_post_created);
|
showSnackBar(R.string.blogs_blog_post_created);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,7 +105,6 @@ public class FeedFragment extends BaseFragment implements
|
|||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
feedController.onStart();
|
feedController.onStart();
|
||||||
list.startPeriodicUpdate();
|
|
||||||
loadPersonalBlog();
|
loadPersonalBlog();
|
||||||
loadBlogPosts(false);
|
loadBlogPosts(false);
|
||||||
}
|
}
|
||||||
@@ -130,7 +129,7 @@ public class FeedFragment extends BaseFragment implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExceptionUi(DbException exception) {
|
public void onExceptionUi(DbException exception) {
|
||||||
handleDbException(exception);
|
// TODO: Decide how to handle errors in the UI
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -154,10 +153,11 @@ public class FeedFragment extends BaseFragment implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExceptionUi(DbException exception) {
|
public void onExceptionUi(DbException e) {
|
||||||
handleDbException(exception);
|
// TODO: Decide how to handle errors in the UI
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
list.startPeriodicUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -169,24 +169,28 @@ public class FeedFragment extends BaseFragment implements
|
|||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||||
if (personalBlog == null) return false;
|
if (personalBlog == null) return false;
|
||||||
|
ActivityOptionsCompat options =
|
||||||
|
makeCustomAnimation(getActivity(), android.R.anim.slide_in_left,
|
||||||
|
android.R.anim.slide_out_right);
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.action_write_blog_post:
|
case R.id.action_write_blog_post:
|
||||||
Intent i1 =
|
Intent i1 =
|
||||||
new Intent(getActivity(), WriteBlogPostActivity.class);
|
new Intent(getActivity(), WriteBlogPostActivity.class);
|
||||||
i1.putExtra(GROUP_ID, personalBlog.getId().getBytes());
|
i1.putExtra(GROUP_ID, personalBlog.getId().getBytes());
|
||||||
startActivityForResult(i1, REQUEST_WRITE_BLOG_POST);
|
startActivityForResult(i1, REQUEST_WRITE_POST,
|
||||||
|
options.toBundle());
|
||||||
return true;
|
return true;
|
||||||
case R.id.action_rss_feeds_import:
|
case R.id.action_rss_feeds_import:
|
||||||
Intent i2 =
|
Intent i2 =
|
||||||
new Intent(getActivity(), RssFeedImportActivity.class);
|
new Intent(getActivity(), RssFeedImportActivity.class);
|
||||||
i2.putExtra(GROUP_ID, personalBlog.getId().getBytes());
|
i2.putExtra(GROUP_ID, personalBlog.getId().getBytes());
|
||||||
startActivity(i2);
|
startActivity(i2, options.toBundle());
|
||||||
return true;
|
return true;
|
||||||
case R.id.action_rss_feeds_manage:
|
case R.id.action_rss_feeds_manage:
|
||||||
Intent i3 =
|
Intent i3 =
|
||||||
new Intent(getActivity(), RssFeedManageActivity.class);
|
new Intent(getActivity(), RssFeedManageActivity.class);
|
||||||
i3.putExtra(GROUP_ID, personalBlog.getId().getBytes());
|
i3.putExtra(GROUP_ID, personalBlog.getId().getBytes());
|
||||||
startActivity(i3);
|
startActivity(i3, options.toBundle());
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
@@ -211,7 +215,7 @@ public class FeedFragment extends BaseFragment implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExceptionUi(DbException exception) {
|
public void onExceptionUi(DbException exception) {
|
||||||
handleDbException(exception);
|
// TODO: Decide how to handle errors in the UI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -221,7 +225,10 @@ public class FeedFragment extends BaseFragment implements
|
|||||||
public void onBlogPostClick(BlogPostItem post) {
|
public void onBlogPostClick(BlogPostItem post) {
|
||||||
FeedPostFragment f =
|
FeedPostFragment f =
|
||||||
FeedPostFragment.newInstance(post.getGroupId(), post.getId());
|
FeedPostFragment.newInstance(post.getGroupId(), post.getId());
|
||||||
showNextFragment(f);
|
getActivity().getSupportFragmentManager().beginTransaction()
|
||||||
|
.replace(R.id.content_fragment, f, f.getUniqueTag())
|
||||||
|
.addToBackStack(f.getUniqueTag())
|
||||||
|
.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -262,5 +269,4 @@ public class FeedFragment extends BaseFragment implements
|
|||||||
public void onBlogRemoved() {
|
public void onBlogRemoved() {
|
||||||
loadBlogPosts(true);
|
loadBlogPosts(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ public class FeedPostFragment extends BasePostFragment {
|
|||||||
|
|
||||||
private static final String TAG = FeedPostFragment.class.getName();
|
private static final String TAG = FeedPostFragment.class.getName();
|
||||||
|
|
||||||
|
private MessageId postId;
|
||||||
private GroupId blogId;
|
private GroupId blogId;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@@ -53,6 +54,10 @@ public class FeedPostFragment extends BasePostFragment {
|
|||||||
if (b == null) throw new IllegalStateException("No group ID in args");
|
if (b == null) throw new IllegalStateException("No group ID in args");
|
||||||
blogId = new GroupId(b);
|
blogId = new GroupId(b);
|
||||||
|
|
||||||
|
byte[] p = args.getByteArray(POST_ID);
|
||||||
|
if (p == null) throw new IllegalStateException("No post ID in args");
|
||||||
|
postId = new MessageId(p);
|
||||||
|
|
||||||
return super.onCreateView(inflater, container, savedInstanceState);
|
return super.onCreateView(inflater, container, savedInstanceState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +84,7 @@ public class FeedPostFragment extends BasePostFragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExceptionUi(DbException exception) {
|
public void onExceptionUi(DbException exception) {
|
||||||
handleDbException(exception);
|
// TODO: Decide how to handle errors in the UI
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
package org.briarproject.briar.android.blog;
|
package org.briarproject.briar.android.blog;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.transition.Fade;
|
||||||
|
import android.transition.Transition;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
@@ -19,7 +23,10 @@ public class ReblogActivity extends BriarActivity implements
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setSceneTransitionAnimation();
|
|
||||||
|
if (Build.VERSION.SDK_INT >= 21) {
|
||||||
|
setTransition();
|
||||||
|
}
|
||||||
|
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
byte[] groupId = intent.getByteArrayExtra(GROUP_ID);
|
byte[] groupId = intent.getByteArrayExtra(GROUP_ID);
|
||||||
@@ -34,7 +41,10 @@ public class ReblogActivity extends BriarActivity implements
|
|||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
ReblogFragment f = ReblogFragment
|
ReblogFragment f = ReblogFragment
|
||||||
.newInstance(new GroupId(groupId), new MessageId(postId));
|
.newInstance(new GroupId(groupId), new MessageId(postId));
|
||||||
showInitialFragment(f);
|
getSupportFragmentManager()
|
||||||
|
.beginTransaction()
|
||||||
|
.add(R.id.fragmentContainer, f)
|
||||||
|
.commit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,4 +64,18 @@ public class ReblogActivity extends BriarActivity implements
|
|||||||
component.inject(this);
|
component.inject(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFragmentCreated(String tag) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(21)
|
||||||
|
private void setTransition() {
|
||||||
|
Transition fade = new Fade();
|
||||||
|
fade.excludeTarget(android.R.id.statusBarBackground, true);
|
||||||
|
fade.excludeTarget(R.id.action_bar_container, true);
|
||||||
|
fade.excludeTarget(android.R.id.navigationBarBackground, true);
|
||||||
|
getWindow().setExitTransition(fade);
|
||||||
|
getWindow().setEnterTransition(fade);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,8 @@ public class ReblogFragment extends BaseFragment implements TextInputListener {
|
|||||||
blogId = new GroupId(args.getByteArray(GROUP_ID));
|
blogId = new GroupId(args.getByteArray(GROUP_ID));
|
||||||
postId = new MessageId(args.getByteArray(POST_ID));
|
postId = new MessageId(args.getByteArray(POST_ID));
|
||||||
|
|
||||||
View v = inflater.inflate(R.layout.fragment_reblog, container, false);
|
View v = inflater.inflate(R.layout.fragment_reblog, container,
|
||||||
|
false);
|
||||||
ui = new ViewHolder(v);
|
ui = new ViewHolder(v);
|
||||||
ui.post.setTransitionName(postId);
|
ui.post.setTransitionName(postId);
|
||||||
ui.input.setSendButtonEnabled(false);
|
ui.input.setSendButtonEnabled(false);
|
||||||
@@ -99,7 +100,8 @@ public class ReblogFragment extends BaseFragment implements TextInputListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExceptionUi(DbException exception) {
|
public void onExceptionUi(DbException exception) {
|
||||||
handleDbException(exception);
|
// TODO
|
||||||
|
finish();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -129,7 +131,8 @@ public class ReblogFragment extends BaseFragment implements TextInputListener {
|
|||||||
new UiExceptionHandler<DbException>(this) {
|
new UiExceptionHandler<DbException>(this) {
|
||||||
@Override
|
@Override
|
||||||
public void onExceptionUi(DbException exception) {
|
public void onExceptionUi(DbException exception) {
|
||||||
handleDbException(exception);
|
// TODO proper error handling
|
||||||
|
// do nothing, this fragment is gone already
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
finish();
|
finish();
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package org.briarproject.briar.android.blog;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.design.widget.Snackbar;
|
import android.support.design.widget.Snackbar;
|
||||||
|
import android.support.v4.app.ActivityCompat;
|
||||||
|
import android.support.v4.app.ActivityOptionsCompat;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
@@ -24,6 +26,7 @@ import java.util.logging.Logger;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static android.support.design.widget.Snackbar.LENGTH_LONG;
|
import static android.support.design.widget.Snackbar.LENGTH_LONG;
|
||||||
|
import static android.support.v4.app.ActivityOptionsCompat.makeCustomAnimation;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
|
|
||||||
public class RssFeedManageActivity extends BriarActivity
|
public class RssFeedManageActivity extends BriarActivity
|
||||||
@@ -86,9 +89,13 @@ public class RssFeedManageActivity extends BriarActivity
|
|||||||
onBackPressed();
|
onBackPressed();
|
||||||
return true;
|
return true;
|
||||||
case R.id.action_rss_feeds_import:
|
case R.id.action_rss_feeds_import:
|
||||||
Intent i = new Intent(this, RssFeedImportActivity.class);
|
Intent i =
|
||||||
|
new Intent(this, RssFeedImportActivity.class);
|
||||||
i.putExtra(GROUP_ID, groupId.getBytes());
|
i.putExtra(GROUP_ID, groupId.getBytes());
|
||||||
startActivity(i);
|
ActivityOptionsCompat options =
|
||||||
|
makeCustomAnimation(this, android.R.anim.slide_in_left,
|
||||||
|
android.R.anim.slide_out_right);
|
||||||
|
ActivityCompat.startActivity(this, i, options.toBundle());
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
|
|||||||
@@ -10,27 +10,13 @@ import javax.annotation.concurrent.NotThreadSafe;
|
|||||||
public class ContactItem {
|
public class ContactItem {
|
||||||
|
|
||||||
private final Contact contact;
|
private final Contact contact;
|
||||||
private boolean connected;
|
|
||||||
|
|
||||||
public ContactItem(Contact contact) {
|
public ContactItem(Contact contact) {
|
||||||
this(contact, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContactItem(Contact contact, boolean connected) {
|
|
||||||
this.contact = contact;
|
this.contact = contact;
|
||||||
this.connected = connected;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Contact getContact() {
|
public Contact getContact() {
|
||||||
return contact;
|
return contact;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isConnected() {
|
|
||||||
return connected;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setConnected(boolean connected) {
|
|
||||||
this.connected = connected;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package org.briarproject.briar.android.contact;
|
package org.briarproject.briar.android.contact;
|
||||||
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.annotation.UiThread;
|
import android.support.annotation.UiThread;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -13,6 +12,8 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.contact.BaseContactListAdapter.OnContactClickListener;
|
import org.briarproject.briar.android.contact.BaseContactListAdapter.OnContactClickListener;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import im.delight.android.identicons.IdenticonDrawable;
|
import im.delight.android.identicons.IdenticonDrawable;
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
@@ -23,8 +24,6 @@ public class ContactItemViewHolder<I extends ContactItem>
|
|||||||
protected final ViewGroup layout;
|
protected final ViewGroup layout;
|
||||||
protected final ImageView avatar;
|
protected final ImageView avatar;
|
||||||
protected final TextView name;
|
protected final TextView name;
|
||||||
@Nullable
|
|
||||||
protected final ImageView bulb;
|
|
||||||
|
|
||||||
public ContactItemViewHolder(View v) {
|
public ContactItemViewHolder(View v) {
|
||||||
super(v);
|
super(v);
|
||||||
@@ -32,8 +31,6 @@ public class ContactItemViewHolder<I extends ContactItem>
|
|||||||
layout = (ViewGroup) v;
|
layout = (ViewGroup) v;
|
||||||
avatar = (ImageView) v.findViewById(R.id.avatarView);
|
avatar = (ImageView) v.findViewById(R.id.avatarView);
|
||||||
name = (TextView) v.findViewById(R.id.nameView);
|
name = (TextView) v.findViewById(R.id.nameView);
|
||||||
// this can be null as not all layouts that use this ViewHolder have it
|
|
||||||
bulb = (ImageView) v.findViewById(R.id.bulbView);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void bind(final I item,
|
protected void bind(final I item,
|
||||||
@@ -44,15 +41,6 @@ public class ContactItemViewHolder<I extends ContactItem>
|
|||||||
String contactName = author.getName();
|
String contactName = author.getName();
|
||||||
name.setText(contactName);
|
name.setText(contactName);
|
||||||
|
|
||||||
if (bulb != null) {
|
|
||||||
// online/offline
|
|
||||||
if (item.isConnected()) {
|
|
||||||
bulb.setImageResource(R.drawable.contact_connected);
|
|
||||||
} else {
|
|
||||||
bulb.setImageResource(R.drawable.contact_disconnected);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
layout.setOnClickListener(new View.OnClickListener() {
|
layout.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
|
|||||||
@@ -109,8 +109,6 @@ public class ContactListFragment extends BaseFragment implements EventListener {
|
|||||||
@Nullable ViewGroup container,
|
@Nullable ViewGroup container,
|
||||||
@Nullable Bundle savedInstanceState) {
|
@Nullable Bundle savedInstanceState) {
|
||||||
|
|
||||||
getActivity().setTitle(R.string.contact_list_button);
|
|
||||||
|
|
||||||
View contentView = inflater.inflate(R.layout.list, container, false);
|
View contentView = inflater.inflate(R.layout.list, container, false);
|
||||||
|
|
||||||
OnContactClickListener<ContactListItem> onContactClickListener =
|
OnContactClickListener<ContactListItem> onContactClickListener =
|
||||||
@@ -122,6 +120,7 @@ public class ContactListFragment extends BaseFragment implements EventListener {
|
|||||||
ContactId contactId = item.getContact().getId();
|
ContactId contactId = item.getContact().getId();
|
||||||
i.putExtra(CONTACT_ID, contactId.getInt());
|
i.putExtra(CONTACT_ID, contactId.getInt());
|
||||||
|
|
||||||
|
// work-around for android bug #224270
|
||||||
if (Build.VERSION.SDK_INT >= 23) {
|
if (Build.VERSION.SDK_INT >= 23) {
|
||||||
ContactListItemViewHolder holder =
|
ContactListItemViewHolder holder =
|
||||||
(ContactListItemViewHolder) list
|
(ContactListItemViewHolder) list
|
||||||
@@ -141,8 +140,7 @@ public class ContactListFragment extends BaseFragment implements EventListener {
|
|||||||
ActivityCompat.startActivity(getActivity(), i,
|
ActivityCompat.startActivity(getActivity(), i,
|
||||||
options.toBundle());
|
options.toBundle());
|
||||||
} else {
|
} else {
|
||||||
// work-around for android bug #224270
|
getActivity().startActivity(i);
|
||||||
startActivity(i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,13 +10,14 @@ import javax.annotation.concurrent.NotThreadSafe;
|
|||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class ContactListItem extends ContactItem {
|
public class ContactListItem extends ContactItem {
|
||||||
|
|
||||||
private boolean empty;
|
private boolean connected, empty;
|
||||||
private long timestamp;
|
private long timestamp;
|
||||||
private int unread;
|
private int unread;
|
||||||
|
|
||||||
public ContactListItem(Contact contact, boolean connected,
|
public ContactListItem(Contact contact, boolean connected,
|
||||||
GroupCount count) {
|
GroupCount count) {
|
||||||
super(contact, connected);
|
super(contact);
|
||||||
|
this.connected = connected;
|
||||||
this.empty = count.getMsgCount() == 0;
|
this.empty = count.getMsgCount() == 0;
|
||||||
this.unread = count.getUnreadCount();
|
this.unread = count.getUnreadCount();
|
||||||
this.timestamp = count.getLatestMsgTime();
|
this.timestamp = count.getLatestMsgTime();
|
||||||
@@ -29,6 +30,14 @@ public class ContactListItem extends ContactItem {
|
|||||||
unread++;
|
unread++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isConnected() {
|
||||||
|
return connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setConnected(boolean connected) {
|
||||||
|
this.connected = connected;
|
||||||
|
}
|
||||||
|
|
||||||
boolean isEmpty() {
|
boolean isEmpty() {
|
||||||
return empty;
|
return empty;
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user