Compare commits
27 Commits
priority-e
...
1242-displ
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a9fe070b0 | ||
|
|
144ea0c2fc | ||
|
|
a917ebdc76 | ||
|
|
2a389c74dc | ||
|
|
ef16d096f1 | ||
|
|
679455888b | ||
|
|
d4372ddae7 | ||
|
|
c3ef990a94 | ||
|
|
9422ba2718 | ||
|
|
8343f5c2db | ||
|
|
371c7efb04 | ||
|
|
92d67645ab | ||
|
|
a20e868970 | ||
|
|
dd853f6718 | ||
|
|
16a8ad996a | ||
|
|
e27885f0c8 | ||
|
|
f6ef48bf90 | ||
|
|
e282ca763d | ||
|
|
71016382dc | ||
|
|
d004933fae | ||
|
|
37512c50d8 | ||
|
|
0b61a5d40a | ||
|
|
5dd320f282 | ||
|
|
2a21db5fb6 | ||
|
|
b023593a2c | ||
|
|
5ccf2cae1f | ||
|
|
c2cb89ab73 |
25
.idea/codeStyles/Project.xml
generated
@@ -39,31 +39,6 @@
|
|||||||
<JetCodeStyleSettings>
|
<JetCodeStyleSettings>
|
||||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||||
</JetCodeStyleSettings>
|
</JetCodeStyleSettings>
|
||||||
<Objective-C-extensions>
|
|
||||||
<file>
|
|
||||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
|
|
||||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
|
|
||||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
|
|
||||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
|
|
||||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
|
|
||||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
|
|
||||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
|
|
||||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
|
|
||||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
|
|
||||||
</file>
|
|
||||||
<class>
|
|
||||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
|
|
||||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
|
|
||||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
|
|
||||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
|
|
||||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
|
|
||||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
|
|
||||||
</class>
|
|
||||||
<extensions>
|
|
||||||
<pair source="cpp" header="h" fileNamingConvention="NONE" />
|
|
||||||
<pair source="c" header="h" fileNamingConvention="NONE" />
|
|
||||||
</extensions>
|
|
||||||
</Objective-C-extensions>
|
|
||||||
<XML>
|
<XML>
|
||||||
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
|
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
|
||||||
</XML>
|
</XML>
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ configurations {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation project(path: ':bramble-core', configuration: 'default')
|
implementation project(path: ':bramble-core', configuration: 'default')
|
||||||
tor 'org.briarproject:tor-android:0.3.4.8@zip'
|
tor 'org.briarproject:tor-android:0.3.5.8@zip'
|
||||||
tor 'org.briarproject:obfs4proxy-android:0.0.7@zip'
|
tor 'org.briarproject:obfs4proxy-android:0.0.9@zip'
|
||||||
|
|
||||||
annotationProcessor 'com.google.dagger:dagger-compiler:2.19'
|
annotationProcessor 'com.google.dagger:dagger-compiler:2.19'
|
||||||
|
|
||||||
|
|||||||
@@ -68,8 +68,8 @@ dependencyVerification {
|
|||||||
'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8',
|
'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8',
|
||||||
'org.bouncycastle:bcpkix-jdk15on:1.56:bcpkix-jdk15on-1.56.jar:7043dee4e9e7175e93e0b36f45b1ec1ecb893c5f755667e8b916eb8dd201c6ca',
|
'org.bouncycastle:bcpkix-jdk15on:1.56:bcpkix-jdk15on-1.56.jar:7043dee4e9e7175e93e0b36f45b1ec1ecb893c5f755667e8b916eb8dd201c6ca',
|
||||||
'org.bouncycastle:bcprov-jdk15on:1.56:bcprov-jdk15on-1.56.jar:963e1ee14f808ffb99897d848ddcdb28fa91ddda867eb18d303e82728f878349',
|
'org.bouncycastle:bcprov-jdk15on:1.56:bcprov-jdk15on-1.56.jar:963e1ee14f808ffb99897d848ddcdb28fa91ddda867eb18d303e82728f878349',
|
||||||
'org.briarproject:obfs4proxy-android:0.0.7:obfs4proxy-android-0.0.7.zip:abdfb5d889d848de9bf214f9276abbf454808a505b870819eccc9a9e985bf617',
|
'org.briarproject:obfs4proxy-android:0.0.9:obfs4proxy-android-0.0.9.zip:9b7e9181535ea8d8bbe8ae6338e08cf4c5fc1e357a779393e0ce49586d459ae0',
|
||||||
'org.briarproject:tor-android:0.3.4.8:tor-android-0.3.4.8.zip:989a0352d9d8d8172cd6c2137654e165e5d2beb10ed1211bab3814e224ad1926',
|
'org.briarproject:tor-android:0.3.5.8:tor-android-0.3.5.8.zip:42a13a6f185be1a62f42e3f30ce66a3c099ac5ec890a65e7593111b65b44a54a',
|
||||||
'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d',
|
'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d',
|
||||||
'org.codehaus.groovy:groovy-all:2.4.12:groovy-all-2.4.12.jar:6a56af4bd48903d56bec62821876cadefafd007360cc6bd0d8f7aa8d72b38be4',
|
'org.codehaus.groovy:groovy-all:2.4.12:groovy-all-2.4.12.jar:6a56af4bd48903d56bec62821876cadefafd007360cc6bd0d8f7aa8d72b38be4',
|
||||||
'org.codehaus.mojo:animal-sniffer-annotations:1.14:animal-sniffer-annotations-1.14.jar:2068320bd6bad744c3673ab048f67e30bef8f518996fa380033556600669905d',
|
'org.codehaus.mojo:animal-sniffer-annotations:1.14:animal-sniffer-annotations-1.14.jar:2068320bd6bad744c3673ab048f67e30bef8f518996fa380033556600669905d',
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
package org.briarproject.bramble.api.contact;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
|
||||||
public interface ContactExchangeListener {
|
|
||||||
|
|
||||||
void contactExchangeSucceeded(Author remoteAuthor);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The exchange failed because the contact already exists.
|
|
||||||
*/
|
|
||||||
void duplicateContact(Author remoteAuthor);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A general failure.
|
|
||||||
*/
|
|
||||||
void contactExchangeFailed();
|
|
||||||
}
|
|
||||||
@@ -41,8 +41,7 @@ public interface ContactExchangeTask {
|
|||||||
/**
|
/**
|
||||||
* Exchanges contact information with a remote peer.
|
* Exchanges contact information with a remote peer.
|
||||||
*/
|
*/
|
||||||
void startExchange(ContactExchangeListener listener,
|
void startExchange(LocalAuthor localAuthor, SecretKey masterSecret,
|
||||||
LocalAuthor localAuthor, SecretKey masterSecret,
|
|
||||||
DuplexTransportConnection conn, TransportId transportId,
|
DuplexTransportConnection conn, TransportId transportId,
|
||||||
boolean alice);
|
boolean alice);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package org.briarproject.bramble.api.contact.event;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.event.Event;
|
||||||
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
@NotNullByDefault
|
||||||
|
public class ContactExchangeFailedEvent extends Event {
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private final Author duplicateRemoteAuthor;
|
||||||
|
|
||||||
|
public ContactExchangeFailedEvent(@Nullable Author duplicateRemoteAuthor) {
|
||||||
|
this.duplicateRemoteAuthor = duplicateRemoteAuthor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContactExchangeFailedEvent() {
|
||||||
|
this(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Author getDuplicateRemoteAuthor() {
|
||||||
|
return duplicateRemoteAuthor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean wasDuplicateContact() {
|
||||||
|
return duplicateRemoteAuthor != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package org.briarproject.bramble.api.contact.event;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.event.Event;
|
||||||
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
@NotNullByDefault
|
||||||
|
public class ContactExchangeSucceededEvent extends Event {
|
||||||
|
|
||||||
|
private final Author remoteAuthor;
|
||||||
|
|
||||||
|
public ContactExchangeSucceededEvent(Author remoteAuthor) {
|
||||||
|
this.remoteAuthor = remoteAuthor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Author getRemoteAuthor() {
|
||||||
|
return remoteAuthor;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,10 +2,11 @@ package org.briarproject.bramble.contact;
|
|||||||
|
|
||||||
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.ContactExchangeListener;
|
|
||||||
import org.briarproject.bramble.api.contact.ContactExchangeTask;
|
import org.briarproject.bramble.api.contact.ContactExchangeTask;
|
||||||
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;
|
||||||
|
import org.briarproject.bramble.api.contact.event.ContactExchangeFailedEvent;
|
||||||
|
import org.briarproject.bramble.api.contact.event.ContactExchangeSucceededEvent;
|
||||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||||
@@ -13,6 +14,7 @@ import org.briarproject.bramble.api.data.BdfList;
|
|||||||
import org.briarproject.bramble.api.db.ContactExistsException;
|
import org.briarproject.bramble.api.db.ContactExistsException;
|
||||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
@@ -63,6 +65,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
|||||||
private final ClientHelper clientHelper;
|
private final ClientHelper clientHelper;
|
||||||
private final RecordReaderFactory recordReaderFactory;
|
private final RecordReaderFactory recordReaderFactory;
|
||||||
private final RecordWriterFactory recordWriterFactory;
|
private final RecordWriterFactory recordWriterFactory;
|
||||||
|
private final EventBus eventBus;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
private final ConnectionManager connectionManager;
|
private final ConnectionManager connectionManager;
|
||||||
private final ContactManager contactManager;
|
private final ContactManager contactManager;
|
||||||
@@ -71,7 +74,6 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
|||||||
private final StreamReaderFactory streamReaderFactory;
|
private final StreamReaderFactory streamReaderFactory;
|
||||||
private final StreamWriterFactory streamWriterFactory;
|
private final StreamWriterFactory streamWriterFactory;
|
||||||
|
|
||||||
private volatile ContactExchangeListener listener;
|
|
||||||
private volatile LocalAuthor localAuthor;
|
private volatile LocalAuthor localAuthor;
|
||||||
private volatile DuplexTransportConnection conn;
|
private volatile DuplexTransportConnection conn;
|
||||||
private volatile TransportId transportId;
|
private volatile TransportId transportId;
|
||||||
@@ -81,8 +83,9 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
|||||||
@Inject
|
@Inject
|
||||||
ContactExchangeTaskImpl(DatabaseComponent db, ClientHelper clientHelper,
|
ContactExchangeTaskImpl(DatabaseComponent db, ClientHelper clientHelper,
|
||||||
RecordReaderFactory recordReaderFactory,
|
RecordReaderFactory recordReaderFactory,
|
||||||
RecordWriterFactory recordWriterFactory, Clock clock,
|
RecordWriterFactory recordWriterFactory, EventBus eventBus,
|
||||||
ConnectionManager connectionManager, ContactManager contactManager,
|
Clock clock, ConnectionManager connectionManager,
|
||||||
|
ContactManager contactManager,
|
||||||
TransportPropertyManager transportPropertyManager,
|
TransportPropertyManager transportPropertyManager,
|
||||||
CryptoComponent crypto, StreamReaderFactory streamReaderFactory,
|
CryptoComponent crypto, StreamReaderFactory streamReaderFactory,
|
||||||
StreamWriterFactory streamWriterFactory) {
|
StreamWriterFactory streamWriterFactory) {
|
||||||
@@ -90,6 +93,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
|||||||
this.clientHelper = clientHelper;
|
this.clientHelper = clientHelper;
|
||||||
this.recordReaderFactory = recordReaderFactory;
|
this.recordReaderFactory = recordReaderFactory;
|
||||||
this.recordWriterFactory = recordWriterFactory;
|
this.recordWriterFactory = recordWriterFactory;
|
||||||
|
this.eventBus = eventBus;
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
this.connectionManager = connectionManager;
|
this.connectionManager = connectionManager;
|
||||||
this.contactManager = contactManager;
|
this.contactManager = contactManager;
|
||||||
@@ -100,11 +104,9 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startExchange(ContactExchangeListener listener,
|
public void startExchange(LocalAuthor localAuthor, SecretKey masterSecret,
|
||||||
LocalAuthor localAuthor, SecretKey masterSecret,
|
|
||||||
DuplexTransportConnection conn, TransportId transportId,
|
DuplexTransportConnection conn, TransportId transportId,
|
||||||
boolean alice) {
|
boolean alice) {
|
||||||
this.listener = listener;
|
|
||||||
this.localAuthor = localAuthor;
|
this.localAuthor = localAuthor;
|
||||||
this.conn = conn;
|
this.conn = conn;
|
||||||
this.transportId = transportId;
|
this.transportId = transportId;
|
||||||
@@ -123,8 +125,8 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
|||||||
out = conn.getWriter().getOutputStream();
|
out = conn.getWriter().getOutputStream();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
listener.contactExchangeFailed();
|
|
||||||
tryToClose(conn);
|
tryToClose(conn);
|
||||||
|
eventBus.broadcast(new ContactExchangeFailedEvent());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,7 +136,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
|||||||
localProperties = transportPropertyManager.getLocalProperties();
|
localProperties = transportPropertyManager.getLocalProperties();
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
listener.contactExchangeFailed();
|
eventBus.broadcast(new ContactExchangeFailedEvent());
|
||||||
tryToClose(conn);
|
tryToClose(conn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -196,7 +198,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
|||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
listener.contactExchangeFailed();
|
eventBus.broadcast(new ContactExchangeFailedEvent());
|
||||||
tryToClose(conn);
|
tryToClose(conn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -204,7 +206,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
|||||||
// Verify the contact's signature
|
// Verify the contact's signature
|
||||||
if (!verify(remoteInfo.author, remoteNonce, remoteInfo.signature)) {
|
if (!verify(remoteInfo.author, remoteNonce, remoteInfo.signature)) {
|
||||||
LOG.warning("Invalid signature");
|
LOG.warning("Invalid signature");
|
||||||
listener.contactExchangeFailed();
|
eventBus.broadcast(new ContactExchangeFailedEvent());
|
||||||
tryToClose(conn);
|
tryToClose(conn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -221,15 +223,17 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
|||||||
conn);
|
conn);
|
||||||
// Pseudonym exchange succeeded
|
// Pseudonym exchange succeeded
|
||||||
LOG.info("Pseudonym exchange succeeded");
|
LOG.info("Pseudonym exchange succeeded");
|
||||||
listener.contactExchangeSucceeded(remoteInfo.author);
|
eventBus.broadcast(
|
||||||
|
new ContactExchangeSucceededEvent(remoteInfo.author));
|
||||||
} catch (ContactExistsException e) {
|
} catch (ContactExistsException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
tryToClose(conn);
|
tryToClose(conn);
|
||||||
listener.duplicateContact(remoteInfo.author);
|
eventBus.broadcast(
|
||||||
|
new ContactExchangeFailedEvent(remoteInfo.author));
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
tryToClose(conn);
|
tryToClose(conn);
|
||||||
listener.contactExchangeFailed();
|
eventBus.broadcast(new ContactExchangeFailedEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,16 +17,24 @@ public interface CircumventionProvider {
|
|||||||
String[] BLOCKED = {"CN", "IR", "EG", "BY", "TR", "SY", "VE"};
|
String[] BLOCKED = {"CN", "IR", "EG", "BY", "TR", "SY", "VE"};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Countries where vanilla bridge connection are likely to work.
|
* Countries where obfs4 bridge connection are likely to work.
|
||||||
* Should be a subset of {@link #BLOCKED}.
|
* Should be a subset of {@link #BLOCKED}.
|
||||||
*/
|
*/
|
||||||
String[] BRIDGES = { "EG", "BY", "TR", "SY", "VE" };
|
String[] BRIDGES = { "CN", "IR", "EG", "BY", "TR", "SY", "VE" };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Countries where obfs4 bridges won't work and meek is needed.
|
||||||
|
* Should be a subset of {@link #BRIDGES}.
|
||||||
|
*/
|
||||||
|
String[] NEEDS_MEEK = {"CN", "IR"};
|
||||||
|
|
||||||
boolean isTorProbablyBlocked(String countryCode);
|
boolean isTorProbablyBlocked(String countryCode);
|
||||||
|
|
||||||
boolean doBridgesWork(String countryCode);
|
boolean doBridgesWork(String countryCode);
|
||||||
|
|
||||||
|
boolean needsMeek(String countryCode);
|
||||||
|
|
||||||
@IoExecutor
|
@IoExecutor
|
||||||
List<String> getBridges();
|
List<String> getBridges(boolean meek);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ class CircumventionProviderImpl implements CircumventionProvider {
|
|||||||
new HashSet<>(asList(BLOCKED));
|
new HashSet<>(asList(BLOCKED));
|
||||||
private static final Set<String> BRIDGES_WORK_IN_COUNTRIES =
|
private static final Set<String> BRIDGES_WORK_IN_COUNTRIES =
|
||||||
new HashSet<>(asList(BRIDGES));
|
new HashSet<>(asList(BRIDGES));
|
||||||
|
private static final Set<String> BRIDGES_NEED_MEEK =
|
||||||
|
new HashSet<>(asList(NEEDS_MEEK));
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private volatile List<String> bridges = null;
|
private volatile List<String> bridges = null;
|
||||||
@@ -40,9 +42,14 @@ class CircumventionProviderImpl implements CircumventionProvider {
|
|||||||
return BRIDGES_WORK_IN_COUNTRIES.contains(countryCode);
|
return BRIDGES_WORK_IN_COUNTRIES.contains(countryCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean needsMeek(String countryCode) {
|
||||||
|
return BRIDGES_NEED_MEEK.contains(countryCode);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@IoExecutor
|
@IoExecutor
|
||||||
public List<String> getBridges() {
|
public List<String> getBridges(boolean useMeek) {
|
||||||
List<String> bridges = this.bridges;
|
List<String> bridges = this.bridges;
|
||||||
if (bridges != null) return new ArrayList<>(bridges);
|
if (bridges != null) return new ArrayList<>(bridges);
|
||||||
|
|
||||||
@@ -53,6 +60,8 @@ class CircumventionProviderImpl implements CircumventionProvider {
|
|||||||
bridges = new ArrayList<>();
|
bridges = new ArrayList<>();
|
||||||
while (scanner.hasNextLine()) {
|
while (scanner.hasNextLine()) {
|
||||||
String line = scanner.nextLine();
|
String line = scanner.nextLine();
|
||||||
|
boolean isMeekBridge = line.startsWith("Bridge meek");
|
||||||
|
if (useMeek && !isMeekBridge || !useMeek && isMeekBridge) continue;
|
||||||
if (!line.startsWith("#")) bridges.add(line);
|
if (!line.startsWith("#")) bridges.add(line);
|
||||||
}
|
}
|
||||||
scanner.close();
|
scanner.close();
|
||||||
|
|||||||
@@ -470,13 +470,19 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
if (!enable) callback.transportDisabled();
|
if (!enable) callback.transportDisabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void enableBridges(boolean enable) throws IOException {
|
private void enableBridges(boolean enable, boolean needsMeek)
|
||||||
|
throws IOException {
|
||||||
if (enable) {
|
if (enable) {
|
||||||
Collection<String> conf = new ArrayList<>();
|
Collection<String> conf = new ArrayList<>();
|
||||||
conf.add("UseBridges 1");
|
conf.add("UseBridges 1");
|
||||||
conf.add("ClientTransportPlugin obfs4 exec " +
|
if (needsMeek) {
|
||||||
obfs4File.getAbsolutePath());
|
conf.add("ClientTransportPlugin meek_lite exec " +
|
||||||
conf.addAll(circumventionProvider.getBridges());
|
obfs4File.getAbsolutePath());
|
||||||
|
} else {
|
||||||
|
conf.add("ClientTransportPlugin obfs4 exec " +
|
||||||
|
obfs4File.getAbsolutePath());
|
||||||
|
}
|
||||||
|
conf.addAll(circumventionProvider.getBridges(needsMeek));
|
||||||
controlConnection.setConf(conf);
|
controlConnection.setConf(conf);
|
||||||
} else {
|
} else {
|
||||||
controlConnection.setConf("UseBridges", "0");
|
controlConnection.setConf("UseBridges", "0");
|
||||||
@@ -716,12 +722,17 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
enableNetwork(false);
|
enableNetwork(false);
|
||||||
} else if (network == PREF_TOR_NETWORK_WITH_BRIDGES ||
|
} else if (network == PREF_TOR_NETWORK_WITH_BRIDGES ||
|
||||||
(automatic && bridgesWork)) {
|
(automatic && bridgesWork)) {
|
||||||
LOG.info("Enabling network, using bridges");
|
if (circumventionProvider.needsMeek(country)) {
|
||||||
enableBridges(true);
|
LOG.info("Enabling network, using meek bridges");
|
||||||
|
enableBridges(true, true);
|
||||||
|
} else {
|
||||||
|
LOG.info("Enabling network, using obfs4 bridges");
|
||||||
|
enableBridges(true, false);
|
||||||
|
}
|
||||||
enableNetwork(true);
|
enableNetwork(true);
|
||||||
} else {
|
} else {
|
||||||
LOG.info("Enabling network, not using bridges");
|
LOG.info("Enabling network, not using bridges");
|
||||||
enableBridges(false);
|
enableBridges(false, false);
|
||||||
enableNetwork(true);
|
enableNetwork(true);
|
||||||
}
|
}
|
||||||
if (online && wifi && charging) {
|
if (online && wifi && charging) {
|
||||||
|
|||||||
@@ -2,3 +2,4 @@ Bridge obfs4 78.46.188.239:37356 5A2D2F4158D0453E00C7C176978D3F41D69C45DB cert=3
|
|||||||
Bridge obfs4 52.15.78.72:9443 02069A3C5362476936B62BA6F5ACC41ABD573A9B cert=ijYG/OKc7kqu2YzKNFfeXN7/BG2BOgfEP2KyYEiGDQthnHbsOiTWHeIG0WJVW+BckzDgKw iat-mode=0
|
Bridge obfs4 52.15.78.72:9443 02069A3C5362476936B62BA6F5ACC41ABD573A9B cert=ijYG/OKc7kqu2YzKNFfeXN7/BG2BOgfEP2KyYEiGDQthnHbsOiTWHeIG0WJVW+BckzDgKw iat-mode=0
|
||||||
Bridge obfs4 13.58.29.242:9443 0C58939A77DA6B6B29D4B5236A75865659607AE0 cert=OylWIEHb/ezpq1zWxW0sgKRn+9ARH2eOcQOZ8/Gew+4l+oKOhQ2jUX/Y+FSl61JorXZUWA iat-mode=0
|
Bridge obfs4 13.58.29.242:9443 0C58939A77DA6B6B29D4B5236A75865659607AE0 cert=OylWIEHb/ezpq1zWxW0sgKRn+9ARH2eOcQOZ8/Gew+4l+oKOhQ2jUX/Y+FSl61JorXZUWA iat-mode=0
|
||||||
Bridge obfs4 45.33.37.112:9443 60A609BB4ABE8D46E634AE81ED29ADAB7776B399 cert=t5v19WmNv5Sc2YPNr8RQids365W7MY8zJwQVkOxBjUMFomMWARDzsbYpcWLLcw0J9Gm+BQ iat-mode=0
|
Bridge obfs4 45.33.37.112:9443 60A609BB4ABE8D46E634AE81ED29ADAB7776B399 cert=t5v19WmNv5Sc2YPNr8RQids365W7MY8zJwQVkOxBjUMFomMWARDzsbYpcWLLcw0J9Gm+BQ iat-mode=0
|
||||||
|
Bridge meek_lite 0.0.2.0:2 97700DFE9F483596DDA6264C4D7DF7641E1E39CE url=https://meek.azureedge.net/ front=ajax.aspnetcdn.com
|
||||||
@@ -16,7 +16,7 @@ dependencies {
|
|||||||
implementation fileTree(dir: 'libs', include: '*.jar')
|
implementation fileTree(dir: 'libs', include: '*.jar')
|
||||||
implementation 'net.java.dev.jna:jna:4.5.2'
|
implementation 'net.java.dev.jna:jna:4.5.2'
|
||||||
implementation 'net.java.dev.jna:jna-platform:4.5.2'
|
implementation 'net.java.dev.jna:jna-platform:4.5.2'
|
||||||
tor 'org.briarproject:tor:0.3.4.8@zip'
|
tor 'org.briarproject:tor:0.3.5.8@zip'
|
||||||
tor 'org.briarproject:obfs4proxy:0.0.7@zip'
|
tor 'org.briarproject:obfs4proxy:0.0.7@zip'
|
||||||
|
|
||||||
annotationProcessor 'com.google.dagger:dagger-compiler:2.19'
|
annotationProcessor 'com.google.dagger:dagger-compiler:2.19'
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public class BridgeTest extends BrambleTestCase {
|
|||||||
public static Iterable<String> data() {
|
public static Iterable<String> data() {
|
||||||
BrambleJavaIntegrationTestComponent component =
|
BrambleJavaIntegrationTestComponent component =
|
||||||
DaggerBrambleJavaIntegrationTestComponent.builder().build();
|
DaggerBrambleJavaIntegrationTestComponent.builder().build();
|
||||||
return component.getCircumventionProvider().getBridges();
|
return component.getCircumventionProvider().getBridges(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static long TIMEOUT = SECONDS.toMillis(30);
|
private final static long TIMEOUT = SECONDS.toMillis(30);
|
||||||
@@ -104,7 +104,12 @@ public class BridgeTest extends BrambleTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getBridges() {
|
public boolean needsMeek(String countryCode) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getBridges(boolean useMeek) {
|
||||||
return singletonList(bridge);
|
return singletonList(bridge);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ dependencyVerification {
|
|||||||
'org.apache.ant:ant:1.9.4:ant-1.9.4.jar:649ae0730251de07b8913f49286d46bba7b92d47c5f332610aa426c4f02161d8',
|
'org.apache.ant:ant:1.9.4:ant-1.9.4.jar:649ae0730251de07b8913f49286d46bba7b92d47c5f332610aa426c4f02161d8',
|
||||||
'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8',
|
'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8',
|
||||||
'org.briarproject:obfs4proxy:0.0.7:obfs4proxy-0.0.7.zip:5b2f693262ce43a7e130f7cc7d5d1617925330640a2eb6d71085e95df8ee0642',
|
'org.briarproject:obfs4proxy:0.0.7:obfs4proxy-0.0.7.zip:5b2f693262ce43a7e130f7cc7d5d1617925330640a2eb6d71085e95df8ee0642',
|
||||||
'org.briarproject:tor:0.3.4.8:tor-0.3.4.8.zip:bc0158c34002f471a4fe14a6a481816c918eb520a220bb027f64be902beb757f',
|
'org.briarproject:tor:0.3.5.8:tor-0.3.5.8.zip:96e83391f01984f28669235fc02fbb0243140a2b3b2c73aeffd0042c8d3ced18',
|
||||||
'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d',
|
'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d',
|
||||||
'org.codehaus.mojo:animal-sniffer-annotations:1.14:animal-sniffer-annotations-1.14.jar:2068320bd6bad744c3673ab048f67e30bef8f518996fa380033556600669905d',
|
'org.codehaus.mojo:animal-sniffer-annotations:1.14:animal-sniffer-annotations-1.14.jar:2068320bd6bad744c3673ab048f67e30bef8f518996fa380033556600669905d',
|
||||||
'org.hamcrest:hamcrest-core:1.3:hamcrest-core-1.3.jar:66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9',
|
'org.hamcrest:hamcrest-core:1.3:hamcrest-core-1.3.jar:66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9',
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||||
<uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
|
<uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
|
||||||
<uses-permission-sdk-23 android:name="android.permission.USE_BIOMETRIC" />
|
<uses-permission-sdk-23 android:name="android.permission.USE_BIOMETRIC" />
|
||||||
|
<uses-permission-sdk-23 android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name="org.briarproject.briar.android.BriarApplicationImpl"
|
android:name="org.briarproject.briar.android.BriarApplicationImpl"
|
||||||
|
|||||||
@@ -67,6 +67,10 @@ public class ImageActivity extends BriarActivity
|
|||||||
final static String NAME = "name";
|
final static String NAME = "name";
|
||||||
final static String DATE = "date";
|
final static String DATE = "date";
|
||||||
|
|
||||||
|
@RequiresApi(api = 16)
|
||||||
|
private final static int UI_FLAGS_DEFAULT =
|
||||||
|
SYSTEM_UI_FLAG_LAYOUT_STABLE | SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ViewModelProvider.Factory viewModelFactory;
|
ViewModelProvider.Factory viewModelFactory;
|
||||||
|
|
||||||
@@ -138,9 +142,7 @@ public class ImageActivity extends BriarActivity
|
|||||||
|
|
||||||
if (SDK_INT >= 16) {
|
if (SDK_INT >= 16) {
|
||||||
viewModel.getOnImageClicked().observe(this, this::onImageClicked);
|
viewModel.getOnImageClicked().observe(this, this::onImageClicked);
|
||||||
window.getDecorView().setSystemUiVisibility(
|
window.getDecorView().setSystemUiVisibility(UI_FLAGS_DEFAULT);
|
||||||
SYSTEM_UI_FLAG_LAYOUT_STABLE |
|
|
||||||
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,9 +208,16 @@ public class ImageActivity extends BriarActivity
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPullComplete() {
|
public void onPullComplete() {
|
||||||
|
showStatusBarBeforeFinishing();
|
||||||
supportFinishAfterTransition();
|
supportFinishAfterTransition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
showStatusBarBeforeFinishing();
|
||||||
|
super.onBackPressed();
|
||||||
|
}
|
||||||
|
|
||||||
@RequiresApi(api = 16)
|
@RequiresApi(api = 16)
|
||||||
private void onImageClicked(@Nullable Boolean clicked) {
|
private void onImageClicked(@Nullable Boolean clicked) {
|
||||||
if (clicked != null && clicked) {
|
if (clicked != null && clicked) {
|
||||||
@@ -229,9 +238,8 @@ public class ImageActivity extends BriarActivity
|
|||||||
|
|
||||||
@RequiresApi(api = 16)
|
@RequiresApi(api = 16)
|
||||||
private void hideSystemUi(View decorView) {
|
private void hideSystemUi(View decorView) {
|
||||||
decorView.setSystemUiVisibility(SYSTEM_UI_FLAG_FULLSCREEN |
|
decorView.setSystemUiVisibility(
|
||||||
SYSTEM_UI_FLAG_LAYOUT_STABLE | SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
SYSTEM_UI_FLAG_FULLSCREEN | UI_FLAGS_DEFAULT);
|
||||||
);
|
|
||||||
appBarLayout.animate()
|
appBarLayout.animate()
|
||||||
.translationYBy(-1 * appBarLayout.getHeight())
|
.translationYBy(-1 * appBarLayout.getHeight())
|
||||||
.alpha(0f)
|
.alpha(0f)
|
||||||
@@ -241,9 +249,7 @@ public class ImageActivity extends BriarActivity
|
|||||||
|
|
||||||
@RequiresApi(api = 16)
|
@RequiresApi(api = 16)
|
||||||
private void showSystemUi(View decorView) {
|
private void showSystemUi(View decorView) {
|
||||||
decorView.setSystemUiVisibility(
|
decorView.setSystemUiVisibility(UI_FLAGS_DEFAULT);
|
||||||
SYSTEM_UI_FLAG_LAYOUT_STABLE | SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
|
||||||
);
|
|
||||||
appBarLayout.animate()
|
appBarLayout.animate()
|
||||||
.translationYBy(appBarLayout.getHeight())
|
.translationYBy(appBarLayout.getHeight())
|
||||||
.alpha(1f)
|
.alpha(1f)
|
||||||
@@ -251,6 +257,18 @@ public class ImageActivity extends BriarActivity
|
|||||||
.start();
|
.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we don't show the status bar again before finishing this activity,
|
||||||
|
* the return transition will "jump" down the size of the status bar
|
||||||
|
* when the previous activity (with visible status bar) is shown.
|
||||||
|
*/
|
||||||
|
private void showStatusBarBeforeFinishing() {
|
||||||
|
if (SDK_INT >= 16 && appBarLayout.getVisibility() == GONE) {
|
||||||
|
View decorView = getWindow().getDecorView();
|
||||||
|
decorView.setSystemUiVisibility(UI_FLAGS_DEFAULT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void showSaveImageDialog() {
|
private void showSaveImageDialog() {
|
||||||
OnClickListener okListener = (dialog, which) -> {
|
OnClickListener okListener = (dialog, which) -> {
|
||||||
if (SDK_INT >= 19) {
|
if (SDK_INT >= 19) {
|
||||||
|
|||||||
@@ -4,9 +4,12 @@ import android.os.Bundle;
|
|||||||
import android.support.annotation.UiThread;
|
import android.support.annotation.UiThread;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.contact.ContactExchangeListener;
|
|
||||||
import org.briarproject.bramble.api.contact.ContactExchangeTask;
|
import org.briarproject.bramble.api.contact.ContactExchangeTask;
|
||||||
|
import org.briarproject.bramble.api.contact.event.ContactExchangeFailedEvent;
|
||||||
|
import org.briarproject.bramble.api.contact.event.ContactExchangeSucceededEvent;
|
||||||
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.EventListener;
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
@@ -28,7 +31,7 @@ import static org.briarproject.bramble.util.LogUtils.logException;
|
|||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
public class ContactExchangeActivity extends KeyAgreementActivity implements
|
public class ContactExchangeActivity extends KeyAgreementActivity implements
|
||||||
ContactExchangeListener {
|
EventListener {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(ContactExchangeActivity.class.getName());
|
Logger.getLogger(ContactExchangeActivity.class.getName());
|
||||||
@@ -50,6 +53,20 @@ public class ContactExchangeActivity extends KeyAgreementActivity implements
|
|||||||
getSupportActionBar().setTitle(R.string.add_contact_title);
|
getSupportActionBar().setTitle(R.string.add_contact_title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
// Listen to updates from contactExchangeTask
|
||||||
|
eventBus.addListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
// Stop listen to updates from contactExchangeTask
|
||||||
|
eventBus.addListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
private void startContactExchange(KeyAgreementResult result) {
|
private void startContactExchange(KeyAgreementResult result) {
|
||||||
runOnDbThread(() -> {
|
runOnDbThread(() -> {
|
||||||
LocalAuthor localAuthor;
|
LocalAuthor localAuthor;
|
||||||
@@ -63,15 +80,28 @@ public class ContactExchangeActivity extends KeyAgreementActivity implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Exchange contact details
|
// Exchange contact details
|
||||||
contactExchangeTask.startExchange(ContactExchangeActivity.this,
|
contactExchangeTask.startExchange(localAuthor,
|
||||||
localAuthor, result.getMasterKey(),
|
result.getMasterKey(), result.getConnection(),
|
||||||
result.getConnection(), result.getTransportId(),
|
result.getTransportId(), result.wasAlice());
|
||||||
result.wasAlice());
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contactExchangeSucceeded(Author remoteAuthor) {
|
public void eventOccurred(Event e) {
|
||||||
|
if (e instanceof ContactExchangeSucceededEvent) {
|
||||||
|
contactExchangeSucceeded(
|
||||||
|
((ContactExchangeSucceededEvent) e).getRemoteAuthor());
|
||||||
|
} else if (e instanceof ContactExchangeFailedEvent) {
|
||||||
|
ContactExchangeFailedEvent fe = (ContactExchangeFailedEvent) e;
|
||||||
|
if (fe.wasDuplicateContact()) {
|
||||||
|
duplicateContact(fe.getDuplicateRemoteAuthor());
|
||||||
|
} else {
|
||||||
|
contactExchangeFailed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void contactExchangeSucceeded(Author remoteAuthor) {
|
||||||
runOnUiThreadUnlessDestroyed(() -> {
|
runOnUiThreadUnlessDestroyed(() -> {
|
||||||
String contactName = remoteAuthor.getName();
|
String contactName = remoteAuthor.getName();
|
||||||
String format = getString(R.string.contact_added_toast);
|
String format = getString(R.string.contact_added_toast);
|
||||||
@@ -82,8 +112,7 @@ public class ContactExchangeActivity extends KeyAgreementActivity implements
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void duplicateContact(Author remoteAuthor) {
|
||||||
public void duplicateContact(Author remoteAuthor) {
|
|
||||||
runOnUiThreadUnlessDestroyed(() -> {
|
runOnUiThreadUnlessDestroyed(() -> {
|
||||||
String contactName = remoteAuthor.getName();
|
String contactName = remoteAuthor.getName();
|
||||||
String format = getString(R.string.contact_already_exists);
|
String format = getString(R.string.contact_already_exists);
|
||||||
@@ -94,8 +123,7 @@ public class ContactExchangeActivity extends KeyAgreementActivity implements
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void contactExchangeFailed() {
|
||||||
public void contactExchangeFailed() {
|
|
||||||
runOnUiThreadUnlessDestroyed(() -> {
|
runOnUiThreadUnlessDestroyed(() -> {
|
||||||
showErrorFragment(R.string.connection_error_explanation);
|
showErrorFragment(R.string.connection_error_explanation);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -178,6 +178,14 @@ public class GroupActivity extends
|
|||||||
} else super.onActivityResult(request, result, data);
|
} else super.onActivityResult(request, result, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemReceived(GroupMessageItem item) {
|
||||||
|
super.onItemReceived(item);
|
||||||
|
if (item instanceof JoinMessageItem) {
|
||||||
|
if (((JoinMessageItem) item).isInitial()) loadSharingContacts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getMaxTextLength() {
|
protected int getMaxTextLength() {
|
||||||
return MAX_GROUP_POST_TEXT_LENGTH;
|
return MAX_GROUP_POST_TEXT_LENGTH;
|
||||||
|
|||||||
@@ -7,14 +7,20 @@ import android.view.MenuItem;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
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.EventBus;
|
||||||
|
import org.briarproject.bramble.api.event.EventListener;
|
||||||
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.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
|
import org.briarproject.bramble.api.sync.event.GroupRemovedEvent;
|
||||||
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.controller.handler.UiResultExceptionHandler;
|
import org.briarproject.briar.android.controller.handler.UiResultExceptionHandler;
|
||||||
import org.briarproject.briar.android.view.BriarRecyclerView;
|
import org.briarproject.briar.android.view.BriarRecyclerView;
|
||||||
|
import org.briarproject.briar.api.privategroup.JoinMessageHeader;
|
||||||
|
import org.briarproject.briar.api.privategroup.event.GroupMessageAddedEvent;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
@@ -23,10 +29,13 @@ import javax.inject.Inject;
|
|||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
public class GroupMemberListActivity extends BriarActivity {
|
public class GroupMemberListActivity extends BriarActivity
|
||||||
|
implements EventListener {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
GroupMemberListController controller;
|
GroupMemberListController controller;
|
||||||
|
@Inject
|
||||||
|
EventBus eventBus;
|
||||||
|
|
||||||
private MemberListAdapter adapter;
|
private MemberListAdapter adapter;
|
||||||
private BriarRecyclerView list;
|
private BriarRecyclerView list;
|
||||||
@@ -61,28 +70,38 @@ public class GroupMemberListActivity extends BriarActivity {
|
|||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
controller.loadMembers(groupId,
|
loadMembers();
|
||||||
new UiResultExceptionHandler<Collection<MemberListItem>, DbException>(
|
eventBus.addListener(this);
|
||||||
this) {
|
|
||||||
@Override
|
|
||||||
public void onResultUi(Collection<MemberListItem> members) {
|
|
||||||
adapter.addAll(members);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onExceptionUi(DbException exception) {
|
|
||||||
handleDbException(exception);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
list.startPeriodicUpdate();
|
list.startPeriodicUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStop() {
|
public void onStop() {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
|
eventBus.removeListener(this);
|
||||||
list.stopPeriodicUpdate();
|
list.stopPeriodicUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eventOccurred(Event e) {
|
||||||
|
if (e instanceof GroupMessageAddedEvent) {
|
||||||
|
// we can't use GroupInvitationResponseReceivedEvent, because
|
||||||
|
// a peer only becomes a member after joining the group by message
|
||||||
|
GroupMessageAddedEvent ge = (GroupMessageAddedEvent) e;
|
||||||
|
if (ge.getGroupId().equals(groupId) &&
|
||||||
|
ge.getHeader() instanceof JoinMessageHeader) {
|
||||||
|
loadMembers();
|
||||||
|
}
|
||||||
|
} else if (e instanceof GroupRemovedEvent) {
|
||||||
|
GroupRemovedEvent g = (GroupRemovedEvent) e;
|
||||||
|
if (g.getGroup().getId().equals(groupId)) {
|
||||||
|
runOnUiThreadUnlessDestroyed(
|
||||||
|
this::supportFinishAfterTransition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO ContactConnectedEvent and ContactDisconnectedEvent
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
@@ -94,4 +113,20 @@ public class GroupMemberListActivity extends BriarActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadMembers() {
|
||||||
|
controller.loadMembers(groupId,
|
||||||
|
new UiResultExceptionHandler<Collection<MemberListItem>, DbException>(
|
||||||
|
this) {
|
||||||
|
@Override
|
||||||
|
public void onResultUi(Collection<MemberListItem> members) {
|
||||||
|
adapter.addAll(members);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onExceptionUi(DbException exception) {
|
||||||
|
handleDbException(exception);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,14 @@ package org.briarproject.briar.android.sharing;
|
|||||||
import org.briarproject.bramble.api.contact.Contact;
|
import org.briarproject.bramble.api.contact.Contact;
|
||||||
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.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.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.api.blog.BlogInvitationResponse;
|
||||||
import org.briarproject.briar.api.blog.BlogSharingManager;
|
import org.briarproject.briar.api.blog.BlogSharingManager;
|
||||||
|
import org.briarproject.briar.api.blog.event.BlogInvitationResponseReceivedEvent;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
@@ -26,6 +29,19 @@ public class BlogSharingStatusActivity extends SharingStatusActivity {
|
|||||||
component.inject(this);
|
component.inject(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eventOccurred(Event e) {
|
||||||
|
super.eventOccurred(e);
|
||||||
|
if (e instanceof BlogInvitationResponseReceivedEvent) {
|
||||||
|
BlogInvitationResponseReceivedEvent r =
|
||||||
|
(BlogInvitationResponseReceivedEvent) e;
|
||||||
|
BlogInvitationResponse h = r.getMessageHeader();
|
||||||
|
if (h.getShareableId().equals(getGroupId()) && h.wasAccepted()) {
|
||||||
|
loadSharedWith();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
int getInfoText() {
|
int getInfoText() {
|
||||||
return R.string.sharing_status_blog;
|
return R.string.sharing_status_blog;
|
||||||
|
|||||||
@@ -3,11 +3,14 @@ package org.briarproject.briar.android.sharing;
|
|||||||
import org.briarproject.bramble.api.contact.Contact;
|
import org.briarproject.bramble.api.contact.Contact;
|
||||||
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.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.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.api.forum.ForumInvitationResponse;
|
||||||
import org.briarproject.briar.api.forum.ForumSharingManager;
|
import org.briarproject.briar.api.forum.ForumSharingManager;
|
||||||
|
import org.briarproject.briar.api.forum.event.ForumInvitationResponseReceivedEvent;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
@@ -26,6 +29,19 @@ public class ForumSharingStatusActivity extends SharingStatusActivity {
|
|||||||
component.inject(this);
|
component.inject(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eventOccurred(Event e) {
|
||||||
|
super.eventOccurred(e);
|
||||||
|
if (e instanceof ForumInvitationResponseReceivedEvent) {
|
||||||
|
ForumInvitationResponseReceivedEvent r =
|
||||||
|
(ForumInvitationResponseReceivedEvent) e;
|
||||||
|
ForumInvitationResponse h = r.getMessageHeader();
|
||||||
|
if (h.getShareableId().equals(getGroupId()) && h.wasAccepted()) {
|
||||||
|
loadSharedWith();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
int getInfoText() {
|
int getInfoText() {
|
||||||
return R.string.sharing_status_forum;
|
return R.string.sharing_status_forum;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.briarproject.briar.android.sharing;
|
|||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.CallSuper;
|
||||||
import android.support.annotation.StringRes;
|
import android.support.annotation.StringRes;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
@@ -10,14 +11,19 @@ import android.widget.TextView;
|
|||||||
import org.briarproject.bramble.api.contact.Contact;
|
import org.briarproject.bramble.api.contact.Contact;
|
||||||
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.EventBus;
|
||||||
|
import org.briarproject.bramble.api.event.EventListener;
|
||||||
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.ConnectionRegistry;
|
import org.briarproject.bramble.api.plugin.ConnectionRegistry;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
|
import org.briarproject.bramble.api.sync.event.GroupRemovedEvent;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.activity.BriarActivity;
|
import org.briarproject.briar.android.activity.BriarActivity;
|
||||||
import org.briarproject.briar.android.contact.ContactItem;
|
import org.briarproject.briar.android.contact.ContactItem;
|
||||||
import org.briarproject.briar.android.view.BriarRecyclerView;
|
import org.briarproject.briar.android.view.BriarRecyclerView;
|
||||||
|
import org.briarproject.briar.api.sharing.event.ContactLeftShareableEvent;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -32,10 +38,13 @@ import static org.briarproject.bramble.util.LogUtils.logException;
|
|||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
abstract class SharingStatusActivity extends BriarActivity {
|
abstract class SharingStatusActivity extends BriarActivity
|
||||||
|
implements EventListener {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ConnectionRegistry connectionRegistry;
|
ConnectionRegistry connectionRegistry;
|
||||||
|
@Inject
|
||||||
|
EventBus eventBus;
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(SharingStatusActivity.class.getName());
|
Logger.getLogger(SharingStatusActivity.class.getName());
|
||||||
@@ -68,6 +77,7 @@ abstract class SharingStatusActivity extends BriarActivity {
|
|||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
|
eventBus.addListener(this);
|
||||||
loadSharedWith();
|
loadSharedWith();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,9 +85,28 @@ abstract class SharingStatusActivity extends BriarActivity {
|
|||||||
public void onStop() {
|
public void onStop() {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
adapter.clear();
|
adapter.clear();
|
||||||
|
eventBus.removeListener(this);
|
||||||
list.showProgressBar();
|
list.showProgressBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@CallSuper
|
||||||
|
public void eventOccurred(Event e) {
|
||||||
|
if (e instanceof ContactLeftShareableEvent) {
|
||||||
|
ContactLeftShareableEvent c = (ContactLeftShareableEvent) e;
|
||||||
|
if (c.getGroupId().equals(getGroupId())) {
|
||||||
|
loadSharedWith();
|
||||||
|
}
|
||||||
|
} else if (e instanceof GroupRemovedEvent) {
|
||||||
|
GroupRemovedEvent g = (GroupRemovedEvent) e;
|
||||||
|
if (g.getGroup().getId().equals(getGroupId())) {
|
||||||
|
runOnUiThreadUnlessDestroyed(
|
||||||
|
this::supportFinishAfterTransition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO ContactConnectedEvent and ContactDisconnectedEvent
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
// Handle presses on the action bar items
|
// Handle presses on the action bar items
|
||||||
@@ -100,7 +129,7 @@ abstract class SharingStatusActivity extends BriarActivity {
|
|||||||
return groupId;
|
return groupId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadSharedWith() {
|
protected void loadSharedWith() {
|
||||||
runOnDbThread(() -> {
|
runOnDbThread(() -> {
|
||||||
try {
|
try {
|
||||||
List<ContactItem> contactItems = new ArrayList<>();
|
List<ContactItem> contactItems = new ArrayList<>();
|
||||||
@@ -118,6 +147,7 @@ abstract class SharingStatusActivity extends BriarActivity {
|
|||||||
|
|
||||||
private void displaySharedWith(List<ContactItem> contacts) {
|
private void displaySharedWith(List<ContactItem> contacts) {
|
||||||
runOnUiThreadUnlessDestroyed(() -> {
|
runOnUiThreadUnlessDestroyed(() -> {
|
||||||
|
adapter.clear();
|
||||||
if (contacts.isEmpty()) list.showData();
|
if (contacts.isEmpty()) list.showData();
|
||||||
else adapter.addAll(contacts);
|
else adapter.addAll(contacts);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -82,11 +82,11 @@
|
|||||||
android:layout_marginStart="@dimen/listitem_horizontal_margin"
|
android:layout_marginStart="@dimen/listitem_horizontal_margin"
|
||||||
android:layout_marginTop="@dimen/margin_medium"
|
android:layout_marginTop="@dimen/margin_medium"
|
||||||
android:textColor="?android:attr/textColorTertiary"
|
android:textColor="?android:attr/textColorTertiary"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toStartOf="@+id/removeButton"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/avatarView"
|
app:layout_constraintLeft_toRightOf="@+id/avatarView"
|
||||||
app:layout_constraintStart_toEndOf="@+id/avatarView"
|
app:layout_constraintStart_toEndOf="@+id/avatarView"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/messageCountView"
|
app:layout_constraintTop_toBottomOf="@+id/messageCountView"
|
||||||
tools:text="@string/groups_group_is_empty"/>
|
tools:text="This group is empty, but has a long status text"/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/removeButton"
|
android:id="@+id/removeButton"
|
||||||
@@ -94,9 +94,11 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/groups_remove"
|
android:text="@string/groups_remove"
|
||||||
|
android:visibility="gone"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/divider"
|
app:layout_constraintBottom_toBottomOf="@+id/divider"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
tools:visibility="gone"/>
|
app:layout_constraintTop_toTopOf="@+id/statusView"
|
||||||
|
tools:visibility="visible"/>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/divider"
|
android:id="@+id/divider"
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
android:id="@+id/action_group_member_list"
|
android:id="@+id/action_group_member_list"
|
||||||
android:icon="@drawable/ic_group_white"
|
android:icon="@drawable/ic_group_white"
|
||||||
android:title="@string/groups_member_list"
|
android:title="@string/groups_member_list"
|
||||||
app:showAsAction="ifRoom"/>
|
app:showAsAction="never"/>
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_group_reveal"
|
android:id="@+id/action_group_reveal"
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.briarproject.briar.messaging;
|
package org.briarproject.briar.messaging;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.FormatException;
|
import org.briarproject.bramble.api.FormatException;
|
||||||
|
import org.briarproject.bramble.api.UniqueId;
|
||||||
import org.briarproject.bramble.api.client.ClientHelper;
|
import org.briarproject.bramble.api.client.ClientHelper;
|
||||||
import org.briarproject.bramble.api.client.ContactGroupFactory;
|
import org.briarproject.bramble.api.client.ContactGroupFactory;
|
||||||
import org.briarproject.bramble.api.contact.Contact;
|
import org.briarproject.bramble.api.contact.Contact;
|
||||||
@@ -32,11 +33,12 @@ import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
|||||||
import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent;
|
import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent;
|
||||||
import org.briarproject.briar.client.ConversationClientImpl;
|
import org.briarproject.briar.client.ConversationClientImpl;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
@@ -44,7 +46,7 @@ import javax.annotation.concurrent.Immutable;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
import static org.briarproject.bramble.util.StringUtils.fromHexString;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ;
|
import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ;
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@@ -219,8 +221,26 @@ class MessagingManagerImpl extends ConversationClientImpl
|
|||||||
long timestamp = meta.getLong("timestamp");
|
long timestamp = meta.getLong("timestamp");
|
||||||
boolean local = meta.getBoolean("local");
|
boolean local = meta.getBoolean("local");
|
||||||
boolean read = meta.getBoolean("read");
|
boolean read = meta.getBoolean("read");
|
||||||
|
// TODO replace fake attachments by real ones
|
||||||
|
boolean hasText;
|
||||||
|
List<AttachmentHeader> attachments;
|
||||||
|
Random random = new Random(id.hashCode());
|
||||||
|
if (random.nextBoolean()) {
|
||||||
|
hasText = random.nextBoolean();
|
||||||
|
attachments = new ArrayList<>();
|
||||||
|
int numAttachments = random.nextInt(10) + 1;
|
||||||
|
for (int i = 0; i < numAttachments; i++) {
|
||||||
|
byte[] b = new byte[UniqueId.LENGTH];
|
||||||
|
random.nextBytes(b);
|
||||||
|
attachments.add(new AttachmentHeader(new MessageId(b),
|
||||||
|
"image/jpeg"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hasText = true;
|
||||||
|
attachments = emptyList();
|
||||||
|
}
|
||||||
headers.add(new PrivateMessageHeader(id, g, timestamp, local,
|
headers.add(new PrivateMessageHeader(id, g, timestamp, local,
|
||||||
read, s.isSent(), s.isSeen(), true, emptyList()));
|
read, s.isSent(), s.isSeen(), hasText, attachments));
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
@@ -241,11 +261,30 @@ class MessagingManagerImpl extends ConversationClientImpl
|
|||||||
@Override
|
@Override
|
||||||
public Attachment getAttachment(MessageId m) {
|
public Attachment getAttachment(MessageId m) {
|
||||||
// TODO add real implementation
|
// TODO add real implementation
|
||||||
byte[] bytes = fromHexString("89504E470D0A1A0A0000000D49484452" +
|
String[] files = new String[] {
|
||||||
"000000010000000108060000001F15C4" +
|
// "error_animated.gif",
|
||||||
"890000000A49444154789C6300010000" +
|
// "error_high.jpg",
|
||||||
"0500010D0A2DB40000000049454E44AE426082");
|
// "error_wide.jpg",
|
||||||
return new Attachment(new ByteArrayInputStream(bytes));
|
// "error_huge.gif",
|
||||||
|
// "error_large.gif",
|
||||||
|
// "error_malformed.jpg",
|
||||||
|
// "wide.jpg",
|
||||||
|
// "high.jpg",
|
||||||
|
// "small.png",
|
||||||
|
"kitten1.jpg",
|
||||||
|
"kitten2.jpg",
|
||||||
|
"kitten3.gif",
|
||||||
|
"kitten4.jpg",
|
||||||
|
"kitten5.jpg",
|
||||||
|
"kitten6.png",
|
||||||
|
};
|
||||||
|
int index = Math.abs(m.hashCode() % files.length);
|
||||||
|
String file = files[index];
|
||||||
|
getLogger(MessagingManagerImpl.class.getName())
|
||||||
|
.warning("Loading file: " + file);
|
||||||
|
|
||||||
|
InputStream is = getClass().getClassLoader().getResourceAsStream(file);
|
||||||
|
return new Attachment(new BufferedInputStream(is));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
BIN
briar-core/src/main/resources/error_animated.gif
Normal file
|
After Width: | Height: | Size: 43 B |
BIN
briar-core/src/main/resources/error_high.jpg
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
briar-core/src/main/resources/error_huge.gif
Normal file
|
After Width: | Height: | Size: 43 B |
BIN
briar-core/src/main/resources/error_large.gif
Normal file
|
After Width: | Height: | Size: 43 B |
0
briar-core/src/main/resources/error_malformed.jpg
Normal file
BIN
briar-core/src/main/resources/error_wide.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
briar-core/src/main/resources/high.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
briar-core/src/main/resources/kitten1.jpg
Normal file
|
After Width: | Height: | Size: 57 KiB |
BIN
briar-core/src/main/resources/kitten2.jpg
Normal file
|
After Width: | Height: | Size: 128 KiB |
BIN
briar-core/src/main/resources/kitten3.gif
Normal file
|
After Width: | Height: | Size: 288 KiB |
BIN
briar-core/src/main/resources/kitten4.jpg
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
briar-core/src/main/resources/kitten5.jpg
Normal file
|
After Width: | Height: | Size: 79 KiB |
BIN
briar-core/src/main/resources/kitten6.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
briar-core/src/main/resources/small.png
Normal file
|
After Width: | Height: | Size: 133 B |
BIN
briar-core/src/main/resources/wide.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
@@ -11,6 +11,10 @@ The REST API peer comes as a `jar` file
|
|||||||
and needs a Java Runtime Environment (JRE) that supports at least Java 8.
|
and needs a Java Runtime Environment (JRE) that supports at least Java 8.
|
||||||
It currently works only on GNU/Linux operating systems.
|
It currently works only on GNU/Linux operating systems.
|
||||||
|
|
||||||
|
To build the `jar` file, you can do this:
|
||||||
|
|
||||||
|
$ ./gradlew --configure-on-demand briar-headless:jar
|
||||||
|
|
||||||
You can start the peer (and its API server) like this:
|
You can start the peer (and its API server) like this:
|
||||||
|
|
||||||
$ java -jar briar-headless/build/libs/briar-headless.jar
|
$ java -jar briar-headless/build/libs/briar-headless.jar
|
||||||
|
|||||||