mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-14 11:49:04 +01:00
Compare commits
15 Commits
alpha-1.4.
...
print-db-s
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6fa7520e9 | ||
|
|
d3bffaadf3 | ||
|
|
12b887881d | ||
|
|
74a3f54d28 | ||
|
|
edcb234b93 | ||
|
|
dae00c7e4e | ||
|
|
29b16c4d74 | ||
|
|
40d58a9359 | ||
|
|
60a1a4d2d1 | ||
|
|
238aeb3abd | ||
|
|
62c16fad09 | ||
|
|
68e57bda0d | ||
|
|
0df73dbf0a | ||
|
|
5b648cbd35 | ||
|
|
5e7891d78a |
@@ -123,5 +123,6 @@ pre_release_tests:
|
|||||||
extends: .optional_tests
|
extends: .optional_tests
|
||||||
script:
|
script:
|
||||||
- OPTIONAL_TESTS=org.briarproject.bramble.plugin.tor.BridgeTest ./gradlew --info bramble-java:test --tests BridgeTest
|
- OPTIONAL_TESTS=org.briarproject.bramble.plugin.tor.BridgeTest ./gradlew --info bramble-java:test --tests BridgeTest
|
||||||
|
timeout: 3h
|
||||||
only:
|
only:
|
||||||
- tags
|
- tags
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
package org.briarproject.bramble.api;
|
package org.briarproject.bramble.api;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public abstract class StringMap extends Hashtable<String, String> {
|
public abstract class StringMap extends Hashtable<String, String> {
|
||||||
|
|
||||||
protected StringMap(Map<String, String> m) {
|
protected StringMap(Map<String, String> m) {
|
||||||
@@ -52,4 +58,31 @@ public abstract class StringMap extends Hashtable<String, String> {
|
|||||||
public void putLong(String key, long value) {
|
public void putLong(String key, long value) {
|
||||||
put(key, String.valueOf(value));
|
put(key, String.valueOf(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public int[] getIntArray(String key) {
|
||||||
|
String s = get(key);
|
||||||
|
if (s == null) return null;
|
||||||
|
// Handle empty string because "".split(",") returns {""}
|
||||||
|
if (s.length() == 0) return new int[0];
|
||||||
|
String[] intStrings = s.split(",");
|
||||||
|
int[] ints = new int[intStrings.length];
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < ints.length; i++) {
|
||||||
|
ints[i] = Integer.parseInt(intStrings[i]);
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return ints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putIntArray(String key, int[] value) {
|
||||||
|
List<String> intStrings = new ArrayList<>();
|
||||||
|
for (int integer : value) {
|
||||||
|
intStrings.add(String.valueOf(integer));
|
||||||
|
}
|
||||||
|
// Puts empty string if input array value is empty
|
||||||
|
put(key, StringUtils.join(intStrings, ","));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -746,4 +746,6 @@ public interface DatabaseComponent extends TransactionManager {
|
|||||||
*/
|
*/
|
||||||
void updateTransportKeys(Transaction txn, Collection<TransportKeySet> keys)
|
void updateTransportKeys(Transaction txn, Collection<TransportKeySet> keys)
|
||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
|
void printStats(Transaction txn) throws DbException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,4 +32,13 @@ public interface MailboxManager {
|
|||||||
*/
|
*/
|
||||||
MailboxPairingTask startPairingTask(String qrCodePayload);
|
MailboxPairingTask startPairingTask(String qrCodePayload);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can be used by the UI to test the mailbox connection.
|
||||||
|
*
|
||||||
|
* @return true (success) or false (error).
|
||||||
|
* A {@link OwnMailboxConnectionStatusEvent} might be broadcast with a new
|
||||||
|
* {@link MailboxStatus}.
|
||||||
|
*/
|
||||||
|
boolean checkConnection();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package org.briarproject.bramble.api.mailbox;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@@ -11,12 +13,14 @@ public class MailboxProperties {
|
|||||||
private final String baseUrl;
|
private final String baseUrl;
|
||||||
private final MailboxAuthToken authToken;
|
private final MailboxAuthToken authToken;
|
||||||
private final boolean owner;
|
private final boolean owner;
|
||||||
|
private final List<MailboxVersion> serverSupports;
|
||||||
|
|
||||||
public MailboxProperties(String baseUrl, MailboxAuthToken authToken,
|
public MailboxProperties(String baseUrl, MailboxAuthToken authToken,
|
||||||
boolean owner) {
|
boolean owner, List<MailboxVersion> serverSupports) {
|
||||||
this.baseUrl = baseUrl;
|
this.baseUrl = baseUrl;
|
||||||
this.authToken = authToken;
|
this.authToken = authToken;
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
|
this.serverSupports = serverSupports;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBaseUrl() {
|
public String getBaseUrl() {
|
||||||
@@ -35,4 +39,8 @@ public class MailboxProperties {
|
|||||||
public boolean isOwner() {
|
public boolean isOwner() {
|
||||||
return owner;
|
return owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<MailboxVersion> getServerSupports() {
|
||||||
|
return serverSupports;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package org.briarproject.bramble.api.mailbox;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
@NotNullByDefault
|
||||||
|
public class MailboxVersion implements Comparable<MailboxVersion> {
|
||||||
|
|
||||||
|
private final int major;
|
||||||
|
private final int minor;
|
||||||
|
|
||||||
|
public MailboxVersion(int major, int minor) {
|
||||||
|
this.major = major;
|
||||||
|
this.minor = minor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMajor() {
|
||||||
|
return major;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMinor() {
|
||||||
|
return minor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o instanceof MailboxVersion) {
|
||||||
|
MailboxVersion v = (MailboxVersion) o;
|
||||||
|
return major == v.major && minor == v.minor;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(MailboxVersion v) {
|
||||||
|
int c = major - v.major;
|
||||||
|
if (c != 0) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
return minor - v.minor;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,6 +20,7 @@ import org.briarproject.bramble.api.identity.Author;
|
|||||||
import org.briarproject.bramble.api.identity.AuthorId;
|
import org.briarproject.bramble.api.identity.AuthorId;
|
||||||
import org.briarproject.bramble.api.identity.Identity;
|
import org.briarproject.bramble.api.identity.Identity;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
|
import org.briarproject.bramble.api.mailbox.MailboxProperties;
|
||||||
import org.briarproject.bramble.api.mailbox.MailboxPropertiesUpdate;
|
import org.briarproject.bramble.api.mailbox.MailboxPropertiesUpdate;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.properties.TransportProperties;
|
import org.briarproject.bramble.api.properties.TransportProperties;
|
||||||
@@ -291,6 +292,18 @@ public class TestUtils {
|
|||||||
a.getOutboxId().equals(b.getOutboxId());
|
a.getOutboxId().equals(b.getOutboxId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean mailboxPropertiesEqual(
|
||||||
|
@Nullable MailboxProperties a,
|
||||||
|
@Nullable MailboxProperties b) {
|
||||||
|
if (a == null || b == null) {
|
||||||
|
return a == b;
|
||||||
|
}
|
||||||
|
return a.getOnion().equals(b.getOnion()) &&
|
||||||
|
a.getAuthToken().equals(b.getAuthToken()) &&
|
||||||
|
a.isOwner() == b.isOwner() &&
|
||||||
|
a.getServerSupports().equals(b.getServerSupports());
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean hasEvent(Transaction txn,
|
public static boolean hasEvent(Transaction txn,
|
||||||
Class<? extends Event> eventClass) {
|
Class<? extends Event> eventClass) {
|
||||||
for (CommitAction action : txn.getActions()) {
|
for (CommitAction action : txn.getActions()) {
|
||||||
|
|||||||
@@ -862,4 +862,6 @@ interface Database<T> {
|
|||||||
* Stores the given transport keys, deleting any keys they have replaced.
|
* Stores the given transport keys, deleting any keys they have replaced.
|
||||||
*/
|
*/
|
||||||
void updateTransportKeys(T txn, TransportKeySet ks) throws DbException;
|
void updateTransportKeys(T txn, TransportKeySet ks) throws DbException;
|
||||||
|
|
||||||
|
void printStats(T txn) throws DbException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1256,6 +1256,12 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void printStats(Transaction transaction) throws DbException {
|
||||||
|
T txn = unbox(transaction);
|
||||||
|
db.printStats(txn);
|
||||||
|
}
|
||||||
|
|
||||||
private class CommitActionVisitor implements Visitor {
|
private class CommitActionVisitor implements Visitor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -13,8 +13,12 @@ import org.briarproject.bramble.util.StringUtils;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.DriverManager;
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@@ -26,6 +30,7 @@ import static java.util.logging.Level.WARNING;
|
|||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
|
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
|
||||||
import static org.briarproject.bramble.util.IoUtils.isNonEmptyDirectory;
|
import static org.briarproject.bramble.util.IoUtils.isNonEmptyDirectory;
|
||||||
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logFileOrDir;
|
import static org.briarproject.bramble.util.LogUtils.logFileOrDir;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -101,6 +106,73 @@ class H2Database extends JdbcDatabase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void printStats(Connection txn) throws DbException {
|
||||||
|
List<String> names = printNames(txn);
|
||||||
|
for (String table : names) {
|
||||||
|
tryPrintStats(txn, table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> printNames(Connection txn) throws DbException {
|
||||||
|
List<String> names = new ArrayList<>();
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
String sql =
|
||||||
|
"SELECT table_catalog, table_schema, table_name FROM INFORMATION_SCHEMA.TABLES";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
String catalog = rs.getString(1);
|
||||||
|
String schema = rs.getString(2);
|
||||||
|
String name = rs.getString(3);
|
||||||
|
LOG.info(
|
||||||
|
String.format("Table %s %s %s", catalog, schema, name));
|
||||||
|
names.add(schema + "." + name);
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
tryToClose(rs, LOG, WARNING);
|
||||||
|
tryToClose(ps, LOG, WARNING);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tryPrintStats(Connection txn, String table) {
|
||||||
|
try {
|
||||||
|
printStats(txn, table);
|
||||||
|
} catch (DbException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printStats(Connection txn, String table) throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
String sql = "CALL DISK_SPACE_USED(?)";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setString(1, table);
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
if (!rs.next()) {
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
}
|
||||||
|
long size = rs.getLong(1);
|
||||||
|
if (rs.next()) throw new DbStateException();
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
LOG.info(String.format("Size of table %s: %d", table, size));
|
||||||
|
} catch (SQLException e) {
|
||||||
|
tryToClose(rs, LOG, WARNING);
|
||||||
|
tryToClose(ps, LOG, WARNING);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Connection createConnection() throws DbException, SQLException {
|
protected Connection createConnection() throws DbException, SQLException {
|
||||||
SecretKey key = this.key;
|
SecretKey key = this.key;
|
||||||
|
|||||||
@@ -93,6 +93,11 @@ class HyperSqlDatabase extends JdbcDatabase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void printStats(Connection txn) throws DbException {
|
||||||
|
// Not implemented
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Connection createConnection() throws DbException, SQLException {
|
protected Connection createConnection() throws DbException, SQLException {
|
||||||
SecretKey key = this.key;
|
SecretKey key = this.key;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ interface MailboxApi {
|
|||||||
* @return the owner token
|
* @return the owner token
|
||||||
* @throws ApiException for 401 response.
|
* @throws ApiException for 401 response.
|
||||||
*/
|
*/
|
||||||
MailboxAuthToken setup(MailboxProperties properties)
|
MailboxProperties setup(MailboxProperties properties)
|
||||||
throws IOException, ApiException;
|
throws IOException, ApiException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import org.briarproject.bramble.api.mailbox.MailboxFileId;
|
|||||||
import org.briarproject.bramble.api.mailbox.MailboxFolderId;
|
import org.briarproject.bramble.api.mailbox.MailboxFolderId;
|
||||||
import org.briarproject.bramble.api.mailbox.MailboxId;
|
import org.briarproject.bramble.api.mailbox.MailboxId;
|
||||||
import org.briarproject.bramble.api.mailbox.MailboxProperties;
|
import org.briarproject.bramble.api.mailbox.MailboxProperties;
|
||||||
|
import org.briarproject.bramble.api.mailbox.MailboxVersion;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -56,7 +57,7 @@ class MailboxApiImpl implements MailboxApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MailboxAuthToken setup(MailboxProperties properties)
|
public MailboxProperties setup(MailboxProperties properties)
|
||||||
throws IOException, ApiException {
|
throws IOException, ApiException {
|
||||||
if (!properties.isOwner()) throw new IllegalArgumentException();
|
if (!properties.isOwner()) throw new IllegalArgumentException();
|
||||||
Request request = getRequestBuilder(properties.getAuthToken())
|
Request request = getRequestBuilder(properties.getAuthToken())
|
||||||
@@ -75,8 +76,27 @@ class MailboxApiImpl implements MailboxApi {
|
|||||||
if (tokenNode == null) {
|
if (tokenNode == null) {
|
||||||
throw new ApiException();
|
throw new ApiException();
|
||||||
}
|
}
|
||||||
String ownerToken = tokenNode.textValue();
|
List<MailboxVersion> serverSupports = new ArrayList<>();
|
||||||
return MailboxAuthToken.fromString(ownerToken);
|
ArrayNode serverSupportsNode = getArray(node, "serverSupports");
|
||||||
|
for (JsonNode versionNode : serverSupportsNode) {
|
||||||
|
if (!versionNode.isObject()) throw new ApiException();
|
||||||
|
ObjectNode objectNode = (ObjectNode) versionNode;
|
||||||
|
JsonNode majorNode = objectNode.get("major");
|
||||||
|
JsonNode minorNode = objectNode.get("minor");
|
||||||
|
if (majorNode == null || !majorNode.isNumber()) {
|
||||||
|
throw new ApiException();
|
||||||
|
}
|
||||||
|
if (minorNode == null || !minorNode.isNumber()) {
|
||||||
|
throw new ApiException();
|
||||||
|
}
|
||||||
|
int major = majorNode.asInt();
|
||||||
|
int minor = minorNode.asInt();
|
||||||
|
if (major < 0 || minor < 0) throw new ApiException();
|
||||||
|
serverSupports.add(new MailboxVersion(major, minor));
|
||||||
|
}
|
||||||
|
return new MailboxProperties(properties.getBaseUrl(),
|
||||||
|
MailboxAuthToken.fromString(tokenNode.textValue()),
|
||||||
|
true, serverSupports);
|
||||||
} catch (JacksonException | InvalidMailboxIdException e) {
|
} catch (JacksonException | InvalidMailboxIdException e) {
|
||||||
throw new ApiException();
|
throw new ApiException();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,27 +2,42 @@ package org.briarproject.bramble.mailbox;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
|
import org.briarproject.bramble.api.db.TransactionManager;
|
||||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||||
import org.briarproject.bramble.api.mailbox.MailboxManager;
|
import org.briarproject.bramble.api.mailbox.MailboxManager;
|
||||||
import org.briarproject.bramble.api.mailbox.MailboxPairingTask;
|
import org.briarproject.bramble.api.mailbox.MailboxPairingTask;
|
||||||
|
import org.briarproject.bramble.api.mailbox.MailboxProperties;
|
||||||
import org.briarproject.bramble.api.mailbox.MailboxSettingsManager;
|
import org.briarproject.bramble.api.mailbox.MailboxSettingsManager;
|
||||||
import org.briarproject.bramble.api.mailbox.MailboxStatus;
|
import org.briarproject.bramble.api.mailbox.MailboxStatus;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.GuardedBy;
|
import javax.annotation.concurrent.GuardedBy;
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static java.util.logging.Level.WARNING;
|
||||||
|
import static java.util.logging.Logger.getLogger;
|
||||||
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class MailboxManagerImpl implements MailboxManager {
|
class MailboxManagerImpl implements MailboxManager {
|
||||||
|
|
||||||
|
private static final String TAG = MailboxManagerImpl.class.getName();
|
||||||
|
private final static Logger LOG = getLogger(TAG);
|
||||||
|
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
|
private final MailboxApi api;
|
||||||
|
private final TransactionManager db;
|
||||||
private final MailboxSettingsManager mailboxSettingsManager;
|
private final MailboxSettingsManager mailboxSettingsManager;
|
||||||
private final MailboxPairingTaskFactory pairingTaskFactory;
|
private final MailboxPairingTaskFactory pairingTaskFactory;
|
||||||
|
private final Clock clock;
|
||||||
private final Object lock = new Object();
|
private final Object lock = new Object();
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -32,11 +47,17 @@ class MailboxManagerImpl implements MailboxManager {
|
|||||||
@Inject
|
@Inject
|
||||||
MailboxManagerImpl(
|
MailboxManagerImpl(
|
||||||
@IoExecutor Executor ioExecutor,
|
@IoExecutor Executor ioExecutor,
|
||||||
|
MailboxApi api,
|
||||||
|
TransactionManager db,
|
||||||
MailboxSettingsManager mailboxSettingsManager,
|
MailboxSettingsManager mailboxSettingsManager,
|
||||||
MailboxPairingTaskFactory pairingTaskFactory) {
|
MailboxPairingTaskFactory pairingTaskFactory,
|
||||||
|
Clock clock) {
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
|
this.api = api;
|
||||||
|
this.db = db;
|
||||||
this.mailboxSettingsManager = mailboxSettingsManager;
|
this.mailboxSettingsManager = mailboxSettingsManager;
|
||||||
this.pairingTaskFactory = pairingTaskFactory;
|
this.pairingTaskFactory = pairingTaskFactory;
|
||||||
|
this.clock = clock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -75,4 +96,29 @@ class MailboxManagerImpl implements MailboxManager {
|
|||||||
return created;
|
return created;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkConnection() {
|
||||||
|
boolean success;
|
||||||
|
try {
|
||||||
|
MailboxProperties props = db.transactionWithNullableResult(true,
|
||||||
|
mailboxSettingsManager::getOwnMailboxProperties);
|
||||||
|
success = api.checkStatus(props);
|
||||||
|
} catch (DbException | IOException | MailboxApi.ApiException e) {
|
||||||
|
success = false;
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
}
|
||||||
|
if (success) {
|
||||||
|
try {
|
||||||
|
// we are only recording successful connections here
|
||||||
|
// as those update the UI and failures might be false negatives
|
||||||
|
db.transaction(false, txn ->
|
||||||
|
mailboxSettingsManager.recordSuccessfulConnection(txn,
|
||||||
|
clock.currentTimeMillis()));
|
||||||
|
} catch (DbException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,9 +115,7 @@ class MailboxPairingTaskImpl implements MailboxPairingTask {
|
|||||||
private void pairMailbox() throws IOException, ApiException, DbException {
|
private void pairMailbox() throws IOException, ApiException, DbException {
|
||||||
MailboxProperties mailboxProperties = decodeQrCodePayload(payload);
|
MailboxProperties mailboxProperties = decodeQrCodePayload(payload);
|
||||||
setState(new MailboxPairingState.Pairing());
|
setState(new MailboxPairingState.Pairing());
|
||||||
MailboxAuthToken ownerToken = api.setup(mailboxProperties);
|
MailboxProperties ownerProperties = api.setup(mailboxProperties);
|
||||||
MailboxProperties ownerProperties = new MailboxProperties(
|
|
||||||
mailboxProperties.getBaseUrl(), ownerToken, true);
|
|
||||||
long time = clock.currentTimeMillis();
|
long time = clock.currentTimeMillis();
|
||||||
db.transaction(false, txn -> {
|
db.transaction(false, txn -> {
|
||||||
mailboxSettingsManager
|
mailboxSettingsManager
|
||||||
@@ -182,7 +180,8 @@ class MailboxPairingTaskImpl implements MailboxPairingTask {
|
|||||||
String baseUrl = "http://" + onion + ".onion";
|
String baseUrl = "http://" + onion + ".onion";
|
||||||
byte[] tokenBytes = Arrays.copyOfRange(bytes, 33, 65);
|
byte[] tokenBytes = Arrays.copyOfRange(bytes, 33, 65);
|
||||||
MailboxAuthToken setupToken = new MailboxAuthToken(tokenBytes);
|
MailboxAuthToken setupToken = new MailboxAuthToken(tokenBytes);
|
||||||
return new MailboxProperties(baseUrl, setupToken, true);
|
return new MailboxProperties(baseUrl, setupToken, true,
|
||||||
|
new ArrayList<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -158,6 +158,12 @@ class MailboxPropertyManagerImpl implements MailboxPropertyManager,
|
|||||||
BdfList body = clientHelper.getMessageAsList(txn, m.getId());
|
BdfList body = clientHelper.getMessageAsList(txn, m.getId());
|
||||||
MailboxPropertiesUpdate p = parseProperties(body);
|
MailboxPropertiesUpdate p = parseProperties(body);
|
||||||
txn.attach(new RemoteMailboxPropertiesUpdateEvent(c, p));
|
txn.attach(new RemoteMailboxPropertiesUpdateEvent(c, p));
|
||||||
|
// Reset message retransmission timers for the contact. Avoiding
|
||||||
|
// messages getting stranded:
|
||||||
|
// - on our mailbox, if they now have a mailbox but didn't before
|
||||||
|
// - on the contact's old mailbox, if they removed their mailbox
|
||||||
|
// - on the contact's old mailbox, if they replaced their mailbox
|
||||||
|
db.resetUnackedMessagesToSend(txn, c);
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new InvalidMessageException(e);
|
throw new InvalidMessageException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,13 @@ import org.briarproject.bramble.api.mailbox.MailboxAuthToken;
|
|||||||
import org.briarproject.bramble.api.mailbox.MailboxProperties;
|
import org.briarproject.bramble.api.mailbox.MailboxProperties;
|
||||||
import org.briarproject.bramble.api.mailbox.MailboxSettingsManager;
|
import org.briarproject.bramble.api.mailbox.MailboxSettingsManager;
|
||||||
import org.briarproject.bramble.api.mailbox.MailboxStatus;
|
import org.briarproject.bramble.api.mailbox.MailboxStatus;
|
||||||
|
import org.briarproject.bramble.api.mailbox.MailboxVersion;
|
||||||
import org.briarproject.bramble.api.mailbox.OwnMailboxConnectionStatusEvent;
|
import org.briarproject.bramble.api.mailbox.OwnMailboxConnectionStatusEvent;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.settings.Settings;
|
import org.briarproject.bramble.api.settings.Settings;
|
||||||
import org.briarproject.bramble.api.settings.SettingsManager;
|
import org.briarproject.bramble.api.settings.SettingsManager;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
@@ -30,6 +32,7 @@ class MailboxSettingsManagerImpl implements MailboxSettingsManager {
|
|||||||
static final String SETTINGS_NAMESPACE = "mailbox";
|
static final String SETTINGS_NAMESPACE = "mailbox";
|
||||||
static final String SETTINGS_KEY_ONION = "onion";
|
static final String SETTINGS_KEY_ONION = "onion";
|
||||||
static final String SETTINGS_KEY_TOKEN = "token";
|
static final String SETTINGS_KEY_TOKEN = "token";
|
||||||
|
static final String SETTINGS_KEY_SERVER_SUPPORTS = "serverSupports";
|
||||||
static final String SETTINGS_KEY_LAST_ATTEMPT = "lastAttempt";
|
static final String SETTINGS_KEY_LAST_ATTEMPT = "lastAttempt";
|
||||||
static final String SETTINGS_KEY_LAST_SUCCESS = "lastSuccess";
|
static final String SETTINGS_KEY_LAST_SUCCESS = "lastSuccess";
|
||||||
static final String SETTINGS_KEY_ATTEMPTS = "attempts";
|
static final String SETTINGS_KEY_ATTEMPTS = "attempts";
|
||||||
@@ -55,9 +58,19 @@ class MailboxSettingsManagerImpl implements MailboxSettingsManager {
|
|||||||
String onion = s.get(SETTINGS_KEY_ONION);
|
String onion = s.get(SETTINGS_KEY_ONION);
|
||||||
String token = s.get(SETTINGS_KEY_TOKEN);
|
String token = s.get(SETTINGS_KEY_TOKEN);
|
||||||
if (isNullOrEmpty(onion) || isNullOrEmpty(token)) return null;
|
if (isNullOrEmpty(onion) || isNullOrEmpty(token)) return null;
|
||||||
|
int[] ints = s.getIntArray(SETTINGS_KEY_SERVER_SUPPORTS);
|
||||||
|
// We know we were paired, so we must have proper serverSupports
|
||||||
|
// TODO is throwing sensible? But it's done like that below on "parse error"
|
||||||
|
if (ints == null || ints.length == 0 || ints.length % 2 != 0) {
|
||||||
|
throw new DbException();
|
||||||
|
}
|
||||||
|
List<MailboxVersion> serverSupports = new ArrayList<>();
|
||||||
|
for (int i = 0; i < ints.length - 1; i += 2) {
|
||||||
|
serverSupports.add(new MailboxVersion(ints[i], ints[i + 1]));
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
MailboxAuthToken tokenId = MailboxAuthToken.fromString(token);
|
MailboxAuthToken tokenId = MailboxAuthToken.fromString(token);
|
||||||
return new MailboxProperties(onion, tokenId, true);
|
return new MailboxProperties(onion, tokenId, true, serverSupports);
|
||||||
} catch (InvalidMailboxIdException e) {
|
} catch (InvalidMailboxIdException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
@@ -69,6 +82,14 @@ class MailboxSettingsManagerImpl implements MailboxSettingsManager {
|
|||||||
Settings s = new Settings();
|
Settings s = new Settings();
|
||||||
s.put(SETTINGS_KEY_ONION, p.getBaseUrl());
|
s.put(SETTINGS_KEY_ONION, p.getBaseUrl());
|
||||||
s.put(SETTINGS_KEY_TOKEN, p.getAuthToken().toString());
|
s.put(SETTINGS_KEY_TOKEN, p.getAuthToken().toString());
|
||||||
|
List<MailboxVersion> serverSupports = p.getServerSupports();
|
||||||
|
int[] ints = new int[serverSupports.size() * 2];
|
||||||
|
int i = 0;
|
||||||
|
for (MailboxVersion v : serverSupports) {
|
||||||
|
ints[i++] = v.getMajor();
|
||||||
|
ints[i++] = v.getMinor();
|
||||||
|
}
|
||||||
|
s.putIntArray(SETTINGS_KEY_SERVER_SUPPORTS, ints);
|
||||||
settingsManager.mergeSettings(txn, s, SETTINGS_NAMESPACE);
|
settingsManager.mergeSettings(txn, s, SETTINGS_NAMESPACE);
|
||||||
for (MailboxHook hook : hooks) {
|
for (MailboxHook hook : hooks) {
|
||||||
hook.mailboxPaired(txn, p.getOnion());
|
hook.mailboxPaired(txn, p.getOnion());
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
|||||||
import static org.briarproject.bramble.test.TestUtils.getContactId;
|
import static org.briarproject.bramble.test.TestUtils.getContactId;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||||
|
import static org.briarproject.bramble.test.TestUtils.mailboxPropertiesEqual;
|
||||||
import static org.briarproject.bramble.test.TestUtils.readBytes;
|
import static org.briarproject.bramble.test.TestUtils.readBytes;
|
||||||
import static org.briarproject.bramble.test.TestUtils.writeBytes;
|
import static org.briarproject.bramble.test.TestUtils.writeBytes;
|
||||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||||
@@ -80,11 +81,20 @@ public class MailboxApiTest extends BrambleTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSetup() throws Exception {
|
public void testSetup() throws Exception {
|
||||||
String validResponse = "{\"token\":\"" + token2 + "\"}";
|
String validVersions = "[ {\"major\":1,\"minor\":0} ]";
|
||||||
|
String validResponse = makeSetupResponse(
|
||||||
|
"\"" + token2 + "\"", validVersions);
|
||||||
String invalidResponse = "{\"foo\":\"bar\"}";
|
String invalidResponse = "{\"foo\":\"bar\"}";
|
||||||
String invalidTokenResponse = "{\"token\":{\"foo\":\"bar\"}}";
|
String invalidTokenResponse = makeSetupResponse(
|
||||||
String invalidTokenResponse2 =
|
"{\"foo\":\"bar\"}", validVersions);
|
||||||
"{\"token\":\"" + getRandomString(64) + "\"}";
|
String invalidTokenResponse2 = makeSetupResponse(
|
||||||
|
"\"" + getRandomString(64) + "\"", validVersions);
|
||||||
|
String invalidVersionsResponse = makeSetupResponse(
|
||||||
|
"\"" + token2 + "\"", "42");
|
||||||
|
String invalidVersionsResponse2 = makeSetupResponse(
|
||||||
|
"\"" + token2 + "\"", "[ 1,0 ]");
|
||||||
|
String invalidVersionsResponse3 = makeSetupResponse(
|
||||||
|
"\"" + token2 + "\"", "[ {\"major\":1, \"minor\":-1} ]");
|
||||||
|
|
||||||
MockWebServer server = new MockWebServer();
|
MockWebServer server = new MockWebServer();
|
||||||
server.enqueue(new MockResponse().setBody(validResponse));
|
server.enqueue(new MockResponse().setBody(validResponse));
|
||||||
@@ -94,15 +104,18 @@ public class MailboxApiTest extends BrambleTestCase {
|
|||||||
server.enqueue(new MockResponse().setResponseCode(500));
|
server.enqueue(new MockResponse().setResponseCode(500));
|
||||||
server.enqueue(new MockResponse().setBody(invalidTokenResponse));
|
server.enqueue(new MockResponse().setBody(invalidTokenResponse));
|
||||||
server.enqueue(new MockResponse().setBody(invalidTokenResponse2));
|
server.enqueue(new MockResponse().setBody(invalidTokenResponse2));
|
||||||
|
server.enqueue(new MockResponse().setBody(invalidVersionsResponse));
|
||||||
|
server.enqueue(new MockResponse().setBody(invalidVersionsResponse2));
|
||||||
|
server.enqueue(new MockResponse().setBody(invalidVersionsResponse3));
|
||||||
server.start();
|
server.start();
|
||||||
String baseUrl = getBaseUrl(server);
|
String baseUrl = getBaseUrl(server);
|
||||||
MailboxProperties properties =
|
MailboxProperties properties =
|
||||||
new MailboxProperties(baseUrl, token, true);
|
new MailboxProperties(baseUrl, token, true, new ArrayList<>());
|
||||||
MailboxProperties properties2 =
|
MailboxProperties properties2 =
|
||||||
new MailboxProperties(baseUrl, token2, true);
|
new MailboxProperties(baseUrl, token2, true, new ArrayList<>());
|
||||||
|
|
||||||
// valid response with valid token
|
// valid response with valid token
|
||||||
assertEquals(token2, api.setup(properties));
|
mailboxPropertiesEqual(properties2, api.setup(properties));
|
||||||
RecordedRequest request1 = server.takeRequest();
|
RecordedRequest request1 = server.takeRequest();
|
||||||
assertEquals("/setup", request1.getPath());
|
assertEquals("/setup", request1.getPath());
|
||||||
assertEquals("PUT", request1.getMethod());
|
assertEquals("PUT", request1.getMethod());
|
||||||
@@ -149,12 +162,38 @@ public class MailboxApiTest extends BrambleTestCase {
|
|||||||
assertEquals("/setup", request7.getPath());
|
assertEquals("/setup", request7.getPath());
|
||||||
assertEquals("PUT", request7.getMethod());
|
assertEquals("PUT", request7.getMethod());
|
||||||
assertToken(request7, token);
|
assertToken(request7, token);
|
||||||
|
|
||||||
|
// invalid non-array serverSupports response
|
||||||
|
assertThrows(ApiException.class, () -> api.setup(properties));
|
||||||
|
RecordedRequest request8 = server.takeRequest();
|
||||||
|
assertEquals("/setup", request8.getPath());
|
||||||
|
assertEquals("PUT", request8.getMethod());
|
||||||
|
assertToken(request8, token);
|
||||||
|
|
||||||
|
// invalid non-object in serverSupports array response
|
||||||
|
assertThrows(ApiException.class, () -> api.setup(properties));
|
||||||
|
RecordedRequest request9 = server.takeRequest();
|
||||||
|
assertEquals("/setup", request9.getPath());
|
||||||
|
assertEquals("PUT", request9.getMethod());
|
||||||
|
assertToken(request9, token);
|
||||||
|
|
||||||
|
// invalid negative minor version in serverSupports response
|
||||||
|
assertThrows(ApiException.class, () -> api.setup(properties));
|
||||||
|
RecordedRequest request10 = server.takeRequest();
|
||||||
|
assertEquals("/setup", request10.getPath());
|
||||||
|
assertEquals("PUT", request10.getMethod());
|
||||||
|
assertToken(request10, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String makeSetupResponse(String token, String versions) {
|
||||||
|
return "{\"token\":" + token + "," +
|
||||||
|
"\"serverSupports\":" + versions + "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSetupOnlyForOwner() {
|
public void testSetupOnlyForOwner() {
|
||||||
MailboxProperties properties =
|
MailboxProperties properties =
|
||||||
new MailboxProperties("", token, false);
|
new MailboxProperties("", token, false, new ArrayList<>());
|
||||||
assertThrows(
|
assertThrows(
|
||||||
IllegalArgumentException.class,
|
IllegalArgumentException.class,
|
||||||
() -> api.setup(properties)
|
() -> api.setup(properties)
|
||||||
@@ -170,9 +209,9 @@ public class MailboxApiTest extends BrambleTestCase {
|
|||||||
server.start();
|
server.start();
|
||||||
String baseUrl = getBaseUrl(server);
|
String baseUrl = getBaseUrl(server);
|
||||||
MailboxProperties properties =
|
MailboxProperties properties =
|
||||||
new MailboxProperties(baseUrl, token, true);
|
new MailboxProperties(baseUrl, token, true, new ArrayList<>());
|
||||||
MailboxProperties properties2 =
|
MailboxProperties properties2 =
|
||||||
new MailboxProperties(baseUrl, token2, true);
|
new MailboxProperties(baseUrl, token2, true, new ArrayList<>());
|
||||||
|
|
||||||
assertTrue(api.checkStatus(properties));
|
assertTrue(api.checkStatus(properties));
|
||||||
RecordedRequest request1 = server.takeRequest();
|
RecordedRequest request1 = server.takeRequest();
|
||||||
@@ -193,7 +232,7 @@ public class MailboxApiTest extends BrambleTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testStatusOnlyForOwner() {
|
public void testStatusOnlyForOwner() {
|
||||||
MailboxProperties properties =
|
MailboxProperties properties =
|
||||||
new MailboxProperties("", token, false);
|
new MailboxProperties("", token, false, new ArrayList<>());
|
||||||
assertThrows(
|
assertThrows(
|
||||||
IllegalArgumentException.class,
|
IllegalArgumentException.class,
|
||||||
() -> api.checkStatus(properties)
|
() -> api.checkStatus(properties)
|
||||||
@@ -210,9 +249,9 @@ public class MailboxApiTest extends BrambleTestCase {
|
|||||||
server.start();
|
server.start();
|
||||||
String baseUrl = getBaseUrl(server);
|
String baseUrl = getBaseUrl(server);
|
||||||
MailboxProperties properties =
|
MailboxProperties properties =
|
||||||
new MailboxProperties(baseUrl, token, true);
|
new MailboxProperties(baseUrl, token, true, new ArrayList<>());
|
||||||
MailboxProperties properties2 =
|
MailboxProperties properties2 =
|
||||||
new MailboxProperties(baseUrl, token2, true);
|
new MailboxProperties(baseUrl, token2, true, new ArrayList<>());
|
||||||
|
|
||||||
api.wipeMailbox(properties);
|
api.wipeMailbox(properties);
|
||||||
RecordedRequest request1 = server.takeRequest();
|
RecordedRequest request1 = server.takeRequest();
|
||||||
@@ -242,7 +281,7 @@ public class MailboxApiTest extends BrambleTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testWipeOnlyForOwner() {
|
public void testWipeOnlyForOwner() {
|
||||||
MailboxProperties properties =
|
MailboxProperties properties =
|
||||||
new MailboxProperties("", token, false);
|
new MailboxProperties("", token, false, new ArrayList<>());
|
||||||
assertThrows(IllegalArgumentException.class, () ->
|
assertThrows(IllegalArgumentException.class, () ->
|
||||||
api.wipeMailbox(properties));
|
api.wipeMailbox(properties));
|
||||||
}
|
}
|
||||||
@@ -256,7 +295,7 @@ public class MailboxApiTest extends BrambleTestCase {
|
|||||||
server.start();
|
server.start();
|
||||||
String baseUrl = getBaseUrl(server);
|
String baseUrl = getBaseUrl(server);
|
||||||
MailboxProperties properties =
|
MailboxProperties properties =
|
||||||
new MailboxProperties(baseUrl, token, true);
|
new MailboxProperties(baseUrl, token, true, new ArrayList<>());
|
||||||
|
|
||||||
// contact gets added as expected
|
// contact gets added as expected
|
||||||
api.addContact(properties, mailboxContact);
|
api.addContact(properties, mailboxContact);
|
||||||
@@ -288,7 +327,7 @@ public class MailboxApiTest extends BrambleTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testAddContactOnlyForOwner() {
|
public void testAddContactOnlyForOwner() {
|
||||||
MailboxProperties properties =
|
MailboxProperties properties =
|
||||||
new MailboxProperties("", token, false);
|
new MailboxProperties("", token, false, new ArrayList<>());
|
||||||
assertThrows(IllegalArgumentException.class, () ->
|
assertThrows(IllegalArgumentException.class, () ->
|
||||||
api.addContact(properties, mailboxContact));
|
api.addContact(properties, mailboxContact));
|
||||||
}
|
}
|
||||||
@@ -303,7 +342,7 @@ public class MailboxApiTest extends BrambleTestCase {
|
|||||||
server.start();
|
server.start();
|
||||||
String baseUrl = getBaseUrl(server);
|
String baseUrl = getBaseUrl(server);
|
||||||
MailboxProperties properties =
|
MailboxProperties properties =
|
||||||
new MailboxProperties(baseUrl, token, true);
|
new MailboxProperties(baseUrl, token, true, new ArrayList<>());
|
||||||
|
|
||||||
// contact gets deleted as expected
|
// contact gets deleted as expected
|
||||||
api.deleteContact(properties, contactId);
|
api.deleteContact(properties, contactId);
|
||||||
@@ -340,7 +379,7 @@ public class MailboxApiTest extends BrambleTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testDeleteContactOnlyForOwner() {
|
public void testDeleteContactOnlyForOwner() {
|
||||||
MailboxProperties properties =
|
MailboxProperties properties =
|
||||||
new MailboxProperties("", token, false);
|
new MailboxProperties("", token, false, new ArrayList<>());
|
||||||
assertThrows(IllegalArgumentException.class, () ->
|
assertThrows(IllegalArgumentException.class, () ->
|
||||||
api.deleteContact(properties, contactId));
|
api.deleteContact(properties, contactId));
|
||||||
}
|
}
|
||||||
@@ -367,7 +406,7 @@ public class MailboxApiTest extends BrambleTestCase {
|
|||||||
server.start();
|
server.start();
|
||||||
String baseUrl = getBaseUrl(server);
|
String baseUrl = getBaseUrl(server);
|
||||||
MailboxProperties properties =
|
MailboxProperties properties =
|
||||||
new MailboxProperties(baseUrl, token, true);
|
new MailboxProperties(baseUrl, token, true, new ArrayList<>());
|
||||||
|
|
||||||
// valid response with two contacts
|
// valid response with two contacts
|
||||||
assertEquals(singletonList(contactId), api.getContacts(properties));
|
assertEquals(singletonList(contactId), api.getContacts(properties));
|
||||||
@@ -432,7 +471,7 @@ public class MailboxApiTest extends BrambleTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testGetContactsOnlyForOwner() {
|
public void testGetContactsOnlyForOwner() {
|
||||||
MailboxProperties properties =
|
MailboxProperties properties =
|
||||||
new MailboxProperties("", token, false);
|
new MailboxProperties("", token, false, new ArrayList<>());
|
||||||
assertThrows(
|
assertThrows(
|
||||||
IllegalArgumentException.class,
|
IllegalArgumentException.class,
|
||||||
() -> api.getContacts(properties)
|
() -> api.getContacts(properties)
|
||||||
@@ -452,7 +491,7 @@ public class MailboxApiTest extends BrambleTestCase {
|
|||||||
server.start();
|
server.start();
|
||||||
String baseUrl = getBaseUrl(server);
|
String baseUrl = getBaseUrl(server);
|
||||||
MailboxProperties properties =
|
MailboxProperties properties =
|
||||||
new MailboxProperties(baseUrl, token, true);
|
new MailboxProperties(baseUrl, token, true, new ArrayList<>());
|
||||||
|
|
||||||
// file gets uploaded as expected
|
// file gets uploaded as expected
|
||||||
api.addFile(properties, contactInboxId, file);
|
api.addFile(properties, contactInboxId, file);
|
||||||
@@ -511,7 +550,7 @@ public class MailboxApiTest extends BrambleTestCase {
|
|||||||
server.start();
|
server.start();
|
||||||
String baseUrl = getBaseUrl(server);
|
String baseUrl = getBaseUrl(server);
|
||||||
MailboxProperties properties =
|
MailboxProperties properties =
|
||||||
new MailboxProperties(baseUrl, token, true);
|
new MailboxProperties(baseUrl, token, true, new ArrayList<>());
|
||||||
|
|
||||||
// valid response with one file
|
// valid response with one file
|
||||||
List<MailboxFile> received1 = api.getFiles(properties, contactInboxId);
|
List<MailboxFile> received1 = api.getFiles(properties, contactInboxId);
|
||||||
@@ -607,7 +646,7 @@ public class MailboxApiTest extends BrambleTestCase {
|
|||||||
server.start();
|
server.start();
|
||||||
String baseUrl = getBaseUrl(server);
|
String baseUrl = getBaseUrl(server);
|
||||||
MailboxProperties properties =
|
MailboxProperties properties =
|
||||||
new MailboxProperties(baseUrl, token, true);
|
new MailboxProperties(baseUrl, token, true, new ArrayList<>());
|
||||||
|
|
||||||
// file gets downloaded as expected
|
// file gets downloaded as expected
|
||||||
api.getFile(properties, contactOutboxId, name, file1);
|
api.getFile(properties, contactOutboxId, name, file1);
|
||||||
@@ -651,7 +690,7 @@ public class MailboxApiTest extends BrambleTestCase {
|
|||||||
server.start();
|
server.start();
|
||||||
String baseUrl = getBaseUrl(server);
|
String baseUrl = getBaseUrl(server);
|
||||||
MailboxProperties properties =
|
MailboxProperties properties =
|
||||||
new MailboxProperties(baseUrl, token, true);
|
new MailboxProperties(baseUrl, token, true, new ArrayList<>());
|
||||||
|
|
||||||
// file gets deleted as expected
|
// file gets deleted as expected
|
||||||
api.deleteFile(properties, contactInboxId, name);
|
api.deleteFile(properties, contactInboxId, name);
|
||||||
@@ -715,7 +754,7 @@ public class MailboxApiTest extends BrambleTestCase {
|
|||||||
server.start();
|
server.start();
|
||||||
String baseUrl = getBaseUrl(server);
|
String baseUrl = getBaseUrl(server);
|
||||||
MailboxProperties properties =
|
MailboxProperties properties =
|
||||||
new MailboxProperties(baseUrl, token, true);
|
new MailboxProperties(baseUrl, token, true, new ArrayList<>());
|
||||||
|
|
||||||
// valid response with one folders
|
// valid response with one folders
|
||||||
assertEquals(singletonList(id1), api.getFolders(properties));
|
assertEquals(singletonList(id1), api.getFolders(properties));
|
||||||
@@ -784,7 +823,7 @@ public class MailboxApiTest extends BrambleTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testGetFoldersOnlyForOwner() {
|
public void testGetFoldersOnlyForOwner() {
|
||||||
MailboxProperties properties =
|
MailboxProperties properties =
|
||||||
new MailboxProperties("", token, false);
|
new MailboxProperties("", token, false, new ArrayList<>());
|
||||||
assertThrows(IllegalArgumentException.class, () ->
|
assertThrows(IllegalArgumentException.class, () ->
|
||||||
api.getFolders(properties));
|
api.getFolders(properties));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import org.junit.rules.TemporaryFolder;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -89,17 +90,16 @@ public class MailboxIntegrationTest extends BrambleTestCase {
|
|||||||
assumeTrue(isOptionalTestEnabled(MailboxIntegrationTest.class));
|
assumeTrue(isOptionalTestEnabled(MailboxIntegrationTest.class));
|
||||||
|
|
||||||
if (ownerProperties != null) return;
|
if (ownerProperties != null) return;
|
||||||
MailboxProperties setupProperties =
|
MailboxProperties setupProperties = new MailboxProperties(
|
||||||
new MailboxProperties(URL_BASE, SETUP_TOKEN, true);
|
URL_BASE, SETUP_TOKEN, true, new ArrayList<>());
|
||||||
MailboxAuthToken ownerToken = api.setup(setupProperties);
|
ownerProperties = api.setup(setupProperties);
|
||||||
ownerProperties = new MailboxProperties(URL_BASE, ownerToken, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
// we can't test wiping as a regular test as it stops the mailbox
|
// we can't test wiping as a regular test as it stops the mailbox
|
||||||
public static void wipe() throws IOException, ApiException {
|
public static void wipe() throws IOException, ApiException {
|
||||||
if (!isOptionalTestEnabled(MailboxIntegrationTest.class)) return;
|
if (!isOptionalTestEnabled(MailboxIntegrationTest.class)) return;
|
||||||
|
|
||||||
api.wipeMailbox(ownerProperties);
|
api.wipeMailbox(ownerProperties);
|
||||||
|
|
||||||
// check doesn't work anymore
|
// check doesn't work anymore
|
||||||
@@ -107,8 +107,8 @@ public class MailboxIntegrationTest extends BrambleTestCase {
|
|||||||
api.checkStatus(ownerProperties));
|
api.checkStatus(ownerProperties));
|
||||||
|
|
||||||
// new setup doesn't work as mailbox is stopping
|
// new setup doesn't work as mailbox is stopping
|
||||||
MailboxProperties setupProperties =
|
MailboxProperties setupProperties = new MailboxProperties(
|
||||||
new MailboxProperties(URL_BASE, SETUP_TOKEN, true);
|
URL_BASE, SETUP_TOKEN, true, new ArrayList<>());
|
||||||
assertThrows(ApiException.class, () -> api.setup(setupProperties));
|
assertThrows(ApiException.class, () -> api.setup(setupProperties));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +151,8 @@ public class MailboxIntegrationTest extends BrambleTestCase {
|
|||||||
ContactId contactId = new ContactId(1);
|
ContactId contactId = new ContactId(1);
|
||||||
MailboxContact contact = getMailboxContact(contactId);
|
MailboxContact contact = getMailboxContact(contactId);
|
||||||
MailboxProperties contactProperties = new MailboxProperties(
|
MailboxProperties contactProperties = new MailboxProperties(
|
||||||
ownerProperties.getBaseUrl(), contact.token, false);
|
ownerProperties.getBaseUrl(), contact.token, false,
|
||||||
|
new ArrayList<>());
|
||||||
api.addContact(ownerProperties, contact);
|
api.addContact(ownerProperties, contact);
|
||||||
|
|
||||||
// upload a file for our contact
|
// upload a file for our contact
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import org.junit.Test;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
@@ -61,10 +62,10 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
|
|||||||
new MailboxAuthToken(getRandomId());
|
new MailboxAuthToken(getRandomId());
|
||||||
private final String validPayload = getValidPayload();
|
private final String validPayload = getValidPayload();
|
||||||
private final long time = System.currentTimeMillis();
|
private final long time = System.currentTimeMillis();
|
||||||
private final MailboxProperties setupProperties =
|
private final MailboxProperties setupProperties = new MailboxProperties(
|
||||||
new MailboxProperties(onionAddress, setupToken, true);
|
onionAddress, setupToken, true, new ArrayList<>());
|
||||||
private final MailboxProperties ownerProperties =
|
private final MailboxProperties ownerProperties = new MailboxProperties(
|
||||||
new MailboxProperties(onionAddress, ownerToken, true);
|
onionAddress, ownerToken, true, new ArrayList<>());
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInitialQrCodeReceivedState() {
|
public void testInitialQrCodeReceivedState() {
|
||||||
@@ -98,7 +99,7 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(crypto).encodeOnion(onionBytes);
|
oneOf(crypto).encodeOnion(onionBytes);
|
||||||
will(returnValue(onion));
|
will(returnValue(onion));
|
||||||
oneOf(api).setup(with(matches(setupProperties)));
|
oneOf(api).setup(with(matches(setupProperties)));
|
||||||
will(returnValue(ownerToken));
|
will(returnValue(ownerProperties));
|
||||||
oneOf(clock).currentTimeMillis();
|
oneOf(clock).currentTimeMillis();
|
||||||
will(returnValue(time));
|
will(returnValue(time));
|
||||||
}});
|
}});
|
||||||
@@ -174,7 +175,7 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(crypto).encodeOnion(onionBytes);
|
oneOf(crypto).encodeOnion(onionBytes);
|
||||||
will(returnValue(onion));
|
will(returnValue(onion));
|
||||||
oneOf(api).setup(with(matches(setupProperties)));
|
oneOf(api).setup(with(matches(setupProperties)));
|
||||||
will(returnValue(ownerToken));
|
will(returnValue(ownerProperties));
|
||||||
oneOf(clock).currentTimeMillis();
|
oneOf(clock).currentTimeMillis();
|
||||||
will(returnValue(time));
|
will(returnValue(time));
|
||||||
}});
|
}});
|
||||||
@@ -206,7 +207,8 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
|
|||||||
return new PredicateMatcher<>(MailboxProperties.class, p1 ->
|
return new PredicateMatcher<>(MailboxProperties.class, p1 ->
|
||||||
p1.getAuthToken().equals(p2.getAuthToken()) &&
|
p1.getAuthToken().equals(p2.getAuthToken()) &&
|
||||||
p1.getBaseUrl().equals(p2.getBaseUrl()) &&
|
p1.getBaseUrl().equals(p2.getBaseUrl()) &&
|
||||||
p1.isOwner() == p2.isOwner());
|
p1.isOwner() == p2.isOwner() &&
|
||||||
|
p1.getServerSupports().equals(p2.getServerSupports()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import org.briarproject.bramble.test.BrambleMockTestCase;
|
|||||||
import org.jmock.Expectations;
|
import org.jmock.Expectations;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -76,7 +77,7 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
|
|
||||||
public MailboxPropertyManagerImplTest() {
|
public MailboxPropertyManagerImplTest() {
|
||||||
ownProps = new MailboxProperties("http://bar.onion",
|
ownProps = new MailboxProperties("http://bar.onion",
|
||||||
new MailboxAuthToken(getRandomId()), true);
|
new MailboxAuthToken(getRandomId()), true, new ArrayList<>());
|
||||||
props = new MailboxPropertiesUpdate(ownProps.getOnion(),
|
props = new MailboxPropertiesUpdate(ownProps.getOnion(),
|
||||||
new MailboxAuthToken(getRandomId()),
|
new MailboxAuthToken(getRandomId()),
|
||||||
new MailboxFolderId(getRandomId()),
|
new MailboxFolderId(getRandomId()),
|
||||||
@@ -281,6 +282,7 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
public void testDoesNotDeleteAnythingWhenFirstUpdateIsDelivered()
|
public void testDoesNotDeleteAnythingWhenFirstUpdateIsDelivered()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
Transaction txn = new Transaction(null, false);
|
Transaction txn = new Transaction(null, false);
|
||||||
|
Contact contact = getContact();
|
||||||
GroupId contactGroupId = new GroupId(getRandomId());
|
GroupId contactGroupId = new GroupId(getRandomId());
|
||||||
Message message = getMessage(contactGroupId);
|
Message message = getMessage(contactGroupId);
|
||||||
BdfList body = BdfList.of(1, propsDict);
|
BdfList body = BdfList.of(1, propsDict);
|
||||||
@@ -304,11 +306,13 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
contactGroupId);
|
contactGroupId);
|
||||||
will(returnValue(messageMetadata));
|
will(returnValue(messageMetadata));
|
||||||
oneOf(clientHelper).getContactId(txn, contactGroupId);
|
oneOf(clientHelper).getContactId(txn, contactGroupId);
|
||||||
|
will(returnValue(contact.getId()));
|
||||||
oneOf(clientHelper).getMessageAsList(txn, message.getId());
|
oneOf(clientHelper).getMessageAsList(txn, message.getId());
|
||||||
will(returnValue(body));
|
will(returnValue(body));
|
||||||
oneOf(clientHelper).parseAndValidateMailboxPropertiesUpdate(
|
oneOf(clientHelper).parseAndValidateMailboxPropertiesUpdate(
|
||||||
propsDict);
|
propsDict);
|
||||||
will(returnValue(props));
|
will(returnValue(props));
|
||||||
|
oneOf(db).resetUnackedMessagesToSend(txn, contact.getId());
|
||||||
}});
|
}});
|
||||||
|
|
||||||
MailboxPropertyManagerImpl t = createInstance();
|
MailboxPropertyManagerImpl t = createInstance();
|
||||||
@@ -321,6 +325,7 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
public void testDeletesOlderUpdateWhenUpdateIsDelivered()
|
public void testDeletesOlderUpdateWhenUpdateIsDelivered()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
Transaction txn = new Transaction(null, false);
|
Transaction txn = new Transaction(null, false);
|
||||||
|
Contact contact = getContact();
|
||||||
GroupId contactGroupId = new GroupId(getRandomId());
|
GroupId contactGroupId = new GroupId(getRandomId());
|
||||||
Message message = getMessage(contactGroupId);
|
Message message = getMessage(contactGroupId);
|
||||||
BdfList body = BdfList.of(1, propsDict);
|
BdfList body = BdfList.of(1, propsDict);
|
||||||
@@ -352,11 +357,13 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(db).deleteMessage(txn, updateId);
|
oneOf(db).deleteMessage(txn, updateId);
|
||||||
oneOf(db).deleteMessageMetadata(txn, updateId);
|
oneOf(db).deleteMessageMetadata(txn, updateId);
|
||||||
oneOf(clientHelper).getContactId(txn, contactGroupId);
|
oneOf(clientHelper).getContactId(txn, contactGroupId);
|
||||||
|
will(returnValue(contact.getId()));
|
||||||
oneOf(clientHelper).getMessageAsList(txn, message.getId());
|
oneOf(clientHelper).getMessageAsList(txn, message.getId());
|
||||||
will(returnValue(body));
|
will(returnValue(body));
|
||||||
oneOf(clientHelper).parseAndValidateMailboxPropertiesUpdate(
|
oneOf(clientHelper).parseAndValidateMailboxPropertiesUpdate(
|
||||||
propsDict);
|
propsDict);
|
||||||
will(returnValue(props));
|
will(returnValue(props));
|
||||||
|
oneOf(db).resetUnackedMessagesToSend(txn, contact.getId());
|
||||||
}});
|
}});
|
||||||
|
|
||||||
MailboxPropertyManagerImpl t = createInstance();
|
MailboxPropertyManagerImpl t = createInstance();
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import org.briarproject.bramble.api.mailbox.MailboxAuthToken;
|
|||||||
import org.briarproject.bramble.api.mailbox.MailboxProperties;
|
import org.briarproject.bramble.api.mailbox.MailboxProperties;
|
||||||
import org.briarproject.bramble.api.mailbox.MailboxSettingsManager;
|
import org.briarproject.bramble.api.mailbox.MailboxSettingsManager;
|
||||||
import org.briarproject.bramble.api.mailbox.MailboxStatus;
|
import org.briarproject.bramble.api.mailbox.MailboxStatus;
|
||||||
|
import org.briarproject.bramble.api.mailbox.MailboxVersion;
|
||||||
import org.briarproject.bramble.api.mailbox.OwnMailboxConnectionStatusEvent;
|
import org.briarproject.bramble.api.mailbox.OwnMailboxConnectionStatusEvent;
|
||||||
import org.briarproject.bramble.api.settings.Settings;
|
import org.briarproject.bramble.api.settings.Settings;
|
||||||
import org.briarproject.bramble.api.settings.SettingsManager;
|
import org.briarproject.bramble.api.settings.SettingsManager;
|
||||||
@@ -13,12 +14,15 @@ import org.briarproject.bramble.test.BrambleMockTestCase;
|
|||||||
import org.jmock.Expectations;
|
import org.jmock.Expectations;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_KEY_ATTEMPTS;
|
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_KEY_ATTEMPTS;
|
||||||
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_KEY_LAST_ATTEMPT;
|
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_KEY_LAST_ATTEMPT;
|
||||||
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_KEY_LAST_SUCCESS;
|
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_KEY_LAST_SUCCESS;
|
||||||
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_KEY_ONION;
|
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_KEY_ONION;
|
||||||
|
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_KEY_SERVER_SUPPORTS;
|
||||||
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_KEY_TOKEN;
|
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_KEY_TOKEN;
|
||||||
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_NAMESPACE;
|
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_NAMESPACE;
|
||||||
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_UPLOADS_NAMESPACE;
|
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_UPLOADS_NAMESPACE;
|
||||||
@@ -40,6 +44,9 @@ public class MailboxSettingsManagerImplTest extends BrambleMockTestCase {
|
|||||||
private final Random random = new Random();
|
private final Random random = new Random();
|
||||||
private final String onion = getRandomString(64);
|
private final String onion = getRandomString(64);
|
||||||
private final MailboxAuthToken token = new MailboxAuthToken(getRandomId());
|
private final MailboxAuthToken token = new MailboxAuthToken(getRandomId());
|
||||||
|
private final List<MailboxVersion> serverSupports =
|
||||||
|
asList(new MailboxVersion(1, 0), new MailboxVersion(1, 1));
|
||||||
|
private final int[] serverSupportsInts = {1, 0, 1, 1};
|
||||||
private final ContactId contactId1 = new ContactId(random.nextInt());
|
private final ContactId contactId1 = new ContactId(random.nextInt());
|
||||||
private final ContactId contactId2 = new ContactId(random.nextInt());
|
private final ContactId contactId2 = new ContactId(random.nextInt());
|
||||||
private final ContactId contactId3 = new ContactId(random.nextInt());
|
private final ContactId contactId3 = new ContactId(random.nextInt());
|
||||||
@@ -67,6 +74,7 @@ public class MailboxSettingsManagerImplTest extends BrambleMockTestCase {
|
|||||||
Settings settings = new Settings();
|
Settings settings = new Settings();
|
||||||
settings.put(SETTINGS_KEY_ONION, onion);
|
settings.put(SETTINGS_KEY_ONION, onion);
|
||||||
settings.put(SETTINGS_KEY_TOKEN, token.toString());
|
settings.put(SETTINGS_KEY_TOKEN, token.toString());
|
||||||
|
settings.putIntArray(SETTINGS_KEY_SERVER_SUPPORTS, serverSupportsInts);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(settingsManager).getSettings(txn, SETTINGS_NAMESPACE);
|
oneOf(settingsManager).getSettings(txn, SETTINGS_NAMESPACE);
|
||||||
@@ -77,6 +85,7 @@ public class MailboxSettingsManagerImplTest extends BrambleMockTestCase {
|
|||||||
assertNotNull(properties);
|
assertNotNull(properties);
|
||||||
assertEquals(onion, properties.getBaseUrl());
|
assertEquals(onion, properties.getBaseUrl());
|
||||||
assertEquals(token, properties.getAuthToken());
|
assertEquals(token, properties.getAuthToken());
|
||||||
|
assertEquals(serverSupports, properties.getServerSupports());
|
||||||
assertTrue(properties.isOwner());
|
assertTrue(properties.isOwner());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,8 +95,10 @@ public class MailboxSettingsManagerImplTest extends BrambleMockTestCase {
|
|||||||
Settings expectedSettings = new Settings();
|
Settings expectedSettings = new Settings();
|
||||||
expectedSettings.put(SETTINGS_KEY_ONION, onion);
|
expectedSettings.put(SETTINGS_KEY_ONION, onion);
|
||||||
expectedSettings.put(SETTINGS_KEY_TOKEN, token.toString());
|
expectedSettings.put(SETTINGS_KEY_TOKEN, token.toString());
|
||||||
MailboxProperties properties =
|
expectedSettings.putIntArray(SETTINGS_KEY_SERVER_SUPPORTS,
|
||||||
new MailboxProperties(onion, token, true);
|
serverSupportsInts);
|
||||||
|
MailboxProperties properties = new MailboxProperties(onion, token, true,
|
||||||
|
serverSupports);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(settingsManager).mergeSettings(txn, expectedSettings,
|
oneOf(settingsManager).mergeSettings(txn, expectedSettings,
|
||||||
|
|||||||
@@ -47,11 +47,11 @@ public class MailboxActivity extends BriarActivity {
|
|||||||
setContentView(R.layout.activity_mailbox);
|
setContentView(R.layout.activity_mailbox);
|
||||||
|
|
||||||
progressBar = findViewById(R.id.progressBar);
|
progressBar = findViewById(R.id.progressBar);
|
||||||
if (viewModel.getState().getValue() == null) {
|
if (viewModel.getPairingState().getValue() == null) {
|
||||||
progressBar.setVisibility(VISIBLE);
|
progressBar.setVisibility(VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.getState().observeEvent(this, state -> {
|
viewModel.getPairingState().observeEvent(this, state -> {
|
||||||
if (state instanceof MailboxState.NotSetup) {
|
if (state instanceof MailboxState.NotSetup) {
|
||||||
onNotSetup();
|
onNotSetup();
|
||||||
} else if (state instanceof MailboxState.ShowDownload) {
|
} else if (state instanceof MailboxState.ShowDownload) {
|
||||||
@@ -67,7 +67,7 @@ public class MailboxActivity extends BriarActivity {
|
|||||||
} else if (state instanceof MailboxState.CameraError) {
|
} else if (state instanceof MailboxState.CameraError) {
|
||||||
onCameraError();
|
onCameraError();
|
||||||
} else if (state instanceof MailboxState.IsPaired) {
|
} else if (state instanceof MailboxState.IsPaired) {
|
||||||
onIsPaired();
|
onIsPaired(((MailboxState.IsPaired) state).isOnline);
|
||||||
} else {
|
} else {
|
||||||
throw new AssertionError("Unknown state: " + state);
|
throw new AssertionError("Unknown state: " + state);
|
||||||
}
|
}
|
||||||
@@ -85,7 +85,7 @@ public class MailboxActivity extends BriarActivity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
MailboxState s = viewModel.getState().getLastValue();
|
MailboxState s = viewModel.getPairingState().getLastValue();
|
||||||
if (s instanceof MailboxState.Pairing) {
|
if (s instanceof MailboxState.Pairing) {
|
||||||
// don't go back in the flow if we are already pairing
|
// don't go back in the flow if we are already pairing
|
||||||
// with the mailbox. We provide a try-again button instead.
|
// with the mailbox. We provide a try-again button instead.
|
||||||
@@ -181,10 +181,13 @@ public class MailboxActivity extends BriarActivity {
|
|||||||
showFragment(getSupportFragmentManager(), f, ErrorFragment.TAG);
|
showFragment(getSupportFragmentManager(), f, ErrorFragment.TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onIsPaired() {
|
private void onIsPaired(boolean isOnline) {
|
||||||
progressBar.setVisibility(INVISIBLE);
|
progressBar.setVisibility(INVISIBLE);
|
||||||
showFragment(getSupportFragmentManager(), new MailboxStatusFragment(),
|
Fragment f = isOnline ?
|
||||||
MailboxStatusFragment.TAG, false);
|
new MailboxStatusFragment() : new OfflineStatusFragment();
|
||||||
|
String tag = isOnline ?
|
||||||
|
MailboxStatusFragment.TAG : OfflineStatusFragment.TAG;
|
||||||
|
showFragment(getSupportFragmentManager(), f, tag, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package org.briarproject.briar.android.mailbox;
|
package org.briarproject.briar.android.mailbox;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState;
|
import org.briarproject.bramble.api.mailbox.MailboxPairingState;
|
||||||
import org.briarproject.bramble.api.mailbox.MailboxStatus;
|
|
||||||
|
|
||||||
class MailboxState {
|
class MailboxState {
|
||||||
|
|
||||||
@@ -29,10 +28,10 @@ class MailboxState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static class IsPaired extends MailboxState {
|
static class IsPaired extends MailboxState {
|
||||||
final MailboxStatus mailboxStatus;
|
final boolean isOnline;
|
||||||
|
|
||||||
IsPaired(MailboxStatus mailboxStatus) {
|
IsPaired(boolean isOnline) {
|
||||||
this.mailboxStatus = mailboxStatus;
|
this.isOnline = isOnline;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,37 +1,62 @@
|
|||||||
package org.briarproject.briar.android.mailbox;
|
package org.briarproject.briar.android.mailbox;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.res.ColorStateList;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.mailbox.MailboxStatus;
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import androidx.annotation.ColorRes;
|
||||||
|
import androidx.annotation.DrawableRes;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.UiThread;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
import static java.util.Objects.requireNonNull;
|
import static android.view.View.INVISIBLE;
|
||||||
|
import static android.view.View.VISIBLE;
|
||||||
|
import static androidx.core.content.ContextCompat.getColor;
|
||||||
|
import static androidx.core.widget.ImageViewCompat.setImageTintList;
|
||||||
|
import static androidx.transition.TransitionManager.beginDelayedTransition;
|
||||||
import static org.briarproject.briar.android.AppModule.getAndroidComponent;
|
import static org.briarproject.briar.android.AppModule.getAndroidComponent;
|
||||||
|
import static org.briarproject.briar.android.util.UiUtils.MIN_DATE_RESOLUTION;
|
||||||
import static org.briarproject.briar.android.util.UiUtils.formatDate;
|
import static org.briarproject.briar.android.util.UiUtils.formatDate;
|
||||||
|
import static org.briarproject.briar.android.util.UiUtils.observeOnce;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
public class MailboxStatusFragment extends Fragment {
|
public class MailboxStatusFragment extends Fragment {
|
||||||
|
|
||||||
static final String TAG = MailboxStatusFragment.class.getName();
|
static final String TAG = MailboxStatusFragment.class.getName();
|
||||||
|
private static final int NUM_FAILURES = 4;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ViewModelProvider.Factory viewModelFactory;
|
ViewModelProvider.Factory viewModelFactory;
|
||||||
|
|
||||||
private MailboxViewModel viewModel;
|
private MailboxViewModel viewModel;
|
||||||
|
private final Handler handler = new Handler(Looper.getMainLooper());
|
||||||
|
@Nullable // UiThread
|
||||||
|
private Runnable refresher = null;
|
||||||
|
|
||||||
|
private ImageView imageView;
|
||||||
|
private TextView statusTitleView;
|
||||||
|
private TextView statusInfoView;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Context context) {
|
public void onAttach(Context context) {
|
||||||
@@ -54,11 +79,72 @@ public class MailboxStatusFragment extends Fragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onViewCreated(View v, @Nullable Bundle savedInstanceState) {
|
public void onViewCreated(View v, @Nullable Bundle savedInstanceState) {
|
||||||
super.onViewCreated(v, savedInstanceState);
|
super.onViewCreated(v, savedInstanceState);
|
||||||
MailboxState.IsPaired state =
|
|
||||||
(MailboxState.IsPaired) viewModel.getState().getLastValue();
|
Button checkButton = v.findViewById(R.id.checkButton);
|
||||||
requireNonNull(state); // TODO check assumption
|
ProgressBar checkProgress = v.findViewById(R.id.checkProgress);
|
||||||
TextView statusInfoView = v.findViewById(R.id.statusInfoView);
|
checkButton.setOnClickListener(view -> {
|
||||||
long lastSuccess = state.mailboxStatus.getTimeOfLastSuccess();
|
beginDelayedTransition((ViewGroup) v);
|
||||||
|
checkButton.setVisibility(INVISIBLE);
|
||||||
|
checkProgress.setVisibility(VISIBLE);
|
||||||
|
observeOnce(viewModel.checkConnection(), this, result -> {
|
||||||
|
beginDelayedTransition((ViewGroup) v);
|
||||||
|
checkButton.setVisibility(VISIBLE);
|
||||||
|
checkProgress.setVisibility(INVISIBLE);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
imageView = v.findViewById(R.id.imageView);
|
||||||
|
statusTitleView = v.findViewById(R.id.statusTitleView);
|
||||||
|
statusInfoView = v.findViewById(R.id.statusInfoView);
|
||||||
|
viewModel.getStatus()
|
||||||
|
.observe(getViewLifecycleOwner(), this::onMailboxStateChanged);
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// * detect problems and show them #2175
|
||||||
|
// * add "Unlink" button confirmation dialog and functionality #2173
|
||||||
|
Button unlinkButton = v.findViewById(R.id.unlinkButton);
|
||||||
|
unlinkButton.setOnClickListener(view -> Toast.makeText(requireContext(),
|
||||||
|
"NOT IMPLEMENTED", Toast.LENGTH_SHORT).show());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
requireActivity().setTitle(R.string.mailbox_status_title);
|
||||||
|
refresher = this::refreshLastConnection;
|
||||||
|
handler.postDelayed(refresher, MIN_DATE_RESOLUTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
handler.removeCallbacks(refresher);
|
||||||
|
refresher = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onMailboxStateChanged(MailboxStatus status) {
|
||||||
|
@ColorRes int tintRes;
|
||||||
|
@DrawableRes int iconRes;
|
||||||
|
String title;
|
||||||
|
if (status.getAttemptsSinceSuccess() == 0) {
|
||||||
|
iconRes = R.drawable.ic_check_circle_outline;
|
||||||
|
title = getString(R.string.mailbox_status_connected_title);
|
||||||
|
tintRes = R.color.briar_brand_green;
|
||||||
|
} else if (status.getAttemptsSinceSuccess() < NUM_FAILURES) {
|
||||||
|
iconRes = R.drawable.ic_help_outline_white;
|
||||||
|
title = getString(R.string.mailbox_status_problem_title);
|
||||||
|
tintRes = R.color.briar_orange_500;
|
||||||
|
} else {
|
||||||
|
tintRes = R.color.briar_red_500;
|
||||||
|
title = getString(R.string.mailbox_status_failure_title);
|
||||||
|
iconRes = R.drawable.alerts_and_states_error;
|
||||||
|
}
|
||||||
|
imageView.setImageResource(iconRes);
|
||||||
|
int color = getColor(requireContext(), tintRes);
|
||||||
|
setImageTintList(imageView, ColorStateList.valueOf(color));
|
||||||
|
statusTitleView.setText(title);
|
||||||
|
|
||||||
|
long lastSuccess = status.getTimeOfLastSuccess();
|
||||||
String lastConnectionText;
|
String lastConnectionText;
|
||||||
if (lastSuccess < 0) {
|
if (lastSuccess < 0) {
|
||||||
lastConnectionText =
|
lastConnectionText =
|
||||||
@@ -66,21 +152,19 @@ public class MailboxStatusFragment extends Fragment {
|
|||||||
} else {
|
} else {
|
||||||
lastConnectionText = formatDate(requireContext(), lastSuccess);
|
lastConnectionText = formatDate(requireContext(), lastSuccess);
|
||||||
}
|
}
|
||||||
String statusInfoText = getString(
|
String statusInfoText =
|
||||||
R.string.mailbox_status_connected_info, lastConnectionText);
|
getString(R.string.mailbox_status_connected_info,
|
||||||
|
lastConnectionText);
|
||||||
statusInfoView.setText(statusInfoText);
|
statusInfoView.setText(statusInfoText);
|
||||||
// TODO
|
|
||||||
// * react to status changes
|
|
||||||
// * detect problems and show them
|
|
||||||
// * update connection time periodically like conversation timestamps
|
|
||||||
// * add "Check connection" button
|
|
||||||
// * add "Unlink" button with confirmation dialog
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@UiThread
|
||||||
public void onStart() {
|
private void refreshLastConnection() {
|
||||||
super.onStart();
|
MailboxStatus status = viewModel.getStatus().getValue();
|
||||||
requireActivity().setTitle(R.string.mailbox_status_title);
|
if (status != null) onMailboxStateChanged(status);
|
||||||
|
if (refresher != null) {
|
||||||
|
handler.postDelayed(refresher, MIN_DATE_RESOLUTION);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,16 +7,22 @@ import com.google.zxing.Result;
|
|||||||
import org.briarproject.bramble.api.Consumer;
|
import org.briarproject.bramble.api.Consumer;
|
||||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||||
import org.briarproject.bramble.api.db.TransactionManager;
|
import org.briarproject.bramble.api.db.TransactionManager;
|
||||||
|
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.lifecycle.IoExecutor;
|
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.bramble.api.mailbox.MailboxManager;
|
import org.briarproject.bramble.api.mailbox.MailboxManager;
|
||||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState;
|
import org.briarproject.bramble.api.mailbox.MailboxPairingState;
|
||||||
import org.briarproject.bramble.api.mailbox.MailboxPairingTask;
|
import org.briarproject.bramble.api.mailbox.MailboxPairingTask;
|
||||||
import org.briarproject.bramble.api.mailbox.MailboxStatus;
|
import org.briarproject.bramble.api.mailbox.MailboxStatus;
|
||||||
|
import org.briarproject.bramble.api.mailbox.OwnMailboxConnectionStatusEvent;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.Plugin;
|
import org.briarproject.bramble.api.plugin.Plugin;
|
||||||
import org.briarproject.bramble.api.plugin.PluginManager;
|
import org.briarproject.bramble.api.plugin.PluginManager;
|
||||||
import org.briarproject.bramble.api.plugin.TorConstants;
|
import org.briarproject.bramble.api.plugin.TorConstants;
|
||||||
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
|
import org.briarproject.bramble.api.plugin.event.TransportInactiveEvent;
|
||||||
import org.briarproject.bramble.api.system.AndroidExecutor;
|
import org.briarproject.bramble.api.system.AndroidExecutor;
|
||||||
import org.briarproject.briar.android.mailbox.MailboxState.NotSetup;
|
import org.briarproject.briar.android.mailbox.MailboxState.NotSetup;
|
||||||
import org.briarproject.briar.android.qrcode.QrCodeDecoder;
|
import org.briarproject.briar.android.qrcode.QrCodeDecoder;
|
||||||
@@ -32,6 +38,8 @@ import javax.inject.Inject;
|
|||||||
import androidx.annotation.AnyThread;
|
import androidx.annotation.AnyThread;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.UiThread;
|
import androidx.annotation.UiThread;
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
@@ -39,17 +47,22 @@ import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
|
|||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class MailboxViewModel extends DbViewModel
|
class MailboxViewModel extends DbViewModel
|
||||||
implements QrCodeDecoder.ResultCallback, Consumer<MailboxPairingState> {
|
implements QrCodeDecoder.ResultCallback, Consumer<MailboxPairingState>,
|
||||||
|
EventListener {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(MailboxViewModel.class.getName());
|
getLogger(MailboxViewModel.class.getName());
|
||||||
|
|
||||||
|
private final EventBus eventBus;
|
||||||
|
private final Executor ioExecutor;
|
||||||
private final QrCodeDecoder qrCodeDecoder;
|
private final QrCodeDecoder qrCodeDecoder;
|
||||||
private final PluginManager pluginManager;
|
private final PluginManager pluginManager;
|
||||||
private final MailboxManager mailboxManager;
|
private final MailboxManager mailboxManager;
|
||||||
|
|
||||||
private final MutableLiveEvent<MailboxState> state =
|
private final MutableLiveEvent<MailboxState> pairingState =
|
||||||
new MutableLiveEvent<>();
|
new MutableLiveEvent<>();
|
||||||
|
private final MutableLiveData<MailboxStatus> status =
|
||||||
|
new MutableLiveData<>();
|
||||||
@Nullable
|
@Nullable
|
||||||
private MailboxPairingTask pairingTask = null;
|
private MailboxPairingTask pairingTask = null;
|
||||||
|
|
||||||
@@ -60,19 +73,24 @@ class MailboxViewModel extends DbViewModel
|
|||||||
LifecycleManager lifecycleManager,
|
LifecycleManager lifecycleManager,
|
||||||
TransactionManager db,
|
TransactionManager db,
|
||||||
AndroidExecutor androidExecutor,
|
AndroidExecutor androidExecutor,
|
||||||
|
EventBus eventBus,
|
||||||
@IoExecutor Executor ioExecutor,
|
@IoExecutor Executor ioExecutor,
|
||||||
PluginManager pluginManager,
|
PluginManager pluginManager,
|
||||||
MailboxManager mailboxManager) {
|
MailboxManager mailboxManager) {
|
||||||
super(app, dbExecutor, lifecycleManager, db, androidExecutor);
|
super(app, dbExecutor, lifecycleManager, db, androidExecutor);
|
||||||
|
this.eventBus = eventBus;
|
||||||
|
this.ioExecutor = ioExecutor;
|
||||||
this.pluginManager = pluginManager;
|
this.pluginManager = pluginManager;
|
||||||
this.mailboxManager = mailboxManager;
|
this.mailboxManager = mailboxManager;
|
||||||
qrCodeDecoder = new QrCodeDecoder(androidExecutor, ioExecutor, this);
|
qrCodeDecoder = new QrCodeDecoder(androidExecutor, ioExecutor, this);
|
||||||
|
eventBus.addListener(this);
|
||||||
checkIfSetup();
|
checkIfSetup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCleared() {
|
protected void onCleared() {
|
||||||
super.onCleared();
|
super.onCleared();
|
||||||
|
eventBus.removeListener(this);
|
||||||
MailboxPairingTask task = pairingTask;
|
MailboxPairingTask task = pairingTask;
|
||||||
if (task != null) {
|
if (task != null) {
|
||||||
task.removeObserver(this);
|
task.removeObserver(this);
|
||||||
@@ -89,9 +107,11 @@ class MailboxViewModel extends DbViewModel
|
|||||||
if (isPaired) {
|
if (isPaired) {
|
||||||
MailboxStatus mailboxStatus =
|
MailboxStatus mailboxStatus =
|
||||||
mailboxManager.getMailboxStatus(txn);
|
mailboxManager.getMailboxStatus(txn);
|
||||||
state.postEvent(new MailboxState.IsPaired(mailboxStatus));
|
boolean isOnline = isTorActive();
|
||||||
|
pairingState.postEvent(new MailboxState.IsPaired(isOnline));
|
||||||
|
status.postValue(mailboxStatus);
|
||||||
} else {
|
} else {
|
||||||
state.postEvent(new NotSetup());
|
pairingState.postEvent(new NotSetup());
|
||||||
}
|
}
|
||||||
}, this::handleException);
|
}, this::handleException);
|
||||||
} else {
|
} else {
|
||||||
@@ -100,18 +120,37 @@ class MailboxViewModel extends DbViewModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
@Override
|
||||||
|
public void eventOccurred(Event e) {
|
||||||
|
if (e instanceof OwnMailboxConnectionStatusEvent) {
|
||||||
|
MailboxStatus status =
|
||||||
|
((OwnMailboxConnectionStatusEvent) e).getStatus();
|
||||||
|
this.status.setValue(status);
|
||||||
|
} else if (e instanceof TransportInactiveEvent) {
|
||||||
|
TransportId id = ((TransportInactiveEvent) e).getTransportId();
|
||||||
|
if (!TorConstants.ID.equals(id)) return;
|
||||||
|
MailboxState lastState = pairingState.getLastValue();
|
||||||
|
if (lastState instanceof MailboxState.IsPaired) {
|
||||||
|
pairingState.setEvent(new MailboxState.IsPaired(false));
|
||||||
|
} else if (lastState != null) {
|
||||||
|
pairingState.setEvent(new MailboxState.OfflineWhenPairing());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
void onScanButtonClicked() {
|
void onScanButtonClicked() {
|
||||||
if (isTorActive()) {
|
if (isTorActive()) {
|
||||||
state.setEvent(new MailboxState.ScanningQrCode());
|
pairingState.setEvent(new MailboxState.ScanningQrCode());
|
||||||
} else {
|
} else {
|
||||||
state.setEvent(new MailboxState.OfflineWhenPairing());
|
pairingState.setEvent(new MailboxState.OfflineWhenPairing());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
void onCameraError() {
|
void onCameraError() {
|
||||||
state.setEvent(new MailboxState.CameraError());
|
pairingState.setEvent(new MailboxState.CameraError());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -127,7 +166,7 @@ class MailboxViewModel extends DbViewModel
|
|||||||
pairingTask = mailboxManager.startPairingTask(qrCodePayload);
|
pairingTask = mailboxManager.startPairingTask(qrCodePayload);
|
||||||
pairingTask.addObserver(this);
|
pairingTask.addObserver(this);
|
||||||
} else {
|
} else {
|
||||||
state.postEvent(new MailboxState.OfflineWhenPairing());
|
pairingState.postEvent(new MailboxState.OfflineWhenPairing());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +177,7 @@ class MailboxViewModel extends DbViewModel
|
|||||||
LOG.info("New pairing state: " +
|
LOG.info("New pairing state: " +
|
||||||
mailboxPairingState.getClass().getSimpleName());
|
mailboxPairingState.getClass().getSimpleName());
|
||||||
}
|
}
|
||||||
state.setEvent(new MailboxState.Pairing(mailboxPairingState));
|
pairingState.setEvent(new MailboxState.Pairing(mailboxPairingState));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isTorActive() {
|
private boolean isTorActive() {
|
||||||
@@ -148,7 +187,7 @@ class MailboxViewModel extends DbViewModel
|
|||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
void showDownloadFragment() {
|
void showDownloadFragment() {
|
||||||
state.setEvent(new MailboxState.ShowDownload());
|
pairingState.setEvent(new MailboxState.ShowDownload());
|
||||||
}
|
}
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
@@ -157,7 +196,37 @@ class MailboxViewModel extends DbViewModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
LiveEvent<MailboxState> getState() {
|
void checkIfOnlineWhenPaired() {
|
||||||
return state;
|
boolean isOnline = isTorActive();
|
||||||
|
pairingState.setEvent(new MailboxState.IsPaired(isOnline));
|
||||||
|
}
|
||||||
|
|
||||||
|
LiveData<Boolean> checkConnection() {
|
||||||
|
MutableLiveData<Boolean> liveData = new MutableLiveData<>();
|
||||||
|
ioExecutor.execute(() -> {
|
||||||
|
boolean success = mailboxManager.checkConnection();
|
||||||
|
if (LOG.isLoggable(INFO)) {
|
||||||
|
LOG.info("Got result from connection check: " + success);
|
||||||
|
}
|
||||||
|
liveData.postValue(success);
|
||||||
|
if (!success) { // force failure screen
|
||||||
|
MailboxStatus lastStatus = status.getValue();
|
||||||
|
long lastSuccess = lastStatus == null ?
|
||||||
|
-1 : lastStatus.getTimeOfLastSuccess();
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
status.postValue(new MailboxStatus(now, lastSuccess, 999));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return liveData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
LiveEvent<MailboxState> getPairingState() {
|
||||||
|
return pairingState;
|
||||||
|
}
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
LiveData<MailboxStatus> getStatus() {
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,10 +33,9 @@ public class OfflineFragment extends Fragment {
|
|||||||
@Inject
|
@Inject
|
||||||
ViewModelProvider.Factory viewModelFactory;
|
ViewModelProvider.Factory viewModelFactory;
|
||||||
|
|
||||||
private MailboxViewModel viewModel;
|
protected MailboxViewModel viewModel;
|
||||||
|
|
||||||
private NestedScrollView scrollView;
|
private NestedScrollView scrollView;
|
||||||
protected Button buttonView;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Context context) {
|
public void onAttach(Context context) {
|
||||||
@@ -61,8 +60,8 @@ public class OfflineFragment extends Fragment {
|
|||||||
Intent i = new Intent(requireContext(), TransportsActivity.class);
|
Intent i = new Intent(requireContext(), TransportsActivity.class);
|
||||||
startActivity(i);
|
startActivity(i);
|
||||||
});
|
});
|
||||||
buttonView = v.findViewById(R.id.button);
|
Button buttonView = v.findViewById(R.id.button);
|
||||||
buttonView.setOnClickListener(view -> viewModel.showDownloadFragment());
|
buttonView.setOnClickListener(view -> onTryAgainClicked());
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
@@ -74,4 +73,8 @@ public class OfflineFragment extends Fragment {
|
|||||||
scrollView.post(() -> scrollView.fullScroll(FOCUS_DOWN));
|
scrollView.post(() -> scrollView.fullScroll(FOCUS_DOWN));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void onTryAgainClicked() {
|
||||||
|
viewModel.showDownloadFragment();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package org.briarproject.briar.android.mailbox;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
|
|
||||||
|
@MethodsNotNullByDefault
|
||||||
|
@ParametersNotNullByDefault
|
||||||
|
public class OfflineStatusFragment extends OfflineFragment {
|
||||||
|
|
||||||
|
public static final String TAG = OfflineStatusFragment.class.getName();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onTryAgainClicked() {
|
||||||
|
viewModel.checkIfOnlineWhenPaired();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -215,6 +215,7 @@ public class NavDrawerActivity extends BriarActivity implements
|
|||||||
if (IS_DEBUG_BUILD || shouldWarnOldAndroidExpiry()) {
|
if (IS_DEBUG_BUILD || shouldWarnOldAndroidExpiry()) {
|
||||||
navDrawerViewModel.checkExpiryWarning();
|
navDrawerViewModel.checkExpiryWarning();
|
||||||
}
|
}
|
||||||
|
navDrawerViewModel.printStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ package org.briarproject.briar.android.navdrawer;
|
|||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.TransactionManager;
|
|
||||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.settings.Settings;
|
import org.briarproject.bramble.api.settings.Settings;
|
||||||
@@ -41,6 +41,7 @@ public class NavDrawerViewModel extends DbViewModel {
|
|||||||
private static final String SHOW_TRANSPORTS_ONBOARDING =
|
private static final String SHOW_TRANSPORTS_ONBOARDING =
|
||||||
"showTransportsOnboarding";
|
"showTransportsOnboarding";
|
||||||
|
|
||||||
|
private final DatabaseComponent db;
|
||||||
private final SettingsManager settingsManager;
|
private final SettingsManager settingsManager;
|
||||||
|
|
||||||
private final MutableLiveData<Boolean> showExpiryWarning =
|
private final MutableLiveData<Boolean> showExpiryWarning =
|
||||||
@@ -54,10 +55,11 @@ public class NavDrawerViewModel extends DbViewModel {
|
|||||||
NavDrawerViewModel(Application app,
|
NavDrawerViewModel(Application app,
|
||||||
@DatabaseExecutor Executor dbExecutor,
|
@DatabaseExecutor Executor dbExecutor,
|
||||||
LifecycleManager lifecycleManager,
|
LifecycleManager lifecycleManager,
|
||||||
TransactionManager db,
|
DatabaseComponent db,
|
||||||
AndroidExecutor androidExecutor,
|
AndroidExecutor androidExecutor,
|
||||||
SettingsManager settingsManager) {
|
SettingsManager settingsManager) {
|
||||||
super(app, dbExecutor, lifecycleManager, db, androidExecutor);
|
super(app, dbExecutor, lifecycleManager, db, androidExecutor);
|
||||||
|
this.db = db;
|
||||||
this.settingsManager = settingsManager;
|
this.settingsManager = settingsManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,4 +176,16 @@ public class NavDrawerViewModel extends DbViewModel {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void printStats() {
|
||||||
|
runOnDbThread(() -> {
|
||||||
|
try {
|
||||||
|
db.transaction(false, txn -> {
|
||||||
|
db.printStats(txn);
|
||||||
|
});
|
||||||
|
} catch (DbException e) {
|
||||||
|
handleException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,13 +10,14 @@
|
|||||||
android:id="@+id/imageView"
|
android:id="@+id/imageView"
|
||||||
android:layout_width="32dp"
|
android:layout_width="32dp"
|
||||||
android:layout_height="32dp"
|
android:layout_height="32dp"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginHorizontal="16dp"
|
||||||
android:layout_marginLeft="16dp"
|
app:layout_constraintBottom_toTopOf="@+id/statusTitleView"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/statusTitleView"
|
app:layout_constraintHorizontal_bias="0.5"
|
||||||
app:layout_constraintHorizontal_chainStyle="packed"
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_bias="0.25"
|
||||||
app:layout_constraintVertical_chainStyle="packed"
|
app:layout_constraintVertical_chainStyle="packed"
|
||||||
app:srcCompat="@drawable/ic_check_circle_outline"
|
app:srcCompat="@drawable/ic_check_circle_outline"
|
||||||
app:tint="@color/briar_brand_green"
|
app:tint="@color/briar_brand_green"
|
||||||
@@ -26,14 +27,37 @@
|
|||||||
android:id="@+id/statusTitleView"
|
android:id="@+id/statusTitleView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginHorizontal="16dp"
|
android:layout_margin="16dp"
|
||||||
android:text="@string/mailbox_status_connected_title"
|
android:text="@string/mailbox_status_connected_title"
|
||||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/imageView"
|
app:layout_constraintBottom_toTopOf="@+id/checkButton"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@+id/imageView"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="@+id/imageView" />
|
app:layout_constraintTop_toBottomOf="@+id/imageView" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/checkButton"
|
||||||
|
style="@style/BriarButtonFlat.Neutral"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="16dp"
|
||||||
|
android:text="@string/mailbox_status_check_button"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/statusInfoView"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/statusTitleView" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/checkProgress"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:visibility="invisible"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/checkButton"
|
||||||
|
app:layout_constraintEnd_toEndOf="@+id/checkButton"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/checkButton"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/checkButton"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/statusInfoView"
|
android:id="@+id/statusInfoView"
|
||||||
@@ -41,11 +65,21 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="16dp"
|
android:layout_margin="16dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toTopOf="@+id/unlinkButton"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/statusTitleView"
|
app:layout_constraintTop_toBottomOf="@+id/checkButton"
|
||||||
app:layout_constraintVertical_bias="0.0"
|
|
||||||
tools:text="@string/mailbox_status_connected_info" />
|
tools:text="@string/mailbox_status_connected_info" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/unlinkButton"
|
||||||
|
style="@style/BriarButtonFlat.Negative"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:text="@string/mailbox_status_unlink_button"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|||||||
@@ -643,10 +643,14 @@
|
|||||||
<string name="tor_offline_button_check">Check connection settings</string>
|
<string name="tor_offline_button_check">Check connection settings</string>
|
||||||
<string name="mailbox_status_title">Mailbox status</string>
|
<string name="mailbox_status_title">Mailbox status</string>
|
||||||
<string name="mailbox_status_connected_title">Mailbox is running</string>
|
<string name="mailbox_status_connected_title">Mailbox is running</string>
|
||||||
|
<string name="mailbox_status_problem_title">We are having trouble connecting to the mailbox</string>
|
||||||
|
<string name="mailbox_status_failure_title">Mailbox is unavailable</string>
|
||||||
|
<string name="mailbox_status_check_button">Check Connection</string>
|
||||||
<!-- Example for string substitution: Last connection: 3min ago-->
|
<!-- Example for string substitution: Last connection: 3min ago-->
|
||||||
<string name="mailbox_status_connected_info">Last connection: %s</string>
|
<string name="mailbox_status_connected_info">Last connection: %s</string>
|
||||||
<!-- Indicates that there never was a connection to the mailbox. Last connection: Never -->
|
<!-- Indicates that there never was a connection to the mailbox. Last connection: Never -->
|
||||||
<string name="mailbox_status_connected_never">Never</string>
|
<string name="mailbox_status_connected_never">Never</string>
|
||||||
|
<string name="mailbox_status_unlink_button">Unlink</string>
|
||||||
|
|
||||||
<!-- Conversation Settings -->
|
<!-- Conversation Settings -->
|
||||||
<string name="disappearing_messages_title">Disappearing messages</string>
|
<string name="disappearing_messages_title">Disappearing messages</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user