Compare commits
27 Commits
misc-code-
...
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>
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</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>
|
||||
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
|
||||
</XML>
|
||||
|
||||
@@ -30,8 +30,8 @@ configurations {
|
||||
|
||||
dependencies {
|
||||
implementation project(path: ':bramble-core', configuration: 'default')
|
||||
tor 'org.briarproject:tor-android:0.3.4.8@zip'
|
||||
tor 'org.briarproject:obfs4proxy-android:0.0.7@zip'
|
||||
tor 'org.briarproject:tor-android:0.3.5.8@zip'
|
||||
tor 'org.briarproject:obfs4proxy-android:0.0.9@zip'
|
||||
|
||||
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.bouncycastle:bcpkix-jdk15on:1.56:bcpkix-jdk15on-1.56.jar:7043dee4e9e7175e93e0b36f45b1ec1ecb893c5f755667e8b916eb8dd201c6ca',
|
||||
'org.bouncycastle:bcprov-jdk15on:1.56:bcprov-jdk15on-1.56.jar:963e1ee14f808ffb99897d848ddcdb28fa91ddda867eb18d303e82728f878349',
|
||||
'org.briarproject:obfs4proxy-android:0.0.7:obfs4proxy-android-0.0.7.zip:abdfb5d889d848de9bf214f9276abbf454808a505b870819eccc9a9e985bf617',
|
||||
'org.briarproject:tor-android:0.3.4.8:tor-android-0.3.4.8.zip:989a0352d9d8d8172cd6c2137654e165e5d2beb10ed1211bab3814e224ad1926',
|
||||
'org.briarproject:obfs4proxy-android:0.0.9:obfs4proxy-android-0.0.9.zip:9b7e9181535ea8d8bbe8ae6338e08cf4c5fc1e357a779393e0ce49586d459ae0',
|
||||
'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.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',
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
void startExchange(ContactExchangeListener listener,
|
||||
LocalAuthor localAuthor, SecretKey masterSecret,
|
||||
void startExchange(LocalAuthor localAuthor, SecretKey masterSecret,
|
||||
DuplexTransportConnection conn, TransportId transportId,
|
||||
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.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.contact.ContactExchangeListener;
|
||||
import org.briarproject.bramble.api.contact.ContactExchangeTask;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
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.SecretKey;
|
||||
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.DatabaseComponent;
|
||||
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.LocalAuthor;
|
||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||
@@ -63,6 +65,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
||||
private final ClientHelper clientHelper;
|
||||
private final RecordReaderFactory recordReaderFactory;
|
||||
private final RecordWriterFactory recordWriterFactory;
|
||||
private final EventBus eventBus;
|
||||
private final Clock clock;
|
||||
private final ConnectionManager connectionManager;
|
||||
private final ContactManager contactManager;
|
||||
@@ -71,7 +74,6 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
||||
private final StreamReaderFactory streamReaderFactory;
|
||||
private final StreamWriterFactory streamWriterFactory;
|
||||
|
||||
private volatile ContactExchangeListener listener;
|
||||
private volatile LocalAuthor localAuthor;
|
||||
private volatile DuplexTransportConnection conn;
|
||||
private volatile TransportId transportId;
|
||||
@@ -81,8 +83,9 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
||||
@Inject
|
||||
ContactExchangeTaskImpl(DatabaseComponent db, ClientHelper clientHelper,
|
||||
RecordReaderFactory recordReaderFactory,
|
||||
RecordWriterFactory recordWriterFactory, Clock clock,
|
||||
ConnectionManager connectionManager, ContactManager contactManager,
|
||||
RecordWriterFactory recordWriterFactory, EventBus eventBus,
|
||||
Clock clock, ConnectionManager connectionManager,
|
||||
ContactManager contactManager,
|
||||
TransportPropertyManager transportPropertyManager,
|
||||
CryptoComponent crypto, StreamReaderFactory streamReaderFactory,
|
||||
StreamWriterFactory streamWriterFactory) {
|
||||
@@ -90,6 +93,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
||||
this.clientHelper = clientHelper;
|
||||
this.recordReaderFactory = recordReaderFactory;
|
||||
this.recordWriterFactory = recordWriterFactory;
|
||||
this.eventBus = eventBus;
|
||||
this.clock = clock;
|
||||
this.connectionManager = connectionManager;
|
||||
this.contactManager = contactManager;
|
||||
@@ -100,11 +104,9 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startExchange(ContactExchangeListener listener,
|
||||
LocalAuthor localAuthor, SecretKey masterSecret,
|
||||
public void startExchange(LocalAuthor localAuthor, SecretKey masterSecret,
|
||||
DuplexTransportConnection conn, TransportId transportId,
|
||||
boolean alice) {
|
||||
this.listener = listener;
|
||||
this.localAuthor = localAuthor;
|
||||
this.conn = conn;
|
||||
this.transportId = transportId;
|
||||
@@ -123,8 +125,8 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
||||
out = conn.getWriter().getOutputStream();
|
||||
} catch (IOException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
listener.contactExchangeFailed();
|
||||
tryToClose(conn);
|
||||
eventBus.broadcast(new ContactExchangeFailedEvent());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -134,7 +136,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
||||
localProperties = transportPropertyManager.getLocalProperties();
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
listener.contactExchangeFailed();
|
||||
eventBus.broadcast(new ContactExchangeFailedEvent());
|
||||
tryToClose(conn);
|
||||
return;
|
||||
}
|
||||
@@ -196,7 +198,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
listener.contactExchangeFailed();
|
||||
eventBus.broadcast(new ContactExchangeFailedEvent());
|
||||
tryToClose(conn);
|
||||
return;
|
||||
}
|
||||
@@ -204,7 +206,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
||||
// Verify the contact's signature
|
||||
if (!verify(remoteInfo.author, remoteNonce, remoteInfo.signature)) {
|
||||
LOG.warning("Invalid signature");
|
||||
listener.contactExchangeFailed();
|
||||
eventBus.broadcast(new ContactExchangeFailedEvent());
|
||||
tryToClose(conn);
|
||||
return;
|
||||
}
|
||||
@@ -221,15 +223,17 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
||||
conn);
|
||||
// Pseudonym exchange succeeded
|
||||
LOG.info("Pseudonym exchange succeeded");
|
||||
listener.contactExchangeSucceeded(remoteInfo.author);
|
||||
eventBus.broadcast(
|
||||
new ContactExchangeSucceededEvent(remoteInfo.author));
|
||||
} catch (ContactExistsException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
tryToClose(conn);
|
||||
listener.duplicateContact(remoteInfo.author);
|
||||
eventBus.broadcast(
|
||||
new ContactExchangeFailedEvent(remoteInfo.author));
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
tryToClose(conn);
|
||||
listener.contactExchangeFailed();
|
||||
eventBus.broadcast(new ContactExchangeFailedEvent());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,16 +17,24 @@ public interface CircumventionProvider {
|
||||
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}.
|
||||
*/
|
||||
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 doBridgesWork(String countryCode);
|
||||
|
||||
boolean needsMeek(String countryCode);
|
||||
|
||||
@IoExecutor
|
||||
List<String> getBridges();
|
||||
List<String> getBridges(boolean meek);
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ class CircumventionProviderImpl implements CircumventionProvider {
|
||||
new HashSet<>(asList(BLOCKED));
|
||||
private static final Set<String> BRIDGES_WORK_IN_COUNTRIES =
|
||||
new HashSet<>(asList(BRIDGES));
|
||||
private static final Set<String> BRIDGES_NEED_MEEK =
|
||||
new HashSet<>(asList(NEEDS_MEEK));
|
||||
|
||||
@Nullable
|
||||
private volatile List<String> bridges = null;
|
||||
@@ -40,9 +42,14 @@ class CircumventionProviderImpl implements CircumventionProvider {
|
||||
return BRIDGES_WORK_IN_COUNTRIES.contains(countryCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsMeek(String countryCode) {
|
||||
return BRIDGES_NEED_MEEK.contains(countryCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
@IoExecutor
|
||||
public List<String> getBridges() {
|
||||
public List<String> getBridges(boolean useMeek) {
|
||||
List<String> bridges = this.bridges;
|
||||
if (bridges != null) return new ArrayList<>(bridges);
|
||||
|
||||
@@ -53,6 +60,8 @@ class CircumventionProviderImpl implements CircumventionProvider {
|
||||
bridges = new ArrayList<>();
|
||||
while (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine();
|
||||
boolean isMeekBridge = line.startsWith("Bridge meek");
|
||||
if (useMeek && !isMeekBridge || !useMeek && isMeekBridge) continue;
|
||||
if (!line.startsWith("#")) bridges.add(line);
|
||||
}
|
||||
scanner.close();
|
||||
|
||||
@@ -470,13 +470,19 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
if (!enable) callback.transportDisabled();
|
||||
}
|
||||
|
||||
private void enableBridges(boolean enable) throws IOException {
|
||||
private void enableBridges(boolean enable, boolean needsMeek)
|
||||
throws IOException {
|
||||
if (enable) {
|
||||
Collection<String> conf = new ArrayList<>();
|
||||
conf.add("UseBridges 1");
|
||||
conf.add("ClientTransportPlugin obfs4 exec " +
|
||||
obfs4File.getAbsolutePath());
|
||||
conf.addAll(circumventionProvider.getBridges());
|
||||
if (needsMeek) {
|
||||
conf.add("ClientTransportPlugin meek_lite exec " +
|
||||
obfs4File.getAbsolutePath());
|
||||
} else {
|
||||
conf.add("ClientTransportPlugin obfs4 exec " +
|
||||
obfs4File.getAbsolutePath());
|
||||
}
|
||||
conf.addAll(circumventionProvider.getBridges(needsMeek));
|
||||
controlConnection.setConf(conf);
|
||||
} else {
|
||||
controlConnection.setConf("UseBridges", "0");
|
||||
@@ -716,12 +722,17 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
enableNetwork(false);
|
||||
} else if (network == PREF_TOR_NETWORK_WITH_BRIDGES ||
|
||||
(automatic && bridgesWork)) {
|
||||
LOG.info("Enabling network, using bridges");
|
||||
enableBridges(true);
|
||||
if (circumventionProvider.needsMeek(country)) {
|
||||
LOG.info("Enabling network, using meek bridges");
|
||||
enableBridges(true, true);
|
||||
} else {
|
||||
LOG.info("Enabling network, using obfs4 bridges");
|
||||
enableBridges(true, false);
|
||||
}
|
||||
enableNetwork(true);
|
||||
} else {
|
||||
LOG.info("Enabling network, not using bridges");
|
||||
enableBridges(false);
|
||||
enableBridges(false, false);
|
||||
enableNetwork(true);
|
||||
}
|
||||
if (online && wifi && charging) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
Bridge obfs4 78.46.188.239:37356 5A2D2F4158D0453E00C7C176978D3F41D69C45DB cert=3c0SwxpOisbohNxEc4tb875RVW8eOu1opRTVXJhafaKA/PNNtI7ElQIVOVZg1AdL5bxGCw iat-mode=0
|
||||
Bridge obfs4 52.15.78.72:9443 02069A3C5362476936B62BA6F5ACC41ABD573A9B cert=ijYG/OKc7kqu2YzKNFfeXN7/BG2BOgfEP2KyYEiGDQthnHbsOiTWHeIG0WJVW+BckzDgKw iat-mode=0
|
||||
Bridge obfs4 13.58.29.242:9443 0C58939A77DA6B6B29D4B5236A75865659607AE0 cert=OylWIEHb/ezpq1zWxW0sgKRn+9ARH2eOcQOZ8/Gew+4l+oKOhQ2jUX/Y+FSl61JorXZUWA iat-mode=0
|
||||
Bridge obfs4 45.33.37.112:9443 60A609BB4ABE8D46E634AE81ED29ADAB7776B399 cert=t5v19WmNv5Sc2YPNr8RQids365W7MY8zJwQVkOxBjUMFomMWARDzsbYpcWLLcw0J9Gm+BQ iat-mode=0
|
||||
Bridge 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 'net.java.dev.jna:jna:4.5.2'
|
||||
implementation 'net.java.dev.jna:jna-platform:4.5.2'
|
||||
tor 'org.briarproject:tor:0.3.4.8@zip'
|
||||
tor 'org.briarproject:tor:0.3.5.8@zip'
|
||||
tor 'org.briarproject:obfs4proxy:0.0.7@zip'
|
||||
|
||||
annotationProcessor 'com.google.dagger:dagger-compiler:2.19'
|
||||
|
||||
@@ -44,7 +44,7 @@ public class BridgeTest extends BrambleTestCase {
|
||||
public static Iterable<String> data() {
|
||||
BrambleJavaIntegrationTestComponent component =
|
||||
DaggerBrambleJavaIntegrationTestComponent.builder().build();
|
||||
return component.getCircumventionProvider().getBridges();
|
||||
return component.getCircumventionProvider().getBridges(false);
|
||||
}
|
||||
|
||||
private final static long TIMEOUT = SECONDS.toMillis(30);
|
||||
@@ -104,7 +104,12 @@ public class BridgeTest extends BrambleTestCase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getBridges() {
|
||||
public boolean needsMeek(String countryCode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getBridges(boolean useMeek) {
|
||||
return singletonList(bridge);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -21,7 +21,7 @@ dependencyVerification {
|
||||
'org.apache.ant:ant:1.9.4:ant-1.9.4.jar:649ae0730251de07b8913f49286d46bba7b92d47c5f332610aa426c4f02161d8',
|
||||
'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8',
|
||||
'org.briarproject:obfs4proxy:0.0.7:obfs4proxy-0.0.7.zip:5b2f693262ce43a7e130f7cc7d5d1617925330640a2eb6d71085e95df8ee0642',
|
||||
'org.briarproject:tor:0.3.4.8:tor-0.3.4.8.zip:bc0158c34002f471a4fe14a6a481816c918eb520a220bb027f64be902beb757f',
|
||||
'org.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.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',
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
<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.USE_BIOMETRIC" />
|
||||
<uses-permission-sdk-23 android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
|
||||
<application
|
||||
android:name="org.briarproject.briar.android.BriarApplicationImpl"
|
||||
|
||||
@@ -67,6 +67,10 @@ public class ImageActivity extends BriarActivity
|
||||
final static String NAME = "name";
|
||||
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
|
||||
ViewModelProvider.Factory viewModelFactory;
|
||||
|
||||
@@ -138,9 +142,7 @@ public class ImageActivity extends BriarActivity
|
||||
|
||||
if (SDK_INT >= 16) {
|
||||
viewModel.getOnImageClicked().observe(this, this::onImageClicked);
|
||||
window.getDecorView().setSystemUiVisibility(
|
||||
SYSTEM_UI_FLAG_LAYOUT_STABLE |
|
||||
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||||
window.getDecorView().setSystemUiVisibility(UI_FLAGS_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,9 +208,16 @@ public class ImageActivity extends BriarActivity
|
||||
|
||||
@Override
|
||||
public void onPullComplete() {
|
||||
showStatusBarBeforeFinishing();
|
||||
supportFinishAfterTransition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
showStatusBarBeforeFinishing();
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
@RequiresApi(api = 16)
|
||||
private void onImageClicked(@Nullable Boolean clicked) {
|
||||
if (clicked != null && clicked) {
|
||||
@@ -229,9 +238,8 @@ public class ImageActivity extends BriarActivity
|
||||
|
||||
@RequiresApi(api = 16)
|
||||
private void hideSystemUi(View decorView) {
|
||||
decorView.setSystemUiVisibility(SYSTEM_UI_FLAG_FULLSCREEN |
|
||||
SYSTEM_UI_FLAG_LAYOUT_STABLE | SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
);
|
||||
decorView.setSystemUiVisibility(
|
||||
SYSTEM_UI_FLAG_FULLSCREEN | UI_FLAGS_DEFAULT);
|
||||
appBarLayout.animate()
|
||||
.translationYBy(-1 * appBarLayout.getHeight())
|
||||
.alpha(0f)
|
||||
@@ -241,9 +249,7 @@ public class ImageActivity extends BriarActivity
|
||||
|
||||
@RequiresApi(api = 16)
|
||||
private void showSystemUi(View decorView) {
|
||||
decorView.setSystemUiVisibility(
|
||||
SYSTEM_UI_FLAG_LAYOUT_STABLE | SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
);
|
||||
decorView.setSystemUiVisibility(UI_FLAGS_DEFAULT);
|
||||
appBarLayout.animate()
|
||||
.translationYBy(appBarLayout.getHeight())
|
||||
.alpha(1f)
|
||||
@@ -251,6 +257,18 @@ public class ImageActivity extends BriarActivity
|
||||
.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() {
|
||||
OnClickListener okListener = (dialog, which) -> {
|
||||
if (SDK_INT >= 19) {
|
||||
|
||||
@@ -4,9 +4,12 @@ import android.os.Bundle;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.briarproject.bramble.api.contact.ContactExchangeListener;
|
||||
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.event.Event;
|
||||
import org.briarproject.bramble.api.event.EventListener;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||
@@ -28,7 +31,7 @@ import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
public class ContactExchangeActivity extends KeyAgreementActivity implements
|
||||
ContactExchangeListener {
|
||||
EventListener {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(ContactExchangeActivity.class.getName());
|
||||
@@ -50,6 +53,20 @@ public class ContactExchangeActivity extends KeyAgreementActivity implements
|
||||
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) {
|
||||
runOnDbThread(() -> {
|
||||
LocalAuthor localAuthor;
|
||||
@@ -63,15 +80,28 @@ public class ContactExchangeActivity extends KeyAgreementActivity implements
|
||||
}
|
||||
|
||||
// Exchange contact details
|
||||
contactExchangeTask.startExchange(ContactExchangeActivity.this,
|
||||
localAuthor, result.getMasterKey(),
|
||||
result.getConnection(), result.getTransportId(),
|
||||
result.wasAlice());
|
||||
contactExchangeTask.startExchange(localAuthor,
|
||||
result.getMasterKey(), result.getConnection(),
|
||||
result.getTransportId(), result.wasAlice());
|
||||
});
|
||||
}
|
||||
|
||||
@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(() -> {
|
||||
String contactName = remoteAuthor.getName();
|
||||
String format = getString(R.string.contact_added_toast);
|
||||
@@ -82,8 +112,7 @@ public class ContactExchangeActivity extends KeyAgreementActivity implements
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void duplicateContact(Author remoteAuthor) {
|
||||
private void duplicateContact(Author remoteAuthor) {
|
||||
runOnUiThreadUnlessDestroyed(() -> {
|
||||
String contactName = remoteAuthor.getName();
|
||||
String format = getString(R.string.contact_already_exists);
|
||||
@@ -94,8 +123,7 @@ public class ContactExchangeActivity extends KeyAgreementActivity implements
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contactExchangeFailed() {
|
||||
private void contactExchangeFailed() {
|
||||
runOnUiThreadUnlessDestroyed(() -> {
|
||||
showErrorFragment(R.string.connection_error_explanation);
|
||||
});
|
||||
|
||||
@@ -178,6 +178,14 @@ public class GroupActivity extends
|
||||
} 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
|
||||
protected int getMaxTextLength() {
|
||||
return MAX_GROUP_POST_TEXT_LENGTH;
|
||||
|
||||
@@ -7,14 +7,20 @@ import android.view.MenuItem;
|
||||
import android.widget.TextView;
|
||||
|
||||
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.ParametersNotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.event.GroupRemovedEvent;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||
import org.briarproject.briar.android.activity.BriarActivity;
|
||||
import org.briarproject.briar.android.controller.handler.UiResultExceptionHandler;
|
||||
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;
|
||||
|
||||
@@ -23,10 +29,13 @@ import javax.inject.Inject;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
public class GroupMemberListActivity extends BriarActivity {
|
||||
public class GroupMemberListActivity extends BriarActivity
|
||||
implements EventListener {
|
||||
|
||||
@Inject
|
||||
GroupMemberListController controller;
|
||||
@Inject
|
||||
EventBus eventBus;
|
||||
|
||||
private MemberListAdapter adapter;
|
||||
private BriarRecyclerView list;
|
||||
@@ -61,28 +70,38 @@ public class GroupMemberListActivity extends BriarActivity {
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
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);
|
||||
}
|
||||
});
|
||||
loadMembers();
|
||||
eventBus.addListener(this);
|
||||
list.startPeriodicUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
eventBus.removeListener(this);
|
||||
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
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
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.db.DatabaseExecutor;
|
||||
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.ParametersNotNullByDefault;
|
||||
import org.briarproject.briar.R;
|
||||
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.event.BlogInvitationResponseReceivedEvent;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
@@ -26,6 +29,19 @@ public class BlogSharingStatusActivity extends SharingStatusActivity {
|
||||
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
|
||||
int getInfoText() {
|
||||
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.db.DatabaseExecutor;
|
||||
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.ParametersNotNullByDefault;
|
||||
import org.briarproject.briar.R;
|
||||
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.event.ForumInvitationResponseReceivedEvent;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
@@ -26,6 +29,19 @@ public class ForumSharingStatusActivity extends SharingStatusActivity {
|
||||
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
|
||||
int getInfoText() {
|
||||
return R.string.sharing_status_forum;
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.briarproject.briar.android.sharing;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.CallSuper;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.view.MenuItem;
|
||||
@@ -10,14 +11,19 @@ import android.widget.TextView;
|
||||
import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||
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.ParametersNotNullByDefault;
|
||||
import org.briarproject.bramble.api.plugin.ConnectionRegistry;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.event.GroupRemovedEvent;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.activity.BriarActivity;
|
||||
import org.briarproject.briar.android.contact.ContactItem;
|
||||
import org.briarproject.briar.android.view.BriarRecyclerView;
|
||||
import org.briarproject.briar.api.sharing.event.ContactLeftShareableEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -32,10 +38,13 @@ import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
abstract class SharingStatusActivity extends BriarActivity {
|
||||
abstract class SharingStatusActivity extends BriarActivity
|
||||
implements EventListener {
|
||||
|
||||
@Inject
|
||||
ConnectionRegistry connectionRegistry;
|
||||
@Inject
|
||||
EventBus eventBus;
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(SharingStatusActivity.class.getName());
|
||||
@@ -68,6 +77,7 @@ abstract class SharingStatusActivity extends BriarActivity {
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
eventBus.addListener(this);
|
||||
loadSharedWith();
|
||||
}
|
||||
|
||||
@@ -75,9 +85,28 @@ abstract class SharingStatusActivity extends BriarActivity {
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
adapter.clear();
|
||||
eventBus.removeListener(this);
|
||||
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
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
// Handle presses on the action bar items
|
||||
@@ -100,7 +129,7 @@ abstract class SharingStatusActivity extends BriarActivity {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
private void loadSharedWith() {
|
||||
protected void loadSharedWith() {
|
||||
runOnDbThread(() -> {
|
||||
try {
|
||||
List<ContactItem> contactItems = new ArrayList<>();
|
||||
@@ -118,6 +147,7 @@ abstract class SharingStatusActivity extends BriarActivity {
|
||||
|
||||
private void displaySharedWith(List<ContactItem> contacts) {
|
||||
runOnUiThreadUnlessDestroyed(() -> {
|
||||
adapter.clear();
|
||||
if (contacts.isEmpty()) list.showData();
|
||||
else adapter.addAll(contacts);
|
||||
});
|
||||
|
||||
@@ -82,11 +82,11 @@
|
||||
android:layout_marginStart="@dimen/listitem_horizontal_margin"
|
||||
android:layout_marginTop="@dimen/margin_medium"
|
||||
android:textColor="?android:attr/textColorTertiary"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/removeButton"
|
||||
app:layout_constraintLeft_toRightOf="@+id/avatarView"
|
||||
app:layout_constraintStart_toEndOf="@+id/avatarView"
|
||||
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
|
||||
android:id="@+id/removeButton"
|
||||
@@ -94,9 +94,11 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/groups_remove"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/divider"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
tools:visibility="gone"/>
|
||||
app:layout_constraintTop_toTopOf="@+id/statusView"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
android:id="@+id/action_group_member_list"
|
||||
android:icon="@drawable/ic_group_white"
|
||||
android:title="@string/groups_member_list"
|
||||
app:showAsAction="ifRoom"/>
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_group_reveal"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.briarproject.briar.messaging;
|
||||
|
||||
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.ContactGroupFactory;
|
||||
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.client.ConversationClientImpl;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
@@ -44,7 +46,7 @@ import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
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;
|
||||
|
||||
@Immutable
|
||||
@@ -219,8 +221,26 @@ class MessagingManagerImpl extends ConversationClientImpl
|
||||
long timestamp = meta.getLong("timestamp");
|
||||
boolean local = meta.getBoolean("local");
|
||||
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,
|
||||
read, s.isSent(), s.isSeen(), true, emptyList()));
|
||||
read, s.isSent(), s.isSeen(), hasText, attachments));
|
||||
} catch (FormatException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
@@ -241,11 +261,30 @@ class MessagingManagerImpl extends ConversationClientImpl
|
||||
@Override
|
||||
public Attachment getAttachment(MessageId m) {
|
||||
// TODO add real implementation
|
||||
byte[] bytes = fromHexString("89504E470D0A1A0A0000000D49484452" +
|
||||
"000000010000000108060000001F15C4" +
|
||||
"890000000A49444154789C6300010000" +
|
||||
"0500010D0A2DB40000000049454E44AE426082");
|
||||
return new Attachment(new ByteArrayInputStream(bytes));
|
||||
String[] files = new String[] {
|
||||
// "error_animated.gif",
|
||||
// "error_high.jpg",
|
||||
// "error_wide.jpg",
|
||||
// "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
|
||||
|
||||
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.
|
||||
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:
|
||||
|
||||
$ java -jar briar-headless/build/libs/briar-headless.jar
|
||||
|
||||