Compare commits

..

1 Commits

Author SHA1 Message Date
akwizgran
e01e0b57c3 Measure performance of DB lookups for parent blocks. 2019-02-13 16:01:34 +00:00
51 changed files with 293 additions and 377 deletions

View File

@@ -39,6 +39,31 @@
<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>

View File

@@ -30,8 +30,8 @@ configurations {
dependencies {
implementation project(path: ':bramble-core', configuration: 'default')
tor 'org.briarproject:tor-android:0.3.5.8@zip'
tor 'org.briarproject:obfs4proxy-android:0.0.9@zip'
tor 'org.briarproject:tor-android:0.3.4.8@zip'
tor 'org.briarproject:obfs4proxy-android:0.0.7@zip'
annotationProcessor 'com.google.dagger:dagger-compiler:2.19'

View File

@@ -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.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.briarproject:obfs4proxy-android:0.0.7:obfs4proxy-android-0.0.7.zip:abdfb5d889d848de9bf214f9276abbf454808a505b870819eccc9a9e985bf617',
'org.briarproject:tor-android:0.3.4.8:tor-android-0.3.4.8.zip:989a0352d9d8d8172cd6c2137654e165e5d2beb10ed1211bab3814e224ad1926',
'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d',
'org.codehaus.groovy:groovy-all:2.4.12:groovy-all-2.4.12.jar:6a56af4bd48903d56bec62821876cadefafd007360cc6bd0d8f7aa8d72b38be4',
'org.codehaus.mojo:animal-sniffer-annotations:1.14:animal-sniffer-annotations-1.14.jar:2068320bd6bad744c3673ab048f67e30bef8f518996fa380033556600669905d',

View File

@@ -0,0 +1,20 @@
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();
}

View File

@@ -41,7 +41,8 @@ public interface ContactExchangeTask {
/**
* Exchanges contact information with a remote peer.
*/
void startExchange(LocalAuthor localAuthor, SecretKey masterSecret,
void startExchange(ContactExchangeListener listener,
LocalAuthor localAuthor, SecretKey masterSecret,
DuplexTransportConnection conn, TransportId transportId,
boolean alice);
}

View File

@@ -1,32 +0,0 @@
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;
}
}

View File

@@ -1,20 +0,0 @@
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;
}
}

View File

@@ -25,6 +25,7 @@ import org.briarproject.bramble.api.transport.KeySetId;
import org.briarproject.bramble.api.transport.TransportKeys;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
@@ -150,6 +151,8 @@ public interface DatabaseComponent {
boolean containsLocalAuthor(Transaction txn, AuthorId local)
throws DbException;
int countFakes(Transaction txn, List<byte[]> ids) throws DbException;
/**
* Deletes the message with the given ID. Unlike
* {@link #removeMessage(Transaction, MessageId)}, the message ID,

View File

@@ -2,11 +2,10 @@ 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;
@@ -14,7 +13,6 @@ 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;
@@ -65,7 +63,6 @@ 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;
@@ -74,6 +71,7 @@ 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;
@@ -83,9 +81,8 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
@Inject
ContactExchangeTaskImpl(DatabaseComponent db, ClientHelper clientHelper,
RecordReaderFactory recordReaderFactory,
RecordWriterFactory recordWriterFactory, EventBus eventBus,
Clock clock, ConnectionManager connectionManager,
ContactManager contactManager,
RecordWriterFactory recordWriterFactory, Clock clock,
ConnectionManager connectionManager, ContactManager contactManager,
TransportPropertyManager transportPropertyManager,
CryptoComponent crypto, StreamReaderFactory streamReaderFactory,
StreamWriterFactory streamWriterFactory) {
@@ -93,7 +90,6 @@ 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;
@@ -104,9 +100,11 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
}
@Override
public void startExchange(LocalAuthor localAuthor, SecretKey masterSecret,
public void startExchange(ContactExchangeListener listener,
LocalAuthor localAuthor, SecretKey masterSecret,
DuplexTransportConnection conn, TransportId transportId,
boolean alice) {
this.listener = listener;
this.localAuthor = localAuthor;
this.conn = conn;
this.transportId = transportId;
@@ -125,8 +123,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;
}
@@ -136,7 +134,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
localProperties = transportPropertyManager.getLocalProperties();
} catch (DbException e) {
logException(LOG, WARNING, e);
eventBus.broadcast(new ContactExchangeFailedEvent());
listener.contactExchangeFailed();
tryToClose(conn);
return;
}
@@ -198,7 +196,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
}
} catch (IOException e) {
logException(LOG, WARNING, e);
eventBus.broadcast(new ContactExchangeFailedEvent());
listener.contactExchangeFailed();
tryToClose(conn);
return;
}
@@ -206,7 +204,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
// Verify the contact's signature
if (!verify(remoteInfo.author, remoteNonce, remoteInfo.signature)) {
LOG.warning("Invalid signature");
eventBus.broadcast(new ContactExchangeFailedEvent());
listener.contactExchangeFailed();
tryToClose(conn);
return;
}
@@ -223,17 +221,15 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
conn);
// Pseudonym exchange succeeded
LOG.info("Pseudonym exchange succeeded");
eventBus.broadcast(
new ContactExchangeSucceededEvent(remoteInfo.author));
listener.contactExchangeSucceeded(remoteInfo.author);
} catch (ContactExistsException e) {
logException(LOG, WARNING, e);
tryToClose(conn);
eventBus.broadcast(
new ContactExchangeFailedEvent(remoteInfo.author));
listener.duplicateContact(remoteInfo.author);
} catch (DbException e) {
logException(LOG, WARNING, e);
tryToClose(conn);
eventBus.broadcast(new ContactExchangeFailedEvent());
listener.contactExchangeFailed();
}
}

View File

@@ -28,6 +28,7 @@ import org.briarproject.bramble.api.transport.KeySetId;
import org.briarproject.bramble.api.transport.TransportKeys;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
@@ -188,6 +189,8 @@ interface Database<T> {
boolean containsVisibleMessage(T txn, ContactId c, MessageId m)
throws DbException;
int countFakes(T txn, List<byte[]> ids) throws DbException;
/**
* Returns the number of messages offered by the given contact.
* <p/>

View File

@@ -313,6 +313,13 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
return db.containsLocalAuthor(txn, local);
}
@Override
public int countFakes(Transaction transaction, List<byte[]> ids)
throws DbException {
T txn = unbox(transaction);
return db.countFakes(txn, ids);
}
@Override
public void deleteMessage(Transaction transaction, MessageId m)
throws DbException {

View File

@@ -1,5 +1,6 @@
package org.briarproject.bramble.db;
import org.briarproject.bramble.api.UniqueId;
import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.crypto.SecretKey;
@@ -47,6 +48,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
@@ -92,6 +94,8 @@ abstract class JdbcDatabase implements Database<Connection> {
private static final int OFFSET_CURR = 0;
private static final int OFFSET_NEXT = 1;
private static final int NUM_FAKES = 32 * 1024;
private static final String CREATE_SETTINGS =
"CREATE TABLE settings"
+ " (namespace _STRING NOT NULL,"
@@ -285,6 +289,20 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " REFERENCES contacts (contactId)"
+ " ON DELETE CASCADE)";
// In H2 the MEMORY keyword creates a persistent table with in-memory
// indexes, which must be dropped and recreated when reopening the database.
// In HyperSQL it creates a persistent table that's entirely cached in
// memory, which is the default. Dropping and recreating indexes is
// unnecessary.
private static final String CREATE_FAKES =
"CREATE MEMORY TABLE fakes (fakeId _HASH NOT NULL)";
private static final String DROP_INDEX_FAKES_BY_FAKE_ID =
"DROP INDEX IF EXISTS fakesByFakeId";
private static final String INDEX_FAKES_BY_FAKE_ID =
"CREATE INDEX fakesByFakeId ON fakes (fakeId)";
private static final String INDEX_CONTACTS_BY_AUTHOR_ID =
"CREATE INDEX IF NOT EXISTS contactsByAuthorId"
+ " ON contacts (authorId)";
@@ -376,6 +394,16 @@ abstract class JdbcDatabase implements Database<Connection> {
txn = startTransaction();
try {
storeLastCompacted(txn);
createInMemoryIndexes(txn);
commitTransaction(txn);
} catch (DbException e) {
abortTransaction(txn);
throw e;
}
} else {
txn = startTransaction();
try {
createInMemoryIndexes(txn);
commitTransaction(txn);
} catch (DbException e) {
abortTransaction(txn);
@@ -461,6 +489,7 @@ abstract class JdbcDatabase implements Database<Connection> {
private void createTables(Connection txn) throws DbException {
Statement s = null;
PreparedStatement ps = null;
try {
s = txn.createStatement();
s.executeUpdate(dbTypes.replaceTypes(CREATE_SETTINGS));
@@ -477,9 +506,29 @@ abstract class JdbcDatabase implements Database<Connection> {
s.executeUpdate(dbTypes.replaceTypes(CREATE_TRANSPORTS));
s.executeUpdate(dbTypes.replaceTypes(CREATE_OUTGOING_KEYS));
s.executeUpdate(dbTypes.replaceTypes(CREATE_INCOMING_KEYS));
s.executeUpdate(dbTypes.replaceTypes(CREATE_FAKES));
s.close();
Random random = new Random();
long start = now();
ps = txn.prepareStatement("INSERT INTO fakes (fakeId) VALUES (?)");
int inserted = 0;
while (inserted < NUM_FAKES) {
int batchSize = Math.min(1024, NUM_FAKES - inserted);
for (int i = 0; i < batchSize; i++) {
byte[] id = new byte[UniqueId.LENGTH];
random.nextBytes(id);
ps.setBytes(1, id);
ps.addBatch();
}
ps.executeBatch();
inserted += batchSize;
}
ps.close();
LOG.info("Inserting " + NUM_FAKES + " fakes took "
+ (now() - start) + " ms");
} catch (SQLException e) {
tryToClose(s, LOG, WARNING);
tryToClose(ps, LOG, WARNING);
throw new DbException(e);
}
}
@@ -501,6 +550,21 @@ abstract class JdbcDatabase implements Database<Connection> {
}
}
private void createInMemoryIndexes(Connection txn) throws DbException {
Statement s = null;
try {
long start = now();
s = txn.createStatement();
s.executeUpdate(dbTypes.replaceTypes(DROP_INDEX_FAKES_BY_FAKE_ID));
s.executeUpdate(dbTypes.replaceTypes(INDEX_FAKES_BY_FAKE_ID));
s.close();
LOG.info("Indexing fakes took " + (now() - start) + " ms");
} catch (SQLException e) {
tryToClose(s, LOG, WARNING);
throw new DbException(e);
}
}
@Override
public Connection startTransaction() throws DbException {
Connection txn;
@@ -1153,6 +1217,41 @@ abstract class JdbcDatabase implements Database<Connection> {
}
}
@Override
public int countFakes(Connection txn, List<byte[]> ids)
throws DbException {
if (ids.isEmpty()) return 0;
PreparedStatement ps = null;
ResultSet rs = null;
try {
long start = now();
StringBuilder sb = new StringBuilder();
sb.append("SELECT COUNT (fakeId) FROM fakes WHERE fakeId IN (?");
for (int i = 1; i < ids.size(); i++) {
sb.append(",?");
}
sb.append(')');
String sql = sb.toString();
ps = txn.prepareStatement(sql);
for (int i = 0; i < ids.size(); i++) {
ps.setBytes(i + 1, ids.get(i));
}
rs = ps.executeQuery();
if (!rs.next()) throw new DbException();
int count = rs.getInt(1);
if (rs.next()) throw new DbException();
rs.close();
ps.close();
LOG.info("Counting " + ids.size() + " fakes took "
+ (now() - start) + " ms, found " + count);
return count;
} catch (SQLException e) {
tryToClose(rs, LOG, WARNING);
tryToClose(ps, LOG, WARNING);
throw new DbException(e);
}
}
@Override
public int countOfferedMessages(Connection txn, ContactId c)
throws DbException {

View File

@@ -17,24 +17,16 @@ public interface CircumventionProvider {
String[] BLOCKED = {"CN", "IR", "EG", "BY", "TR", "SY", "VE"};
/**
* Countries where obfs4 bridge connection are likely to work.
* Countries where vanilla bridge connection are likely to work.
* Should be a subset of {@link #BLOCKED}.
*/
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"};
String[] BRIDGES = { "EG", "BY", "TR", "SY", "VE" };
boolean isTorProbablyBlocked(String countryCode);
boolean doBridgesWork(String countryCode);
boolean needsMeek(String countryCode);
@IoExecutor
List<String> getBridges(boolean meek);
List<String> getBridges();
}

View File

@@ -22,8 +22,6 @@ 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;
@@ -42,14 +40,9 @@ 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(boolean useMeek) {
public List<String> getBridges() {
List<String> bridges = this.bridges;
if (bridges != null) return new ArrayList<>(bridges);
@@ -60,8 +53,6 @@ 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();

View File

@@ -470,19 +470,13 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
if (!enable) callback.transportDisabled();
}
private void enableBridges(boolean enable, boolean needsMeek)
throws IOException {
private void enableBridges(boolean enable) throws IOException {
if (enable) {
Collection<String> conf = new ArrayList<>();
conf.add("UseBridges 1");
if (needsMeek) {
conf.add("ClientTransportPlugin meek_lite exec " +
obfs4File.getAbsolutePath());
} else {
conf.add("ClientTransportPlugin obfs4 exec " +
obfs4File.getAbsolutePath());
}
conf.addAll(circumventionProvider.getBridges(needsMeek));
conf.add("ClientTransportPlugin obfs4 exec " +
obfs4File.getAbsolutePath());
conf.addAll(circumventionProvider.getBridges());
controlConnection.setConf(conf);
} else {
controlConnection.setConf("UseBridges", "0");
@@ -722,17 +716,12 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
enableNetwork(false);
} else if (network == PREF_TOR_NETWORK_WITH_BRIDGES ||
(automatic && bridgesWork)) {
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);
}
LOG.info("Enabling network, using bridges");
enableBridges(true);
enableNetwork(true);
} else {
LOG.info("Enabling network, not using bridges");
enableBridges(false, false);
enableBridges(false);
enableNetwork(true);
}
if (online && wifi && charging) {

View File

@@ -1,5 +1,4 @@
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 meek_lite 0.0.2.0:2 97700DFE9F483596DDA6264C4D7DF7641E1E39CE url=https://meek.azureedge.net/ front=ajax.aspnetcdn.com
Bridge obfs4 45.33.37.112:9443 60A609BB4ABE8D46E634AE81ED29ADAB7776B399 cert=t5v19WmNv5Sc2YPNr8RQids365W7MY8zJwQVkOxBjUMFomMWARDzsbYpcWLLcw0J9Gm+BQ iat-mode=0

View File

@@ -131,6 +131,19 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
assertTrue(testDir.mkdirs());
}
@Test
public void testFakes() throws Exception {
List<byte[]> ids = new ArrayList<>(1024);
for (int i = 0; i < 1024; i++) {
ids.add(getRandomId());
}
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
assertEquals(0, db.countFakes(txn, ids));
db.commitTransaction(txn);
db.close();
}
@Test
public void testPersistence() throws Exception {
// Store some records

View File

@@ -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.5.8@zip'
tor 'org.briarproject:tor:0.3.4.8@zip'
tor 'org.briarproject:obfs4proxy:0.0.7@zip'
annotationProcessor 'com.google.dagger:dagger-compiler:2.19'

View File

@@ -44,7 +44,7 @@ public class BridgeTest extends BrambleTestCase {
public static Iterable<String> data() {
BrambleJavaIntegrationTestComponent component =
DaggerBrambleJavaIntegrationTestComponent.builder().build();
return component.getCircumventionProvider().getBridges(false);
return component.getCircumventionProvider().getBridges();
}
private final static long TIMEOUT = SECONDS.toMillis(30);
@@ -104,12 +104,7 @@ public class BridgeTest extends BrambleTestCase {
}
@Override
public boolean needsMeek(String countryCode) {
return false;
}
@Override
public List<String> getBridges(boolean useMeek) {
public List<String> getBridges() {
return singletonList(bridge);
}
};

View File

@@ -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.5.8:tor-0.3.5.8.zip:96e83391f01984f28669235fc02fbb0243140a2b3b2c73aeffd0042c8d3ced18',
'org.briarproject:tor:0.3.4.8:tor-0.3.4.8.zip:bc0158c34002f471a4fe14a6a481816c918eb520a220bb027f64be902beb757f',
'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d',
'org.codehaus.mojo:animal-sniffer-annotations:1.14:animal-sniffer-annotations-1.14.jar:2068320bd6bad744c3673ab048f67e30bef8f518996fa380033556600669905d',
'org.hamcrest:hamcrest-core:1.3:hamcrest-core-1.3.jar:66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9',

View File

@@ -22,7 +22,6 @@
<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"

View File

@@ -12,6 +12,7 @@ import org.briarproject.bramble.api.contact.ContactExchangeTask;
import org.briarproject.bramble.api.contact.ContactManager;
import org.briarproject.bramble.api.crypto.CryptoExecutor;
import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator;
import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DatabaseExecutor;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.identity.IdentityManager;
@@ -82,6 +83,8 @@ public interface AndroidComponent
@DatabaseExecutor
Executor databaseExecutor();
DatabaseComponent databaseComponent();
MessageTracker messageTracker();
LifecycleManager lifecycleManager();

View File

@@ -67,10 +67,6 @@ 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;
@@ -142,7 +138,9 @@ public class ImageActivity extends BriarActivity
if (SDK_INT >= 16) {
viewModel.getOnImageClicked().observe(this, this::onImageClicked);
window.getDecorView().setSystemUiVisibility(UI_FLAGS_DEFAULT);
window.getDecorView().setSystemUiVisibility(
SYSTEM_UI_FLAG_LAYOUT_STABLE |
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
}
@@ -208,16 +206,9 @@ 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) {
@@ -238,8 +229,9 @@ public class ImageActivity extends BriarActivity
@RequiresApi(api = 16)
private void hideSystemUi(View decorView) {
decorView.setSystemUiVisibility(
SYSTEM_UI_FLAG_FULLSCREEN | UI_FLAGS_DEFAULT);
decorView.setSystemUiVisibility(SYSTEM_UI_FLAG_FULLSCREEN |
SYSTEM_UI_FLAG_LAYOUT_STABLE | SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
);
appBarLayout.animate()
.translationYBy(-1 * appBarLayout.getHeight())
.alpha(0f)
@@ -249,7 +241,9 @@ public class ImageActivity extends BriarActivity
@RequiresApi(api = 16)
private void showSystemUi(View decorView) {
decorView.setSystemUiVisibility(UI_FLAGS_DEFAULT);
decorView.setSystemUiVisibility(
SYSTEM_UI_FLAG_LAYOUT_STABLE | SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
);
appBarLayout.animate()
.translationYBy(appBarLayout.getHeight())
.alpha(1f)
@@ -257,18 +251,6 @@ 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) {

View File

@@ -4,12 +4,9 @@ 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;
@@ -31,7 +28,7 @@ import static org.briarproject.bramble.util.LogUtils.logException;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public class ContactExchangeActivity extends KeyAgreementActivity implements
EventListener {
ContactExchangeListener {
private static final Logger LOG =
Logger.getLogger(ContactExchangeActivity.class.getName());
@@ -53,20 +50,6 @@ 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;
@@ -80,28 +63,15 @@ public class ContactExchangeActivity extends KeyAgreementActivity implements
}
// Exchange contact details
contactExchangeTask.startExchange(localAuthor,
result.getMasterKey(), result.getConnection(),
result.getTransportId(), result.wasAlice());
contactExchangeTask.startExchange(ContactExchangeActivity.this,
localAuthor, result.getMasterKey(),
result.getConnection(), result.getTransportId(),
result.wasAlice());
});
}
@Override
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) {
public void contactExchangeSucceeded(Author remoteAuthor) {
runOnUiThreadUnlessDestroyed(() -> {
String contactName = remoteAuthor.getName();
String format = getString(R.string.contact_added_toast);
@@ -112,7 +82,8 @@ public class ContactExchangeActivity extends KeyAgreementActivity implements
});
}
private void duplicateContact(Author remoteAuthor) {
@Override
public void duplicateContact(Author remoteAuthor) {
runOnUiThreadUnlessDestroyed(() -> {
String contactName = remoteAuthor.getName();
String format = getString(R.string.contact_already_exists);
@@ -123,7 +94,8 @@ public class ContactExchangeActivity extends KeyAgreementActivity implements
});
}
private void contactExchangeFailed() {
@Override
public void contactExchangeFailed() {
runOnUiThreadUnlessDestroyed(() -> {
showErrorFragment(R.string.connection_error_explanation);
});

View File

@@ -223,6 +223,7 @@ public class NavDrawerActivity extends BriarActivity implements
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
controller.countFakes();
drawerLayout.closeDrawer(START);
clearBackStack();
if (item.getItemId() == R.id.nav_btn_lock) {

View File

@@ -21,4 +21,5 @@ public interface NavDrawerController extends ActivityLifecycleController {
void shouldAskForDozeWhitelisting(Context ctx,
ResultHandler<Boolean> handler);
void countFakes();
}

View File

@@ -3,6 +3,8 @@ package org.briarproject.briar.android.navdrawer;
import android.app.Activity;
import android.content.Context;
import org.briarproject.bramble.api.UniqueId;
import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DatabaseExecutor;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.event.Event;
@@ -21,6 +23,9 @@ import org.briarproject.bramble.api.settings.SettingsManager;
import org.briarproject.briar.android.controller.DbControllerImpl;
import org.briarproject.briar.android.controller.handler.ResultHandler;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
@@ -49,6 +54,7 @@ public class NavDrawerControllerImpl extends DbControllerImpl
private static final String EXPIRY_DATE_WARNING = "expiryDateWarning";
private static final String EXPIRY_SHOW_UPDATE = "expiryShowUpdate";
private final DatabaseComponent db;
private final PluginManager pluginManager;
private final SettingsManager settingsManager;
private final EventBus eventBus;
@@ -57,9 +63,11 @@ public class NavDrawerControllerImpl extends DbControllerImpl
@Inject
NavDrawerControllerImpl(@DatabaseExecutor Executor dbExecutor,
LifecycleManager lifecycleManager, PluginManager pluginManager,
SettingsManager settingsManager, EventBus eventBus) {
DatabaseComponent db, LifecycleManager lifecycleManager,
PluginManager pluginManager, SettingsManager settingsManager,
EventBus eventBus) {
super(dbExecutor, lifecycleManager);
this.db = db;
this.pluginManager = pluginManager;
this.settingsManager = settingsManager;
this.eventBus = eventBus;
@@ -185,6 +193,25 @@ public class NavDrawerControllerImpl extends DbControllerImpl
});
}
@Override
public void countFakes() {
int numFakes = 1024;
Random random = new Random();
List<byte[]> ids = new ArrayList<>(numFakes);
for (int i = 0; i < numFakes; i++) {
byte[] id = new byte[UniqueId.LENGTH];
random.nextBytes(id);
ids.add(id);
}
runOnDbThread(() -> {
try {
db.transaction(true, txn -> db.countFakes(txn, ids));
} catch (DbException e) {
logException(LOG, WARNING, e);
}
});
}
@Override
public boolean isTransportRunning(TransportId transportId) {
Plugin plugin = pluginManager.getPlugin(transportId);

View File

@@ -178,14 +178,6 @@ 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;

View File

@@ -7,20 +7,14 @@ 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;
@@ -29,13 +23,10 @@ import javax.inject.Inject;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public class GroupMemberListActivity extends BriarActivity
implements EventListener {
public class GroupMemberListActivity extends BriarActivity {
@Inject
GroupMemberListController controller;
@Inject
EventBus eventBus;
private MemberListAdapter adapter;
private BriarRecyclerView list;
@@ -70,50 +61,6 @@ public class GroupMemberListActivity extends BriarActivity
@Override
public void onStart() {
super.onStart();
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()) {
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void loadMembers() {
controller.loadMembers(groupId,
new UiResultExceptionHandler<Collection<MemberListItem>, DbException>(
this) {
@@ -127,6 +74,24 @@ public class GroupMemberListActivity extends BriarActivity
handleDbException(exception);
}
});
list.startPeriodicUpdate();
}
@Override
public void onStop() {
super.onStop();
list.stopPeriodicUpdate();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}

View File

@@ -3,14 +3,11 @@ 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;
@@ -29,19 +26,6 @@ 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;

View File

@@ -3,14 +3,11 @@ 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;
@@ -29,19 +26,6 @@ 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;

View File

@@ -2,7 +2,6 @@ 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;
@@ -11,19 +10,14 @@ 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;
@@ -38,13 +32,10 @@ import static org.briarproject.bramble.util.LogUtils.logException;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
abstract class SharingStatusActivity extends BriarActivity
implements EventListener {
abstract class SharingStatusActivity extends BriarActivity {
@Inject
ConnectionRegistry connectionRegistry;
@Inject
EventBus eventBus;
private static final Logger LOG =
Logger.getLogger(SharingStatusActivity.class.getName());
@@ -77,7 +68,6 @@ abstract class SharingStatusActivity extends BriarActivity
@Override
public void onStart() {
super.onStart();
eventBus.addListener(this);
loadSharedWith();
}
@@ -85,28 +75,9 @@ 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
@@ -129,7 +100,7 @@ abstract class SharingStatusActivity extends BriarActivity
return groupId;
}
protected void loadSharedWith() {
private void loadSharedWith() {
runOnDbThread(() -> {
try {
List<ContactItem> contactItems = new ArrayList<>();
@@ -147,7 +118,6 @@ abstract class SharingStatusActivity extends BriarActivity
private void displaySharedWith(List<ContactItem> contacts) {
runOnUiThreadUnlessDestroyed(() -> {
adapter.clear();
if (contacts.isEmpty()) list.showData();
else adapter.addAll(contacts);
});

View File

@@ -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_toStartOf="@+id/removeButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toRightOf="@+id/avatarView"
app:layout_constraintStart_toEndOf="@+id/avatarView"
app:layout_constraintTop_toBottomOf="@+id/messageCountView"
tools:text="This group is empty, but has a long status text"/>
tools:text="@string/groups_group_is_empty"/>
<Button
android:id="@+id/removeButton"
@@ -94,11 +94,9 @@
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"
app:layout_constraintTop_toTopOf="@+id/statusView"
tools:visibility="visible"/>
tools:visibility="gone"/>
<View
android:id="@+id/divider"

View File

@@ -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="never"/>
app:showAsAction="ifRoom"/>
<item
android:id="@+id/action_group_reveal"

View File

@@ -1,7 +1,6 @@
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;
@@ -33,12 +32,11 @@ import org.briarproject.briar.api.messaging.PrivateMessageHeader;
import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent;
import org.briarproject.briar.client.ConversationClientImpl;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
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;
@@ -46,7 +44,7 @@ import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static java.util.Collections.emptyList;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.StringUtils.fromHexString;
import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ;
@Immutable
@@ -221,26 +219,8 @@ 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(), hasText, attachments));
read, s.isSent(), s.isSeen(), true, emptyList()));
} catch (FormatException e) {
throw new DbException(e);
}
@@ -261,30 +241,11 @@ class MessagingManagerImpl extends ConversationClientImpl
@Override
public Attachment getAttachment(MessageId m) {
// TODO add real implementation
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));
byte[] bytes = fromHexString("89504E470D0A1A0A0000000D49484452" +
"000000010000000108060000001F15C4" +
"890000000A49444154789C6300010000" +
"0500010D0A2DB40000000049454E44AE426082");
return new Attachment(new ByteArrayInputStream(bytes));
}
@Override

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -11,10 +11,6 @@ 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