This commit is contained in:
akwizgran
2017-11-16 10:29:18 +00:00
committed by Torsten Grote
parent 27328afe3c
commit 5fa6b0ca1c
109 changed files with 2087 additions and 3450 deletions

View File

@@ -124,12 +124,7 @@ class DroidtoothPlugin implements DuplexPlugin, EventListener {
// with a message queue, so submit it to the AndroidExecutor // with a message queue, so submit it to the AndroidExecutor
try { try {
adapter = androidExecutor.runOnBackgroundThread( adapter = androidExecutor.runOnBackgroundThread(
new Callable<BluetoothAdapter>() { BluetoothAdapter::getDefaultAdapter).get();
@Override
public BluetoothAdapter call() throws Exception {
return BluetoothAdapter.getDefaultAdapter();
}
}).get();
} catch (InterruptedException e) { } catch (InterruptedException e) {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
LOG.warning("Interrupted while getting BluetoothAdapter"); LOG.warning("Interrupted while getting BluetoothAdapter");
@@ -162,40 +157,36 @@ class DroidtoothPlugin implements DuplexPlugin, EventListener {
} }
private void bind() { private void bind() {
ioExecutor.execute(new Runnable() { ioExecutor.execute(() -> {
@Override if (!isRunning()) return;
public void run() { String address = AndroidUtils.getBluetoothAddress(appContext,
if (!isRunning()) return; adapter);
String address = AndroidUtils.getBluetoothAddress(appContext, if (LOG.isLoggable(INFO))
adapter); LOG.info("Local address " + scrubMacAddress(address));
if (LOG.isLoggable(INFO)) if (!StringUtils.isNullOrEmpty(address)) {
LOG.info("Local address " + scrubMacAddress(address)); // Advertise the Bluetooth address to contacts
if (!StringUtils.isNullOrEmpty(address)) { TransportProperties p = new TransportProperties();
// Advertise the Bluetooth address to contacts p.put(PROP_ADDRESS, address);
TransportProperties p = new TransportProperties(); callback.mergeLocalProperties(p);
p.put(PROP_ADDRESS, address);
callback.mergeLocalProperties(p);
}
// Bind a server socket to accept connections from contacts
BluetoothServerSocket ss;
try {
ss = adapter.listenUsingInsecureRfcommWithServiceRecord(
"RFCOMM", getUuid());
} catch (IOException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
return;
}
if (!isRunning()) {
tryToClose(ss);
return;
}
LOG.info("Socket bound");
socket = ss;
backoff.reset();
callback.transportEnabled();
acceptContactConnections();
} }
// Bind a server socket to accept connections from contacts
BluetoothServerSocket ss;
try {
ss = adapter.listenUsingInsecureRfcommWithServiceRecord(
"RFCOMM", getUuid());
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return;
}
if (!isRunning()) {
tryToClose(ss);
return;
}
LOG.info("Socket bound");
socket = ss;
backoff.reset();
callback.transportEnabled();
acceptContactConnections();
}); });
} }
@@ -300,15 +291,12 @@ class DroidtoothPlugin implements DuplexPlugin, EventListener {
if (StringUtils.isNullOrEmpty(address)) continue; if (StringUtils.isNullOrEmpty(address)) continue;
final String uuid = e.getValue().get(PROP_UUID); final String uuid = e.getValue().get(PROP_UUID);
if (StringUtils.isNullOrEmpty(uuid)) continue; if (StringUtils.isNullOrEmpty(uuid)) continue;
ioExecutor.execute(new Runnable() { ioExecutor.execute(() -> {
@Override if (!running) return;
public void run() { BluetoothSocket s = connect(address, uuid);
if (!running) return; if (s != null) {
BluetoothSocket s = connect(address, uuid); backoff.reset();
if (s != null) { callback.outgoingConnectionCreated(c, wrapSocket(s));
backoff.reset();
callback.outgoingConnectionCreated(c, wrapSocket(s));
}
} }
}); });
} }
@@ -438,21 +426,11 @@ class DroidtoothPlugin implements DuplexPlugin, EventListener {
} }
private void enableAdapterAsync() { private void enableAdapterAsync() {
ioExecutor.execute(new Runnable() { ioExecutor.execute(this::enableAdapter);
@Override
public void run() {
enableAdapter();
}
});
} }
private void disableAdapterAsync() { private void disableAdapterAsync() {
ioExecutor.execute(new Runnable() { ioExecutor.execute(this::disableAdapter);
@Override
public void run() {
disableAdapter();
}
});
} }
private class BluetoothStateReceiver extends BroadcastReceiver { private class BluetoothStateReceiver extends BroadcastReceiver {
@@ -490,16 +468,13 @@ class DroidtoothPlugin implements DuplexPlugin, EventListener {
@Override @Override
public Callable<KeyAgreementConnection> listen() { public Callable<KeyAgreementConnection> listen() {
return new Callable<KeyAgreementConnection>() { return () -> {
@Override BluetoothSocket s = ss.accept();
public KeyAgreementConnection call() throws IOException { if (LOG.isLoggable(INFO))
BluetoothSocket s = ss.accept(); LOG.info(ID.getString() + ": Incoming connection");
if (LOG.isLoggable(INFO)) return new KeyAgreementConnection(
LOG.info(ID.getString() + ": Incoming connection"); new DroidtoothTransportConnection(
return new KeyAgreementConnection( DroidtoothPlugin.this, s), ID);
new DroidtoothTransportConnection(
DroidtoothPlugin.this, s), ID);
}
}; };
} }

View File

@@ -370,57 +370,45 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
} }
private void sendDevReports() { private void sendDevReports() {
ioExecutor.execute(new Runnable() { ioExecutor.execute(() -> {
@Override // TODO: Trigger this with a TransportEnabledEvent
public void run() { File reportDir = AndroidUtils.getReportDir(appContext);
// TODO: Trigger this with a TransportEnabledEvent reporter.sendReports(reportDir);
File reportDir = AndroidUtils.getReportDir(appContext);
reporter.sendReports(reportDir);
}
}); });
} }
private void bind() { private void bind() {
ioExecutor.execute(new Runnable() { ioExecutor.execute(() -> {
@Override // If there's already a port number stored in config, reuse it
public void run() { String portString = callback.getSettings().get(PREF_TOR_PORT);
// If there's already a port number stored in config, reuse it int port;
String portString = callback.getSettings().get(PREF_TOR_PORT); if (StringUtils.isNullOrEmpty(portString)) port = 0;
int port; else port = Integer.parseInt(portString);
if (StringUtils.isNullOrEmpty(portString)) port = 0; // Bind a server socket to receive connections from Tor
else port = Integer.parseInt(portString); ServerSocket ss = null;
// Bind a server socket to receive connections from Tor try {
ServerSocket ss = null; ss = new ServerSocket();
try { ss.bind(new InetSocketAddress("127.0.0.1", port));
ss = new ServerSocket(); } catch (IOException e) {
ss.bind(new InetSocketAddress("127.0.0.1", port)); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (IOException e) { tryToClose(ss);
if (LOG.isLoggable(WARNING)) return;
LOG.log(WARNING, e.toString(), e);
tryToClose(ss);
return;
}
if (!running) {
tryToClose(ss);
return;
}
socket = ss;
// Store the port number
final String localPort = String.valueOf(ss.getLocalPort());
Settings s = new Settings();
s.put(PREF_TOR_PORT, localPort);
callback.mergeSettings(s);
// Create a hidden service if necessary
ioExecutor.execute(new Runnable() {
@Override
public void run() {
publishHiddenService(localPort);
}
});
backoff.reset();
// Accept incoming hidden service connections from Tor
acceptContactConnections(ss);
} }
if (!running) {
tryToClose(ss);
return;
}
socket = ss;
// Store the port number
final String localPort = String.valueOf(ss.getLocalPort());
Settings s = new Settings();
s.put(PREF_TOR_PORT, localPort);
callback.mergeSettings(s);
// Create a hidden service if necessary
ioExecutor.execute(() -> publishHiddenService(localPort));
backoff.reset();
// Accept incoming hidden service connections from Tor
acceptContactConnections(ss);
}); });
} }
@@ -550,15 +538,12 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private void connectAndCallBack(final ContactId c, private void connectAndCallBack(final ContactId c,
final TransportProperties p) { final TransportProperties p) {
ioExecutor.execute(new Runnable() { ioExecutor.execute(() -> {
@Override if (!isRunning()) return;
public void run() { DuplexTransportConnection d = createConnection(p);
if (!isRunning()) return; if (d != null) {
DuplexTransportConnection d = createConnection(p); backoff.reset();
if (d != null) { callback.outgoingConnectionCreated(c, d);
backoff.reset();
callback.outgoingConnectionCreated(c, d);
}
} }
}); });
} }
@@ -691,48 +676,43 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
} }
private void updateConnectionStatus() { private void updateConnectionStatus() {
ioExecutor.execute(new Runnable() { ioExecutor.execute(() -> {
@Override if (!running) return;
public void run() {
if (!running) return;
Object o = appContext.getSystemService(CONNECTIVITY_SERVICE); Object o = appContext.getSystemService(CONNECTIVITY_SERVICE);
ConnectivityManager cm = (ConnectivityManager) o; ConnectivityManager cm = (ConnectivityManager) o;
NetworkInfo net = cm.getActiveNetworkInfo(); NetworkInfo net = cm.getActiveNetworkInfo();
boolean online = net != null && net.isConnected(); boolean online = net != null && net.isConnected();
boolean wifi = online && net.getType() == TYPE_WIFI; boolean wifi = online && net.getType() == TYPE_WIFI;
String country = locationUtils.getCurrentCountry(); String country = locationUtils.getCurrentCountry();
boolean blocked = TorNetworkMetadata.isTorProbablyBlocked( boolean blocked = TorNetworkMetadata.isTorProbablyBlocked(
country); country);
Settings s = callback.getSettings(); Settings s = callback.getSettings();
int network = s.getInt(PREF_TOR_NETWORK, int network = s.getInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_ALWAYS);
PREF_TOR_NETWORK_ALWAYS);
if (LOG.isLoggable(INFO)) { if (LOG.isLoggable(INFO)) {
LOG.info("Online: " + online + ", wifi: " + wifi); LOG.info("Online: " + online + ", wifi: " + wifi);
if ("".equals(country)) LOG.info("Country code unknown"); if ("".equals(country)) LOG.info("Country code unknown");
else LOG.info("Country code: " + country); else LOG.info("Country code: " + country);
} }
try { try {
if (!online) { if (!online) {
LOG.info("Disabling network, device is offline"); LOG.info("Disabling network, device is offline");
enableNetwork(false); enableNetwork(false);
} else if (blocked) { } else if (blocked) {
LOG.info("Disabling network, country is blocked"); LOG.info("Disabling network, country is blocked");
enableNetwork(false); enableNetwork(false);
} else if (network == PREF_TOR_NETWORK_NEVER } else if (network == PREF_TOR_NETWORK_NEVER
|| (network == PREF_TOR_NETWORK_WIFI && !wifi)) { || (network == PREF_TOR_NETWORK_WIFI && !wifi)) {
LOG.info("Disabling network due to data setting"); LOG.info("Disabling network due to data setting");
enableNetwork(false); enableNetwork(false);
} else { } else {
LOG.info("Enabling network"); LOG.info("Enabling network");
enableNetwork(true); enableNetwork(true);
}
} catch (IOException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} }
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }

View File

@@ -27,14 +27,11 @@ class AndroidExecutorImpl implements AndroidExecutor {
@Inject @Inject
AndroidExecutorImpl(Application app) { AndroidExecutorImpl(Application app) {
uiHandler = new Handler(app.getApplicationContext().getMainLooper()); uiHandler = new Handler(app.getApplicationContext().getMainLooper());
loop = new Runnable() { loop = () -> {
@Override Looper.prepare();
public void run() { backgroundHandler = new Handler();
Looper.prepare(); startLatch.countDown();
backgroundHandler = new Handler(); Looper.loop();
startLatch.countDown();
Looper.loop();
}
}; };
} }

View File

@@ -8,12 +8,9 @@ public abstract class BrambleTestCase {
public BrambleTestCase() { public BrambleTestCase() {
// Ensure exceptions thrown on worker threads cause tests to fail // Ensure exceptions thrown on worker threads cause tests to fail
UncaughtExceptionHandler fail = new UncaughtExceptionHandler() { UncaughtExceptionHandler fail = (thread, throwable) -> {
@Override throwable.printStackTrace();
public void uncaughtException(Thread thread, Throwable throwable) { fail();
throwable.printStackTrace();
fail();
}
}; };
Thread.setDefaultUncaughtExceptionHandler(fail); Thread.setDefaultUncaughtExceptionHandler(fail);
} }

View File

@@ -50,18 +50,15 @@ public class PoliteExecutor implements Executor {
@Override @Override
public void execute(final Runnable r) { public void execute(final Runnable r) {
final long submitted = System.currentTimeMillis(); final long submitted = System.currentTimeMillis();
Runnable wrapped = new Runnable() { Runnable wrapped = () -> {
@Override if (log.isLoggable(LOG_LEVEL)) {
public void run() { long queued = System.currentTimeMillis() - submitted;
if (log.isLoggable(LOG_LEVEL)) { log.log(LOG_LEVEL, "Queue time " + queued + " ms");
long queued = System.currentTimeMillis() - submitted; }
log.log(LOG_LEVEL, "Queue time " + queued + " ms"); try {
} r.run();
try { } finally {
r.run(); scheduleNext();
} finally {
scheduleNext();
}
} }
}; };
synchronized (lock) { synchronized (lock) {

View File

@@ -31,16 +31,13 @@ public class TimeLoggingExecutor extends ThreadPoolExecutor {
public void execute(final Runnable r) { public void execute(final Runnable r) {
if (log.isLoggable(LOG_LEVEL)) { if (log.isLoggable(LOG_LEVEL)) {
final long submitted = System.currentTimeMillis(); final long submitted = System.currentTimeMillis();
super.execute(new Runnable() { super.execute(() -> {
@Override long started = System.currentTimeMillis();
public void run() { long queued = started - submitted;
long started = System.currentTimeMillis(); log.log(LOG_LEVEL, "Queue time " + queued + " ms");
long queued = started - submitted; r.run();
log.log(LOG_LEVEL, "Queue time " + queued + " ms"); long executing = System.currentTimeMillis() - started;
r.run(); log.log(LOG_LEVEL, "Execution time " + executing + " ms");
long executing = System.currentTimeMillis() - started;
log.log(LOG_LEVEL, "Execution time " + executing + " ms");
}
}); });
} else { } else {
super.execute(r); super.execute(r);

View File

@@ -103,15 +103,11 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
@Override @Override
public boolean open() throws DbException { public boolean open() throws DbException {
Runnable shutdownHook = new Runnable() { Runnable shutdownHook = () -> {
@Override try {
public void run() { close();
try { } catch (DbException e) {
close(); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
}; };
boolean reopened = db.open(); boolean reopened = db.open();

View File

@@ -266,12 +266,7 @@ class ConnectionManagerImpl implements ConnectionManager {
contactId = ctx.getContactId(); contactId = ctx.getContactId();
connectionRegistry.registerConnection(contactId, transportId, true); connectionRegistry.registerConnection(contactId, transportId, true);
// Start the outgoing session on another thread // Start the outgoing session on another thread
ioExecutor.execute(new Runnable() { ioExecutor.execute(this::runOutgoingSession);
@Override
public void run() {
runOutgoingSession();
}
});
try { try {
// Create and run the incoming session // Create and run the incoming session
incomingSession = createIncomingSession(ctx, reader); incomingSession = createIncomingSession(ctx, reader);
@@ -368,12 +363,7 @@ class ConnectionManagerImpl implements ConnectionManager {
return; return;
} }
// Start the incoming session on another thread // Start the incoming session on another thread
ioExecutor.execute(new Runnable() { ioExecutor.execute(this::runIncomingSession);
@Override
public void run() {
runIncomingSession();
}
});
try { try {
// Create and run the outgoing session // Create and run the outgoing session
outgoingSession = createDuplexOutgoingSession(ctx, writer); outgoingSession = createDuplexOutgoingSession(ctx, writer);

View File

@@ -112,29 +112,23 @@ class Poller implements EventListener {
} }
private void connectToContact(final ContactId c, final SimplexPlugin p) { private void connectToContact(final ContactId c, final SimplexPlugin p) {
ioExecutor.execute(new Runnable() { ioExecutor.execute(() -> {
@Override TransportId t = p.getId();
public void run() { if (!connectionRegistry.isConnected(c, t)) {
TransportId t = p.getId(); TransportConnectionWriter w = p.createWriter(c);
if (!connectionRegistry.isConnected(c, t)) { if (w != null)
TransportConnectionWriter w = p.createWriter(c); connectionManager.manageOutgoingConnection(c, t, w);
if (w != null)
connectionManager.manageOutgoingConnection(c, t, w);
}
} }
}); });
} }
private void connectToContact(final ContactId c, final DuplexPlugin p) { private void connectToContact(final ContactId c, final DuplexPlugin p) {
ioExecutor.execute(new Runnable() { ioExecutor.execute(() -> {
@Override TransportId t = p.getId();
public void run() { if (!connectionRegistry.isConnected(c, t)) {
TransportId t = p.getId(); DuplexTransportConnection d = p.createConnection(c);
if (!connectionRegistry.isConnected(c, t)) { if (d != null)
DuplexTransportConnection d = p.createConnection(c); connectionManager.manageOutgoingConnection(c, t, d);
if (d != null)
connectionManager.manageOutgoingConnection(c, t, d);
}
} }
}); });
} }
@@ -161,12 +155,8 @@ class Poller implements EventListener {
if (scheduled == null || due < scheduled.due) { if (scheduled == null || due < scheduled.due) {
final PollTask task = new PollTask(p, due, randomiseNext); final PollTask task = new PollTask(p, due, randomiseNext);
tasks.put(t, task); tasks.put(t, task);
scheduler.schedule(new Runnable() { scheduler.schedule(
@Override () -> ioExecutor.execute(task), delay, MILLISECONDS);
public void run() {
ioExecutor.execute(task);
}
}, delay, MILLISECONDS);
} }
} finally { } finally {
lock.unlock(); lock.unlock();

View File

@@ -260,16 +260,12 @@ class LanTcpPlugin extends TcpPlugin {
@Override @Override
public Callable<KeyAgreementConnection> listen() { public Callable<KeyAgreementConnection> listen() {
return new Callable<KeyAgreementConnection>() { return () -> {
@Override Socket s = ss.accept();
public KeyAgreementConnection call() throws IOException { if (LOG.isLoggable(INFO))
Socket s = ss.accept(); LOG.info(ID.getString() + ": Incoming connection");
if (LOG.isLoggable(INFO)) return new KeyAgreementConnection(
LOG.info(ID.getString() + ": Incoming connection"); new TcpTransportConnection(LanTcpPlugin.this, s), ID);
return new KeyAgreementConnection(
new TcpTransportConnection(LanTcpPlugin.this, s),
ID);
}
}; };
} }

View File

@@ -50,12 +50,7 @@ class PortMapperImpl implements PortMapper {
succeeded = gateway.addPortMapping(port, port, succeeded = gateway.addPortMapping(port, port,
getHostAddress(internal), "TCP", "TCP"); getHostAddress(internal), "TCP", "TCP");
if (succeeded) { if (succeeded) {
shutdownManager.addShutdownHook(new Runnable() { shutdownManager.addShutdownHook(() -> deleteMapping(port));
@Override
public void run() {
deleteMapping(port);
}
});
} }
String externalString = gateway.getExternalIPAddress(); String externalString = gateway.getExternalIPAddress();
if (LOG.isLoggable(INFO)) if (LOG.isLoggable(INFO))

View File

@@ -110,41 +110,37 @@ abstract class TcpPlugin implements DuplexPlugin {
} }
protected void bind() { protected void bind() {
ioExecutor.execute(new Runnable() { ioExecutor.execute(() -> {
@Override if (!running) return;
public void run() { ServerSocket ss = null;
if (!running) return; for (InetSocketAddress addr : getLocalSocketAddresses()) {
ServerSocket ss = null; try {
for (InetSocketAddress addr : getLocalSocketAddresses()) { ss = new ServerSocket();
try { ss.bind(addr);
ss = new ServerSocket(); break;
ss.bind(addr); } catch (IOException e) {
break; if (LOG.isLoggable(INFO))
} catch (IOException e) { LOG.info("Failed to bind " + scrubSocketAddress(addr));
if (LOG.isLoggable(INFO))
LOG.info("Failed to bind " +
scrubSocketAddress(addr));
tryToClose(ss);
}
}
if (ss == null || !ss.isBound()) {
LOG.info("Could not bind server socket");
return;
}
if (!running) {
tryToClose(ss); tryToClose(ss);
return;
} }
socket = ss;
backoff.reset();
InetSocketAddress local =
(InetSocketAddress) ss.getLocalSocketAddress();
setLocalSocketAddress(local);
if (LOG.isLoggable(INFO))
LOG.info("Listening on " + scrubSocketAddress(local));
callback.transportEnabled();
acceptContactConnections();
} }
if (ss == null || !ss.isBound()) {
LOG.info("Could not bind server socket");
return;
}
if (!running) {
tryToClose(ss);
return;
}
socket = ss;
backoff.reset();
InetSocketAddress local =
(InetSocketAddress) ss.getLocalSocketAddress();
setLocalSocketAddress(local);
if (LOG.isLoggable(INFO))
LOG.info("Listening on " + scrubSocketAddress(local));
callback.transportEnabled();
acceptContactConnections();
}); });
} }
@@ -220,15 +216,12 @@ abstract class TcpPlugin implements DuplexPlugin {
private void connectAndCallBack(final ContactId c, private void connectAndCallBack(final ContactId c,
final TransportProperties p) { final TransportProperties p) {
ioExecutor.execute(new Runnable() { ioExecutor.execute(() -> {
@Override if (!isRunning()) return;
public void run() { DuplexTransportConnection d = createConnection(p);
if (!isRunning()) return; if (d != null) {
DuplexTransportConnection d = createConnection(p); backoff.reset();
if (d != null) { callback.outgoingConnectionCreated(c, d);
backoff.reset();
callback.outgoingConnectionCreated(c, d);
}
} }
}); });
} }

View File

@@ -54,36 +54,32 @@ class ReliabilityLayerImpl implements ReliabilityLayer, WriteHandler {
inputStream = new ReceiverInputStream(receiver); inputStream = new ReceiverInputStream(receiver);
outputStream = new SenderOutputStream(sender); outputStream = new SenderOutputStream(sender);
running = true; running = true;
executor.execute(new Runnable() { executor.execute(() -> {
@Override long now = clock.currentTimeMillis();
public void run() { long next = now + TICK_INTERVAL;
long now = clock.currentTimeMillis(); try {
long next = now + TICK_INTERVAL; while (running) {
try { byte[] b = null;
while (running) { while (now < next && b == null) {
byte[] b = null; b = writes.poll(next - now, MILLISECONDS);
while (now < next && b == null) { if (!running) return;
b = writes.poll(next - now, MILLISECONDS); now = clock.currentTimeMillis();
if (!running) return; }
now = clock.currentTimeMillis(); if (b == null) {
} sender.tick();
if (b == null) { while (next <= now) next += TICK_INTERVAL;
sender.tick(); } else {
while (next <= now) next += TICK_INTERVAL; if (b.length == 0) return; // Poison pill
} else { writeHandler.handleWrite(b);
if (b.length == 0) return; // Poison pill
writeHandler.handleWrite(b);
}
} }
} catch (InterruptedException e) {
LOG.warning("Interrupted while waiting to write");
Thread.currentThread().interrupt();
running = false;
} catch (IOException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
running = false;
} }
} catch (InterruptedException e) {
LOG.warning("Interrupted while waiting to write");
Thread.currentThread().interrupt();
running = false;
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
running = false;
} }
}); });
} }

View File

@@ -54,12 +54,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(DuplexOutgoingSession.class.getName()); Logger.getLogger(DuplexOutgoingSession.class.getName());
private static final ThrowingRunnable<IOException> CLOSE = private static final ThrowingRunnable<IOException> CLOSE = () -> {};
new ThrowingRunnable<IOException>() {
@Override
public void run() {
}
};
private final DatabaseComponent db; private final DatabaseComponent db;
private final Executor dbExecutor; private final Executor dbExecutor;

View File

@@ -43,12 +43,7 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(SimplexOutgoingSession.class.getName()); Logger.getLogger(SimplexOutgoingSession.class.getName());
private static final ThrowingRunnable<IOException> CLOSE = private static final ThrowingRunnable<IOException> CLOSE = () -> {};
new ThrowingRunnable<IOException>() {
@Override
public void run() {
}
};
private final DatabaseComponent db; private final DatabaseComponent db;
private final Executor dbExecutor; private final Executor dbExecutor;

View File

@@ -94,12 +94,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
} }
private void validateOutstandingMessagesAsync(final ClientId c) { private void validateOutstandingMessagesAsync(final ClientId c) {
dbExecutor.execute(new Runnable() { dbExecutor.execute(() -> validateOutstandingMessages(c));
@Override
public void run() {
validateOutstandingMessages(c);
}
});
} }
@DatabaseExecutor @DatabaseExecutor
@@ -121,12 +116,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
private void validateNextMessageAsync(final Queue<MessageId> unvalidated) { private void validateNextMessageAsync(final Queue<MessageId> unvalidated) {
if (unvalidated.isEmpty()) return; if (unvalidated.isEmpty()) return;
dbExecutor.execute(new Runnable() { dbExecutor.execute(() -> validateNextMessage(unvalidated));
@Override
public void run() {
validateNextMessage(unvalidated);
}
});
} }
@DatabaseExecutor @DatabaseExecutor
@@ -159,12 +149,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
} }
private void deliverOutstandingMessagesAsync(final ClientId c) { private void deliverOutstandingMessagesAsync(final ClientId c) {
dbExecutor.execute(new Runnable() { dbExecutor.execute(() -> deliverOutstandingMessages(c));
@Override
public void run() {
deliverOutstandingMessages(c);
}
});
} }
@DatabaseExecutor @DatabaseExecutor
@@ -187,12 +172,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
private void deliverNextPendingMessageAsync( private void deliverNextPendingMessageAsync(
final Queue<MessageId> pending) { final Queue<MessageId> pending) {
if (pending.isEmpty()) return; if (pending.isEmpty()) return;
dbExecutor.execute(new Runnable() { dbExecutor.execute(() -> deliverNextPendingMessage(pending));
@Override
public void run() {
deliverNextPendingMessage(pending);
}
});
} }
@DatabaseExecutor @DatabaseExecutor
@@ -255,12 +235,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
} }
private void validateMessageAsync(final Message m, final Group g) { private void validateMessageAsync(final Message m, final Group g) {
validationExecutor.execute(new Runnable() { validationExecutor.execute(() -> validateMessage(m, g));
@Override
public void run() {
validateMessage(m, g);
}
});
} }
@ValidationExecutor @ValidationExecutor
@@ -285,12 +260,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
private void storeMessageContextAsync(final Message m, final ClientId c, private void storeMessageContextAsync(final Message m, final ClientId c,
final MessageContext result) { final MessageContext result) {
dbExecutor.execute(new Runnable() { dbExecutor.execute(() -> storeMessageContext(m, c, result));
@Override
public void run() {
storeMessageContext(m, c, result);
}
});
} }
@DatabaseExecutor @DatabaseExecutor
@@ -385,12 +355,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
} }
private void shareOutstandingMessagesAsync(final ClientId c) { private void shareOutstandingMessagesAsync(final ClientId c) {
dbExecutor.execute(new Runnable() { dbExecutor.execute(() -> shareOutstandingMessages(c));
@Override
public void run() {
shareOutstandingMessages(c);
}
});
} }
@DatabaseExecutor @DatabaseExecutor
@@ -418,12 +383,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
*/ */
private void shareNextMessageAsync(final Queue<MessageId> toShare) { private void shareNextMessageAsync(final Queue<MessageId> toShare) {
if (toShare.isEmpty()) return; if (toShare.isEmpty()) return;
dbExecutor.execute(new Runnable() { dbExecutor.execute(() -> shareNextMessage(toShare));
@Override
public void run() {
shareNextMessage(toShare);
}
});
} }
@DatabaseExecutor @DatabaseExecutor
@@ -452,12 +412,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
private void invalidateNextMessageAsync(final Queue<MessageId> invalidate) { private void invalidateNextMessageAsync(final Queue<MessageId> invalidate) {
if (invalidate.isEmpty()) return; if (invalidate.isEmpty()) return;
dbExecutor.execute(new Runnable() { dbExecutor.execute(() -> invalidateNextMessage(invalidate));
@Override
public void run() {
invalidateNextMessage(invalidate);
}
});
} }
@DatabaseExecutor @DatabaseExecutor
@@ -513,12 +468,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
} }
private void loadGroupAndValidateAsync(final Message m) { private void loadGroupAndValidateAsync(final Message m) {
dbExecutor.execute(new Runnable() { dbExecutor.execute(() -> loadGroupAndValidate(m));
@Override
public void run() {
loadGroupAndValidate(m);
}
});
} }
@DatabaseExecutor @DatabaseExecutor

View File

@@ -157,12 +157,8 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
private void removeContact(final ContactId c) { private void removeContact(final ContactId c) {
activeContacts.remove(c); activeContacts.remove(c);
dbExecutor.execute(new Runnable() { dbExecutor.execute(() -> {
@Override for (TransportKeyManager m : managers.values()) m.removeContact(c);
public void run() {
for (TransportKeyManager m : managers.values())
m.removeContact(c);
}
}); });
} }
} }

View File

@@ -134,32 +134,22 @@ class TransportKeyManagerImpl implements TransportKeyManager {
} }
private void scheduleKeyRotation(long now) { private void scheduleKeyRotation(long now) {
Runnable task = new Runnable() {
@Override
public void run() {
rotateKeys();
}
};
long delay = rotationPeriodLength - now % rotationPeriodLength; long delay = rotationPeriodLength - now % rotationPeriodLength;
scheduler.schedule(task, delay, MILLISECONDS); scheduler.schedule((Runnable) this::rotateKeys, delay, MILLISECONDS);
} }
private void rotateKeys() { private void rotateKeys() {
dbExecutor.execute(new Runnable() { dbExecutor.execute(() -> {
@Override try {
public void run() { Transaction txn = db.startTransaction(false);
try { try {
Transaction txn = db.startTransaction(false); rotateKeys(txn);
try { db.commitTransaction(txn);
rotateKeys(txn); } finally {
db.commitTransaction(txn); db.endTransaction(txn);
} finally {
db.endTransaction(txn);
}
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} }
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }

View File

@@ -28,12 +28,9 @@ public class PoliteExecutorTest extends BrambleTestCase {
final CountDownLatch latch = new CountDownLatch(TASKS); final CountDownLatch latch = new CountDownLatch(TASKS);
for (int i = 0; i < TASKS; i++) { for (int i = 0; i < TASKS; i++) {
final int result = i; final int result = i;
polite.execute(new Runnable() { polite.execute(() -> {
@Override list.add(result);
public void run() { latch.countDown();
list.add(result);
latch.countDown();
}
}); });
} }
// Wait for all the tasks to finish // Wait for all the tasks to finish
@@ -53,12 +50,9 @@ public class PoliteExecutorTest extends BrambleTestCase {
final CountDownLatch latch = new CountDownLatch(TASKS); final CountDownLatch latch = new CountDownLatch(TASKS);
for (int i = 0; i < TASKS; i++) { for (int i = 0; i < TASKS; i++) {
final int result = i; final int result = i;
polite.execute(new Runnable() { polite.execute(() -> {
@Override list.add(result);
public void run() { latch.countDown();
list.add(result);
latch.countDown();
}
}); });
} }
// Wait for all the tasks to finish // Wait for all the tasks to finish
@@ -78,18 +72,15 @@ public class PoliteExecutorTest extends BrambleTestCase {
for (int i = 0; i < TASKS; i++) latches[i] = new CountDownLatch(1); for (int i = 0; i < TASKS; i++) latches[i] = new CountDownLatch(1);
for (int i = 0; i < TASKS; i++) { for (int i = 0; i < TASKS; i++) {
final int result = i; final int result = i;
polite.execute(new Runnable() { polite.execute(() -> {
@Override try {
public void run() { // Each task waits for the next task, if any, to finish
try { if (result < TASKS - 1) latches[result + 1].await();
// Each task waits for the next task, if any, to finish list.add(result);
if (result < TASKS - 1) latches[result + 1].await(); } catch (InterruptedException e) {
list.add(result); fail();
} catch (InterruptedException e) {
fail();
}
latches[result].countDown();
} }
latches[result].countDown();
}); });
} }
// Wait for all the tasks to finish // Wait for all the tasks to finish
@@ -108,18 +99,15 @@ public class PoliteExecutorTest extends BrambleTestCase {
final CountDownLatch latch = new CountDownLatch(TASKS); final CountDownLatch latch = new CountDownLatch(TASKS);
for (int i = 0; i < TASKS; i++) { for (int i = 0; i < TASKS; i++) {
final int result = i; final int result = i;
polite.execute(new Runnable() { polite.execute(() -> {
@Override try {
public void run() { // Each task runs faster than the previous task
try { Thread.sleep(TASKS - result);
// Each task runs faster than the previous task list.add(result);
Thread.sleep(TASKS - result); } catch (InterruptedException e) {
list.add(result); fail();
} catch (InterruptedException e) {
fail();
}
latch.countDown();
} }
latch.countDown();
}); });
} }
// Wait for all the tasks to finish // Wait for all the tasks to finish

View File

@@ -17,11 +17,7 @@ public class ShutdownManagerImplTest extends BrambleTestCase {
ShutdownManager s = createShutdownManager(); ShutdownManager s = createShutdownManager();
Set<Integer> handles = new HashSet<>(); Set<Integer> handles = new HashSet<>();
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
int handle = s.addShutdownHook(new Runnable() { int handle = s.addShutdownHook(() -> {});
@Override
public void run() {
}
});
// The handles should all be distinct // The handles should all be distinct
assertTrue(handles.add(handle)); assertTrue(handles.add(handle));
} }

View File

@@ -113,17 +113,13 @@ class WindowsShutdownManagerImpl extends ShutdownManagerImpl {
final User32 user32 = (User32) Native.loadLibrary("user32", final User32 user32 = (User32) Native.loadLibrary("user32",
User32.class, options); User32.class, options);
// Create a callback to handle the WM_QUERYENDSESSION message // Create a callback to handle the WM_QUERYENDSESSION message
WindowProc proc = new WindowProc() { WindowProc proc = (hwnd, msg, wp, lp) -> {
@Override if (msg == WM_QUERYENDSESSION) {
public LRESULT callback(HWND hwnd, int msg, WPARAM wp, // It's safe to delay returning from this message
LPARAM lp) { runShutdownHooks();
if (msg == WM_QUERYENDSESSION) {
// It's safe to delay returning from this message
runShutdownHooks();
}
// Pass the message to the default window procedure
return user32.DefWindowProc(hwnd, msg, wp, lp);
} }
// Pass the message to the default window procedure
return user32.DefWindowProc(hwnd, msg, wp, lp);
}; };
// Create a native window // Create a native window
HWND hwnd = user32.CreateWindowEx(0, "STATIC", "", WS_MINIMIZE, HWND hwnd = user32.CreateWindowEx(0, "STATIC", "", WS_MINIMIZE,

View File

@@ -108,33 +108,30 @@ class BluetoothPlugin implements DuplexPlugin {
} }
private void bind() { private void bind() {
ioExecutor.execute(new Runnable() { ioExecutor.execute(() -> {
@Override if (!running) return;
public void run() { // Advertise the Bluetooth address to contacts
if (!running) return; TransportProperties p = new TransportProperties();
// Advertise the Bluetooth address to contacts p.put(PROP_ADDRESS, localDevice.getBluetoothAddress());
TransportProperties p = new TransportProperties(); callback.mergeLocalProperties(p);
p.put(PROP_ADDRESS, localDevice.getBluetoothAddress()); // Bind a server socket to accept connections from contacts
callback.mergeLocalProperties(p); String url = makeUrl("localhost", getUuid());
// Bind a server socket to accept connections from contacts StreamConnectionNotifier ss;
String url = makeUrl("localhost", getUuid()); try {
StreamConnectionNotifier ss; ss = (StreamConnectionNotifier) Connector.open(url);
try { } catch (IOException e) {
ss = (StreamConnectionNotifier) Connector.open(url); if (LOG.isLoggable(WARNING))
} catch (IOException e) { LOG.log(WARNING, e.toString(), e);
if (LOG.isLoggable(WARNING)) return;
LOG.log(WARNING, e.toString(), e);
return;
}
if (!running) {
tryToClose(ss);
return;
}
socket = ss;
backoff.reset();
callback.transportEnabled();
acceptContactConnections(ss);
} }
if (!running) {
tryToClose(ss);
return;
}
socket = ss;
backoff.reset();
callback.transportEnabled();
acceptContactConnections(ss);
}); });
} }
@@ -220,20 +217,18 @@ class BluetoothPlugin implements DuplexPlugin {
if (StringUtils.isNullOrEmpty(address)) continue; if (StringUtils.isNullOrEmpty(address)) continue;
final String uuid = e.getValue().get(PROP_UUID); final String uuid = e.getValue().get(PROP_UUID);
if (StringUtils.isNullOrEmpty(uuid)) continue; if (StringUtils.isNullOrEmpty(uuid)) continue;
ioExecutor.execute(new Runnable() { ioExecutor.execute(() -> {
@Override if (!running) return;
public void run() { StreamConnection s = connect(makeUrl(address, uuid));
if (!running) return; if (s != null) {
StreamConnection s = connect(makeUrl(address, uuid)); backoff.reset();
if (s != null) { callback.outgoingConnectionCreated(c, wrapSocket(s));
backoff.reset();
callback.outgoingConnectionCreated(c, wrapSocket(s));
}
} }
}); });
} }
} }
@Nullable
private StreamConnection connect(String url) { private StreamConnection connect(String url) {
if (LOG.isLoggable(INFO)) LOG.info("Connecting to " + url); if (LOG.isLoggable(INFO)) LOG.info("Connecting to " + url);
try { try {
@@ -341,16 +336,13 @@ class BluetoothPlugin implements DuplexPlugin {
@Override @Override
public Callable<KeyAgreementConnection> listen() { public Callable<KeyAgreementConnection> listen() {
return new Callable<KeyAgreementConnection>() { return () -> {
@Override StreamConnection s = ss.acceptAndOpen();
public KeyAgreementConnection call() throws Exception { if (LOG.isLoggable(INFO))
StreamConnection s = ss.acceptAndOpen(); LOG.info(ID.getString() + ": Incoming connection");
if (LOG.isLoggable(INFO)) return new KeyAgreementConnection(
LOG.info(ID.getString() + ": Incoming connection"); new BluetoothTransportConnection(
return new KeyAgreementConnection( BluetoothPlugin.this, s), ID);
new BluetoothTransportConnection(
BluetoothPlugin.this, s), ID);
}
}; };
} }

View File

@@ -390,15 +390,12 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
lock.unlock(); lock.unlock();
} }
} else if (s.equals("RING")) { } else if (s.equals("RING")) {
ioExecutor.execute(new Runnable() { ioExecutor.execute(() -> {
@Override try {
public void run() { answer();
try { } catch (IOException e) {
answer(); if (LOG.isLoggable(WARNING))
} catch (IOException e) { LOG.log(WARNING, e.toString(), e);
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
}); });
} }

View File

@@ -44,7 +44,6 @@ import org.briarproject.briar.api.sharing.event.InvitationResponseReceivedEvent;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.Future; import java.util.concurrent.Future;
@@ -138,16 +137,13 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
@Override @Override
public void stopService() throws ServiceException { public void stopService() throws ServiceException {
// Clear all notifications // Clear all notifications
Future<Void> f = androidExecutor.runOnUiThread(new Callable<Void>() { Future<Void> f = androidExecutor.runOnUiThread(() -> {
@Override clearContactNotification();
public Void call() { clearGroupMessageNotification();
clearContactNotification(); clearForumPostNotification();
clearGroupMessageNotification(); clearBlogPostNotification();
clearForumPostNotification(); clearIntroductionSuccessNotification();
clearBlogPostNotification(); return null;
clearIntroductionSuccessNotification();
return null;
}
}); });
try { try {
f.get(); f.get();
@@ -236,44 +232,35 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
} }
private void loadSettings() { private void loadSettings() {
dbExecutor.execute(new Runnable() { dbExecutor.execute(() -> {
@Override try {
public void run() { settings = settingsManager.getSettings(SETTINGS_NAMESPACE);
try { } catch (DbException e) {
settings = settingsManager.getSettings(SETTINGS_NAMESPACE); if (LOG.isLoggable(WARNING))
} catch (DbException e) { LOG.log(WARNING, e.toString(), e);
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
}); });
} }
private void showContactNotification(final ContactId c) { private void showContactNotification(final ContactId c) {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread(() -> {
@Override if (blockContacts) return;
public void run() { if (c.equals(blockedContact)) return;
if (blockContacts) return; Integer count = contactCounts.get(c);
if (c.equals(blockedContact)) return; if (count == null) contactCounts.put(c, 1);
Integer count = contactCounts.get(c); else contactCounts.put(c, count + 1);
if (count == null) contactCounts.put(c, 1); contactTotal++;
else contactCounts.put(c, count + 1); updateContactNotification(true);
contactTotal++;
updateContactNotification(true);
}
}); });
} }
@Override @Override
public void clearContactNotification(final ContactId c) { public void clearContactNotification(final ContactId c) {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread(() -> {
@Override Integer count = contactCounts.remove(c);
public void run() { if (count == null) return; // Already cleared
Integer count = contactCounts.remove(c); contactTotal -= count;
if (count == null) return; // Already cleared updateContactNotification(false);
contactTotal -= count;
updateContactNotification(false);
}
}); });
} }
@@ -358,40 +345,30 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
@Override @Override
public void clearAllContactNotifications() { public void clearAllContactNotifications() {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread(
@Override (Runnable) this::clearContactNotification);
public void run() {
clearContactNotification();
}
});
} }
@UiThread @UiThread
private void showGroupMessageNotification(final GroupId g) { private void showGroupMessageNotification(final GroupId g) {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread(() -> {
@Override if (blockGroups) return;
public void run() { if (g.equals(blockedGroup)) return;
if (blockGroups) return; Integer count = groupCounts.get(g);
if (g.equals(blockedGroup)) return; if (count == null) groupCounts.put(g, 1);
Integer count = groupCounts.get(g); else groupCounts.put(g, count + 1);
if (count == null) groupCounts.put(g, 1); groupTotal++;
else groupCounts.put(g, count + 1); updateGroupMessageNotification(true);
groupTotal++;
updateGroupMessageNotification(true);
}
}); });
} }
@Override @Override
public void clearGroupMessageNotification(final GroupId g) { public void clearGroupMessageNotification(final GroupId g) {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread(() -> {
@Override Integer count = groupCounts.remove(g);
public void run() { if (count == null) return; // Already cleared
Integer count = groupCounts.remove(g); groupTotal -= count;
if (count == null) return; // Already cleared updateGroupMessageNotification(false);
groupTotal -= count;
updateGroupMessageNotification(false);
}
}); });
} }
@@ -445,40 +422,30 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
@Override @Override
public void clearAllGroupMessageNotifications() { public void clearAllGroupMessageNotifications() {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread(
@Override (Runnable) this::clearGroupMessageNotification);
public void run() {
clearGroupMessageNotification();
}
});
} }
@UiThread @UiThread
private void showForumPostNotification(final GroupId g) { private void showForumPostNotification(final GroupId g) {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread(() -> {
@Override if (blockForums) return;
public void run() { if (g.equals(blockedGroup)) return;
if (blockForums) return; Integer count = forumCounts.get(g);
if (g.equals(blockedGroup)) return; if (count == null) forumCounts.put(g, 1);
Integer count = forumCounts.get(g); else forumCounts.put(g, count + 1);
if (count == null) forumCounts.put(g, 1); forumTotal++;
else forumCounts.put(g, count + 1); updateForumPostNotification(true);
forumTotal++;
updateForumPostNotification(true);
}
}); });
} }
@Override @Override
public void clearForumPostNotification(final GroupId g) { public void clearForumPostNotification(final GroupId g) {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread(() -> {
@Override Integer count = forumCounts.remove(g);
public void run() { if (count == null) return; // Already cleared
Integer count = forumCounts.remove(g); forumTotal -= count;
if (count == null) return; // Already cleared updateForumPostNotification(false);
forumTotal -= count;
updateForumPostNotification(false);
}
}); });
} }
@@ -532,40 +499,30 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
@Override @Override
public void clearAllForumPostNotifications() { public void clearAllForumPostNotifications() {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread(
@Override (Runnable) this::clearForumPostNotification);
public void run() {
clearForumPostNotification();
}
});
} }
@UiThread @UiThread
private void showBlogPostNotification(final GroupId g) { private void showBlogPostNotification(final GroupId g) {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread(() -> {
@Override if (blockBlogs) return;
public void run() { if (g.equals(blockedGroup)) return;
if (blockBlogs) return; Integer count = blogCounts.get(g);
if (g.equals(blockedGroup)) return; if (count == null) blogCounts.put(g, 1);
Integer count = blogCounts.get(g); else blogCounts.put(g, count + 1);
if (count == null) blogCounts.put(g, 1); blogTotal++;
else blogCounts.put(g, count + 1); updateBlogPostNotification(true);
blogTotal++;
updateBlogPostNotification(true);
}
}); });
} }
@Override @Override
public void clearBlogPostNotification(final GroupId g) { public void clearBlogPostNotification(final GroupId g) {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread(() -> {
@Override Integer count = blogCounts.remove(g);
public void run() { if (count == null) return; // Already cleared
Integer count = blogCounts.remove(g); blogTotal -= count;
if (count == null) return; // Already cleared updateBlogPostNotification(false);
blogTotal -= count;
updateBlogPostNotification(false);
}
}); });
} }
@@ -606,22 +563,15 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
@Override @Override
public void clearAllBlogPostNotifications() { public void clearAllBlogPostNotifications() {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread(
@Override (Runnable) this::clearBlogPostNotification);
public void run() {
clearBlogPostNotification();
}
});
} }
private void showIntroductionNotification() { private void showIntroductionNotification() {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread(() -> {
@Override if (blockIntroductions) return;
public void run() { introductionTotal++;
if (blockIntroductions) return; updateIntroductionNotification();
introductionTotal++;
updateIntroductionNotification();
}
}); });
} }
@@ -656,71 +606,41 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
@Override @Override
public void clearAllIntroductionNotifications() { public void clearAllIntroductionNotifications() {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread(
@Override this::clearIntroductionSuccessNotification);
public void run() {
clearIntroductionSuccessNotification();
}
});
} }
@Override @Override
public void blockNotification(final GroupId g) { public void blockNotification(final GroupId g) {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread((Runnable) () -> blockedGroup = g);
@Override
public void run() {
blockedGroup = g;
}
});
} }
@Override @Override
public void unblockNotification(final GroupId g) { public void unblockNotification(final GroupId g) {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread(() -> {
@Override if (g.equals(blockedGroup)) blockedGroup = null;
public void run() {
if (g.equals(blockedGroup)) blockedGroup = null;
}
}); });
} }
@Override @Override
public void blockContactNotification(final ContactId c) { public void blockContactNotification(final ContactId c) {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread((Runnable) () -> blockedContact = c);
@Override
public void run() {
blockedContact = c;
}
});
} }
@Override @Override
public void unblockContactNotification(final ContactId c) { public void unblockContactNotification(final ContactId c) {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread(() -> {
@Override if (c.equals(blockedContact)) blockedContact = null;
public void run() {
if (c.equals(blockedContact)) blockedContact = null;
}
}); });
} }
@Override @Override
public void blockAllBlogPostNotifications() { public void blockAllBlogPostNotifications() {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread((Runnable) () -> blockBlogs = true);
@Override
public void run() {
blockBlogs = true;
}
});
} }
@Override @Override
public void unblockAllBlogPostNotifications() { public void unblockAllBlogPostNotifications() {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread((Runnable) () -> blockBlogs = false);
@Override
public void run() {
blockBlogs = false;
}
});
} }
} }

View File

@@ -112,33 +112,30 @@ public class BriarService extends Service {
} }
private void showStartupFailureNotification(final StartResult result) { private void showStartupFailureNotification(final StartResult result) {
androidExecutor.runOnUiThread(new Runnable() { androidExecutor.runOnUiThread(() -> {
@Override NotificationCompat.Builder b =
public void run() { new NotificationCompat.Builder(BriarService.this);
NotificationCompat.Builder b = b.setSmallIcon(android.R.drawable.stat_notify_error);
new NotificationCompat.Builder(BriarService.this); b.setContentTitle(getText(
b.setSmallIcon(android.R.drawable.stat_notify_error); R.string.startup_failed_notification_title));
b.setContentTitle(getText( b.setContentText(getText(
R.string.startup_failed_notification_title)); R.string.startup_failed_notification_text));
b.setContentText(getText( Intent i = new Intent(BriarService.this,
R.string.startup_failed_notification_text)); StartupFailureActivity.class);
Intent i = new Intent(BriarService.this, i.setFlags(FLAG_ACTIVITY_NEW_TASK);
StartupFailureActivity.class); i.putExtra("briar.START_RESULT", result);
i.setFlags(FLAG_ACTIVITY_NEW_TASK); i.putExtra("briar.FAILURE_NOTIFICATION_ID",
i.putExtra("briar.START_RESULT", result); FAILURE_NOTIFICATION_ID);
i.putExtra("briar.FAILURE_NOTIFICATION_ID", b.setContentIntent(PendingIntent.getActivity(BriarService.this,
FAILURE_NOTIFICATION_ID); 0, i, FLAG_UPDATE_CURRENT));
b.setContentIntent(PendingIntent.getActivity(BriarService.this, Object o = getSystemService(NOTIFICATION_SERVICE);
0, i, FLAG_UPDATE_CURRENT)); NotificationManager nm = (NotificationManager) o;
Object o = getSystemService(NOTIFICATION_SERVICE); nm.notify(FAILURE_NOTIFICATION_ID, b.build());
NotificationManager nm = (NotificationManager) o; // Bring the dashboard to the front to clear the back stack
nm.notify(FAILURE_NOTIFICATION_ID, b.build()); i = new Intent(BriarService.this, NavDrawerActivity.class);
// Bring the dashboard to the front to clear the back stack i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP);
i = new Intent(BriarService.this, NavDrawerActivity.class); i.putExtra("briar.STARTUP_FAILED", true);
i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP); startActivity(i);
i.putExtra("briar.STARTUP_FAILED", true);
startActivity(i);
}
}); });
} }

View File

@@ -152,11 +152,8 @@ public abstract class BaseActivity extends AppCompatActivity
@Override @Override
public void runOnUiThreadUnlessDestroyed(final Runnable r) { public void runOnUiThreadUnlessDestroyed(final Runnable r) {
runOnUiThread(new Runnable() { runOnUiThread(() -> {
@Override if (!destroyed && !isFinishing()) r.run();
public void run() {
if (!destroyed && !isFinishing()) r.run();
}
}); });
} }

View File

@@ -13,7 +13,6 @@ import android.view.Window;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.android.controller.BriarController; import org.briarproject.briar.android.controller.BriarController;
import org.briarproject.briar.android.controller.DbController; import org.briarproject.briar.android.controller.DbController;
import org.briarproject.briar.android.controller.handler.ResultHandler;
import org.briarproject.briar.android.login.PasswordActivity; import org.briarproject.briar.android.login.PasswordActivity;
import org.briarproject.briar.android.panic.ExitActivity; import org.briarproject.briar.android.panic.ExitActivity;
@@ -102,17 +101,8 @@ public abstract class BriarActivity extends BaseActivity {
if (briarController.hasEncryptionKey()) { if (briarController.hasEncryptionKey()) {
// Don't use UiResultHandler because we want the result even if // Don't use UiResultHandler because we want the result even if
// this activity has been destroyed // this activity has been destroyed
briarController.signOut(new ResultHandler<Void>() { briarController.signOut(result -> runOnUiThread(
@Override () -> exit(removeFromRecentApps)));
public void onResult(Void result) {
runOnUiThread(new Runnable() {
@Override
public void run() {
exit(removeFromRecentApps);
}
});
}
});
} else { } else {
exit(removeFromRecentApps); exit(removeFromRecentApps);
} }
@@ -146,11 +136,6 @@ public abstract class BriarActivity extends BaseActivity {
@Deprecated @Deprecated
protected void finishOnUiThread() { protected void finishOnUiThread() {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(this::supportFinishAfterTransition);
@Override
public void run() {
supportFinishAfterTransition();
}
});
} }
} }

View File

@@ -85,38 +85,25 @@ abstract class BaseControllerImpl extends DbControllerImpl
} }
void onBlogPostAdded(final BlogPostHeader h, final boolean local) { void onBlogPostAdded(final BlogPostHeader h, final boolean local) {
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(
@Override () -> listener.onBlogPostAdded(h, local));
public void run() {
listener.onBlogPostAdded(h, local);
}
});
} }
void onBlogRemoved() { void onBlogRemoved() {
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(() -> listener.onBlogRemoved());
@Override
public void run() {
listener.onBlogRemoved();
}
});
} }
@Override @Override
public void loadBlogPosts(final GroupId groupId, public void loadBlogPosts(final GroupId groupId,
final ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) { final ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { Collection<BlogPostItem> items = loadItems(groupId);
try { handler.onResult(items);
Collection<BlogPostItem> items = loadItems(groupId); } catch (DbException e) {
handler.onResult(items); if (LOG.isLoggable(WARNING))
} catch (DbException e) { LOG.log(WARNING, e.toString(), e);
if (LOG.isLoggable(WARNING)) handler.onException(e);
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
} }
}); });
} }
@@ -151,21 +138,18 @@ abstract class BaseControllerImpl extends DbControllerImpl
handler.onResult(new BlogPostItem(header, body)); handler.onResult(new BlogPostItem(header, body));
return; return;
} }
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { long now = System.currentTimeMillis();
try { BlogPostItem item = getItem(header);
long now = System.currentTimeMillis(); long duration = System.currentTimeMillis() - now;
BlogPostItem item = getItem(header); if (LOG.isLoggable(INFO))
long duration = System.currentTimeMillis() - now; LOG.info("Loading body took " + duration + " ms");
if (LOG.isLoggable(INFO)) handler.onResult(item);
LOG.info("Loading body took " + duration + " ms"); } catch (DbException e) {
handler.onResult(item); if (LOG.isLoggable(WARNING))
} catch (DbException e) { LOG.log(WARNING, e.toString(), e);
if (LOG.isLoggable(WARNING)) handler.onException(e);
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
} }
}); });
} }
@@ -180,22 +164,19 @@ abstract class BaseControllerImpl extends DbControllerImpl
loadBlogPost(header, handler); loadBlogPost(header, handler);
return; return;
} }
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { long now = System.currentTimeMillis();
try { BlogPostHeader header1 = getPostHeader(g, m);
long now = System.currentTimeMillis(); BlogPostItem item = getItem(header1);
BlogPostHeader header = getPostHeader(g, m); long duration = System.currentTimeMillis() - now;
BlogPostItem item = getItem(header); if (LOG.isLoggable(INFO))
long duration = System.currentTimeMillis() - now; LOG.info("Loading post took " + duration + " ms");
if (LOG.isLoggable(INFO)) handler.onResult(item);
LOG.info("Loading post took " + duration + " ms"); } catch (DbException e) {
handler.onResult(item); if (LOG.isLoggable(WARNING))
} catch (DbException e) { LOG.log(WARNING, e.toString(), e);
if (LOG.isLoggable(WARNING)) handler.onException(e);
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
} }
}); });
} }
@@ -204,19 +185,16 @@ abstract class BaseControllerImpl extends DbControllerImpl
public void repeatPost(final BlogPostItem item, public void repeatPost(final BlogPostItem item,
final @Nullable String comment, final @Nullable String comment,
final ExceptionHandler<DbException> handler) { final ExceptionHandler<DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { LocalAuthor a = identityManager.getLocalAuthor();
try { Blog b = blogManager.getPersonalBlog(a);
LocalAuthor a = identityManager.getLocalAuthor(); BlogPostHeader h = item.getHeader();
Blog b = blogManager.getPersonalBlog(a); blogManager.addLocalComment(a, b.getId(), comment, h);
BlogPostHeader h = item.getHeader(); } catch (DbException e) {
blogManager.addLocalComment(a, b.getId(), comment, h); if (LOG.isLoggable(WARNING))
} catch (DbException e) { LOG.log(WARNING, e.toString(), e);
if (LOG.isLoggable(WARNING)) handler.onException(e);
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
} }
}); });
} }

View File

@@ -99,13 +99,10 @@ abstract class BasePostFragment extends BaseFragment {
} }
private void startPeriodicUpdate() { private void startPeriodicUpdate() {
refresher = new Runnable() { refresher = () -> {
@Override LOG.info("Updating Content...");
public void run() { ui.updateDate(post.getTimestamp());
LOG.info("Updating Content..."); handler.postDelayed(refresher, MIN_DATE_RESOLUTION);
ui.updateDate(post.getTimestamp());
handler.postDelayed(refresher, MIN_DATE_RESOLUTION);
}
}; };
LOG.info("Adding Handler Callback"); LOG.info("Adding Handler Callback");
handler.postDelayed(refresher, MIN_DATE_RESOLUTION); handler.postDelayed(refresher, MIN_DATE_RESOLUTION);

View File

@@ -3,7 +3,6 @@ package org.briarproject.briar.android.blog;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.view.View;
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;
@@ -41,16 +40,12 @@ public class BlogActivity extends BriarActivity
// Open Sharing Status on Toolbar click // Open Sharing Status on Toolbar click
if (toolbar != null) { if (toolbar != null) {
toolbar.setOnClickListener( toolbar.setOnClickListener(v -> {
new View.OnClickListener() { Intent i1 = new Intent(BlogActivity.this,
@Override BlogSharingStatusActivity.class);
public void onClick(View v) { i1.putExtra(GROUP_ID, groupId.getBytes());
Intent i = new Intent(BlogActivity.this, startActivity(i1);
BlogSharingStatusActivity.class); });
i.putExtra(GROUP_ID, groupId.getBytes());
startActivity(i);
}
});
} }
if (state == null) { if (state == null) {

View File

@@ -126,21 +126,12 @@ class BlogControllerImpl extends BaseControllerImpl
} }
private void onBlogInvitationAccepted(final ContactId c) { private void onBlogInvitationAccepted(final ContactId c) {
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(
@Override () -> listener.onBlogInvitationAccepted(c));
public void run() {
listener.onBlogInvitationAccepted(c);
}
});
} }
private void onBlogLeft(final ContactId c) { private void onBlogLeft(final ContactId c) {
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(() -> listener.onBlogLeft(c));
@Override
public void run() {
listener.onBlogLeft(c);
}
});
} }
@Override @Override
@@ -161,25 +152,22 @@ class BlogControllerImpl extends BaseControllerImpl
public void loadBlog( public void loadBlog(
final ResultExceptionHandler<BlogItem, DbException> handler) { final ResultExceptionHandler<BlogItem, DbException> handler) {
if (groupId == null) throw new IllegalStateException(); if (groupId == null) throw new IllegalStateException();
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { long now = System.currentTimeMillis();
try { LocalAuthor a = identityManager.getLocalAuthor();
long now = System.currentTimeMillis(); Blog b = blogManager.getBlog(groupId);
LocalAuthor a = identityManager.getLocalAuthor(); boolean ours = a.getId().equals(b.getAuthor().getId());
Blog b = blogManager.getBlog(groupId); boolean removable = blogManager.canBeRemoved(b);
boolean ours = a.getId().equals(b.getAuthor().getId()); BlogItem blog = new BlogItem(b, ours, removable);
boolean removable = blogManager.canBeRemoved(b); long duration = System.currentTimeMillis() - now;
BlogItem blog = new BlogItem(b, ours, removable); if (LOG.isLoggable(INFO))
long duration = System.currentTimeMillis() - now; LOG.info("Loading blog took " + duration + " ms");
if (LOG.isLoggable(INFO)) handler.onResult(blog);
LOG.info("Loading blog took " + duration + " ms"); } catch (DbException e) {
handler.onResult(blog); if (LOG.isLoggable(WARNING))
} catch (DbException e) { LOG.log(WARNING, e.toString(), e);
if (LOG.isLoggable(WARNING)) handler.onException(e);
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
} }
}); });
} }
@@ -188,22 +176,19 @@ class BlogControllerImpl extends BaseControllerImpl
public void deleteBlog( public void deleteBlog(
final ResultExceptionHandler<Void, DbException> handler) { final ResultExceptionHandler<Void, DbException> handler) {
if (groupId == null) throw new IllegalStateException(); if (groupId == null) throw new IllegalStateException();
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { long now = System.currentTimeMillis();
try { Blog b = blogManager.getBlog(groupId);
long now = System.currentTimeMillis(); blogManager.removeBlog(b);
Blog b = blogManager.getBlog(groupId); long duration = System.currentTimeMillis() - now;
blogManager.removeBlog(b); if (LOG.isLoggable(INFO))
long duration = System.currentTimeMillis() - now; LOG.info("Removing blog took " + duration + " ms");
if (LOG.isLoggable(INFO)) handler.onResult(null);
LOG.info("Removing blog took " + duration + " ms"); } catch (DbException e) {
handler.onResult(null); if (LOG.isLoggable(WARNING))
} catch (DbException e) { LOG.log(WARNING, e.toString(), e);
if (LOG.isLoggable(WARNING)) handler.onException(e);
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
} }
}); });
} }
@@ -212,21 +197,18 @@ class BlogControllerImpl extends BaseControllerImpl
public void loadSharingContacts( public void loadSharingContacts(
final ResultExceptionHandler<Collection<ContactId>, DbException> handler) { final ResultExceptionHandler<Collection<ContactId>, DbException> handler) {
if (groupId == null) throw new IllegalStateException(); if (groupId == null) throw new IllegalStateException();
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { Collection<Contact> contacts =
try { blogSharingManager.getSharedWith(groupId);
Collection<Contact> contacts = Collection<ContactId> contactIds =
blogSharingManager.getSharedWith(groupId); new ArrayList<>(contacts.size());
Collection<ContactId> contactIds = for (Contact c : contacts) contactIds.add(c.getId());
new ArrayList<>(contacts.size()); handler.onResult(contactIds);
for (Contact c : contacts) contactIds.add(c.getId()); } catch (DbException e) {
handler.onResult(contactIds); if (LOG.isLoggable(WARNING))
} catch (DbException e) { LOG.log(WARNING, e.toString(), e);
if (LOG.isLoggable(WARNING)) handler.onException(e);
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
} }
}); });
} }

View File

@@ -331,12 +331,7 @@ public class BlogFragment extends BaseFragment
Snackbar.make(list, stringId, Snackbar.LENGTH_LONG); Snackbar.make(list, stringId, Snackbar.LENGTH_LONG);
snackbar.getView().setBackgroundResource(R.color.briar_primary); snackbar.getView().setBackgroundResource(R.color.briar_primary);
if (scroll) { if (scroll) {
View.OnClickListener onClick = new View.OnClickListener() { View.OnClickListener onClick = v -> list.smoothScrollToPosition(0);
@Override
public void onClick(View v) {
list.smoothScrollToPosition(0);
}
};
snackbar.setActionTextColor(ContextCompat snackbar.setActionTextColor(ContextCompat
.getColor(getContext(), .getColor(getContext(),
R.color.briar_button_positive)); R.color.briar_button_positive));
@@ -347,12 +342,7 @@ public class BlogFragment extends BaseFragment
private void showDeleteDialog() { private void showDeleteDialog() {
DialogInterface.OnClickListener okListener = DialogInterface.OnClickListener okListener =
new DialogInterface.OnClickListener() { (dialog, which) -> deleteBlog();
@Override
public void onClick(DialogInterface dialog, int which) {
deleteBlog();
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(),
R.style.BriarDialogTheme); R.style.BriarDialogTheme);
builder.setTitle(getString(R.string.blogs_remove_blog)); builder.setTitle(getString(R.string.blogs_remove_blog));

View File

@@ -13,7 +13,6 @@ import android.support.v7.widget.RecyclerView;
import android.text.Spanned; import android.text.Spanned;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
@@ -95,12 +94,7 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
setTransitionName(item.getId()); setTransitionName(item.getId());
if (!fullText) { if (!fullText) {
layout.setClickable(true); layout.setClickable(true);
layout.setOnClickListener(new OnClickListener() { layout.setOnClickListener(v -> listener.onBlogPostClick(item));
@Override
public void onClick(View v) {
listener.onBlogPostClick(item);
}
});
} }
// author and date // author and date
@@ -113,12 +107,7 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
item.isRssFeed() ? AuthorView.RSS_FEED : AuthorView.NORMAL); item.isRssFeed() ? AuthorView.RSS_FEED : AuthorView.NORMAL);
// TODO make author clickable more often #624 // TODO make author clickable more often #624
if (!fullText && item.getHeader().getType() == POST) { if (!fullText && item.getHeader().getType() == POST) {
author.setAuthorClickable(new OnClickListener() { author.setAuthorClickable(v -> listener.onAuthorClick(item));
@Override
public void onClick(View v) {
listener.onAuthorClick(item);
}
});
} else { } else {
author.setAuthorNotClickable(); author.setAuthorNotClickable();
} }
@@ -137,23 +126,20 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
} }
// reblog button // reblog button
reblogButton.setOnClickListener(new OnClickListener() { reblogButton.setOnClickListener(v -> {
@Override Intent i = new Intent(ctx, ReblogActivity.class);
public void onClick(View v) { i.putExtra(GROUP_ID, item.getGroupId().getBytes());
Intent i = new Intent(ctx, ReblogActivity.class); i.putExtra(POST_ID, item.getId().getBytes());
i.putExtra(GROUP_ID, item.getGroupId().getBytes());
i.putExtra(POST_ID, item.getId().getBytes());
if (Build.VERSION.SDK_INT >= 23) { if (Build.VERSION.SDK_INT >= 23) {
ActivityOptionsCompat options = ActivityOptionsCompat options =
makeSceneTransitionAnimation((Activity) ctx, layout, makeSceneTransitionAnimation((Activity) ctx, layout,
getTransitionName(item.getId())); getTransitionName(item.getId()));
ActivityCompat.startActivity((Activity) ctx, i, ActivityCompat.startActivity((Activity) ctx, i,
options.toBundle()); options.toBundle());
} else { } else {
// work-around for android bug #224270 // work-around for android bug #224270
ctx.startActivity(i); ctx.startActivity(i);
}
} }
}); });
@@ -172,12 +158,7 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
reblogger.setAuthorStatus(item.getAuthorStatus()); reblogger.setAuthorStatus(item.getAuthorStatus());
reblogger.setDate(item.getTimestamp()); reblogger.setDate(item.getTimestamp());
if (!fullText) { if (!fullText) {
reblogger.setAuthorClickable(new OnClickListener() { reblogger.setAuthorClickable(v -> listener.onAuthorClick(item));
@Override
public void onClick(View v) {
listener.onAuthorClick(item);
}
});
} }
reblogger.setVisibility(VISIBLE); reblogger.setVisibility(VISIBLE);
reblogger.setPersona(AuthorView.REBLOGGER); reblogger.setPersona(AuthorView.REBLOGGER);

View File

@@ -91,40 +91,31 @@ class FeedControllerImpl extends BaseControllerImpl
} }
private void onBlogAdded() { private void onBlogAdded() {
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(() -> listener.onBlogAdded());
@Override
public void run() {
listener.onBlogAdded();
}
});
} }
@Override @Override
public void loadBlogPosts( public void loadBlogPosts(
final ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) { final ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { long now = System.currentTimeMillis();
try { Collection<BlogPostItem> posts = new ArrayList<>();
long now = System.currentTimeMillis(); for (Blog b : blogManager.getBlogs()) {
Collection<BlogPostItem> posts = new ArrayList<>(); try {
for (Blog b : blogManager.getBlogs()) { posts.addAll(loadItems(b.getId()));
try { } catch (NoSuchGroupException | NoSuchMessageException e) {
posts.addAll(loadItems(b.getId())); if (LOG.isLoggable(WARNING))
} catch (NoSuchGroupException | NoSuchMessageException e) { LOG.log(WARNING, e.toString(), e);
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading all posts took " + duration + " ms");
handler.onResult(posts);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading all posts took " + duration + " ms");
handler.onResult(posts);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
}); });
} }
@@ -132,22 +123,18 @@ class FeedControllerImpl extends BaseControllerImpl
@Override @Override
public void loadPersonalBlog( public void loadPersonalBlog(
final ResultExceptionHandler<Blog, DbException> handler) { final ResultExceptionHandler<Blog, DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { long now = System.currentTimeMillis();
try { Author a = identityManager.getLocalAuthor();
long now = System.currentTimeMillis(); Blog b = blogManager.getPersonalBlog(a);
Author a = identityManager.getLocalAuthor(); long duration = System.currentTimeMillis() - now;
Blog b = blogManager.getPersonalBlog(a); if (LOG.isLoggable(INFO))
long duration = System.currentTimeMillis() - now; LOG.info("Loading blog took " + duration + " ms");
if (LOG.isLoggable(INFO)) handler.onResult(b);
LOG.info("Loading blog took " + duration + " ms"); } catch (DbException e) {
handler.onResult(b); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) { handler.onException(e);
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
} }
}); });
} }

View File

@@ -246,12 +246,7 @@ public class FeedFragment extends BaseFragment implements
Snackbar s = Snackbar.make(list, stringRes, LENGTH_LONG); Snackbar s = Snackbar.make(list, stringRes, LENGTH_LONG);
s.getView().setBackgroundResource(R.color.briar_primary); s.getView().setBackgroundResource(R.color.briar_primary);
if (scroll) { if (scroll) {
OnClickListener onClick = new OnClickListener() { OnClickListener onClick = v -> list.smoothScrollToPosition(0);
@Override
public void onClick(View v) {
list.smoothScrollToPosition(0);
}
};
s.setActionTextColor(ContextCompat s.setActionTextColor(ContextCompat
.getColor(getContext(), .getColor(getContext(),
R.color.briar_button_positive)); R.color.briar_button_positive));

View File

@@ -114,12 +114,7 @@ public class ReblogFragment extends BaseFragment implements TextInputListener {
ui.input.setListener(this); ui.input.setListener(this);
ui.input.setSendButtonEnabled(true); ui.input.setSendButtonEnabled(true);
ui.scrollView.post(new Runnable() { ui.scrollView.post(() -> ui.scrollView.fullScroll(FOCUS_DOWN));
@Override
public void run() {
ui.scrollView.fullScroll(FOCUS_DOWN);
}
});
} }
@Override @Override

View File

@@ -4,7 +4,6 @@ import android.content.Context;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.TextView; import android.widget.TextView;
@@ -42,12 +41,7 @@ class RssFeedAdapter extends BriarAdapter<Feed, RssFeedAdapter.FeedViewHolder> {
ui.title.setText(item.getTitle()); ui.title.setText(item.getTitle());
// Delete Button // Delete Button
ui.delete.setOnClickListener(new OnClickListener() { ui.delete.setOnClickListener(v -> listener.onDeleteClick(item));
@Override
public void onClick(View v) {
listener.onDeleteClick(item);
}
});
// Author // Author
if (item.getAuthor() != null) { if (item.getAuthor() != null) {
@@ -72,12 +66,7 @@ class RssFeedAdapter extends BriarAdapter<Feed, RssFeedAdapter.FeedViewHolder> {
} }
// Open feed's blog when clicked // Open feed's blog when clicked
ui.layout.setOnClickListener(new OnClickListener() { ui.layout.setOnClickListener(v -> listener.onFeedClick(item));
@Override
public void onClick(View v) {
listener.onFeedClick(item);
}
});
} }
@Override @Override

View File

@@ -1,6 +1,5 @@
package org.briarproject.briar.android.blog; package org.briarproject.briar.android.blog;
import android.content.DialogInterface;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.text.Editable; import android.text.Editable;
@@ -8,7 +7,6 @@ import android.text.TextWatcher;
import android.util.Patterns; import android.util.Patterns;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ProgressBar; import android.widget.ProgressBar;
@@ -75,12 +73,7 @@ public class RssFeedImportActivity extends BriarActivity {
}); });
importButton = (Button) findViewById(R.id.importButton); importButton = (Button) findViewById(R.id.importButton);
importButton.setOnClickListener(new View.OnClickListener() { importButton.setOnClickListener(v -> publish());
@Override
public void onClick(View v) {
publish();
}
});
progressBar = (ProgressBar) findViewById(R.id.progressBar); progressBar = (ProgressBar) findViewById(R.id.progressBar);
} }
@@ -126,54 +119,37 @@ public class RssFeedImportActivity extends BriarActivity {
} }
private void importFeed(final String url) { private void importFeed(final String url) {
ioExecutor.execute(new Runnable() { ioExecutor.execute(() -> {
@Override try {
public void run() { feedManager.addFeed(url);
try { feedImported();
feedManager.addFeed(url); } catch (DbException | IOException e) {
feedImported(); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException | IOException e) { importFailed();
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
importFailed();
}
} }
}); });
} }
private void feedImported() { private void feedImported() {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(this::supportFinishAfterTransition);
@Override
public void run() {
supportFinishAfterTransition();
}
});
} }
private void importFailed() { private void importFailed() {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override // hide progress bar, show publish button
public void run() { progressBar.setVisibility(GONE);
// hide progress bar, show publish button importButton.setVisibility(VISIBLE);
progressBar.setVisibility(GONE);
importButton.setVisibility(VISIBLE);
// show error dialog // show error dialog
AlertDialog.Builder builder = AlertDialog.Builder builder =
new AlertDialog.Builder(RssFeedImportActivity.this, new AlertDialog.Builder(RssFeedImportActivity.this,
R.style.BriarDialogTheme); R.style.BriarDialogTheme);
builder.setMessage(R.string.blogs_rss_feeds_import_error); builder.setMessage(R.string.blogs_rss_feeds_import_error);
builder.setNegativeButton(R.string.cancel, null); builder.setNegativeButton(R.string.cancel, null);
builder.setPositiveButton(R.string.try_again_button, builder.setPositiveButton(R.string.try_again_button,
new DialogInterface.OnClickListener() { (dialog, which) -> publish());
@Override AlertDialog dialog = builder.create();
public void onClick(DialogInterface dialog, int which) { dialog.show();
publish();
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
}); });
} }

View File

@@ -105,12 +105,7 @@ public class RssFeedManageActivity extends BriarActivity
@Override @Override
public void onDeleteClick(final Feed feed) { public void onDeleteClick(final Feed feed) {
DialogInterface.OnClickListener okListener = DialogInterface.OnClickListener okListener =
new DialogInterface.OnClickListener() { (dialog, which) -> deleteFeed(feed);
@Override
public void onClick(DialogInterface dialog, int which) {
deleteFeed(feed);
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this, AlertDialog.Builder builder = new AlertDialog.Builder(this,
R.style.BriarDialogTheme); R.style.BriarDialogTheme);
builder.setTitle(getString(R.string.blogs_rss_remove_feed)); builder.setTitle(getString(R.string.blogs_rss_remove_feed));
@@ -124,81 +119,59 @@ public class RssFeedManageActivity extends BriarActivity
private void loadFeeds() { private void loadFeeds() {
final int revision = adapter.getRevision(); final int revision = adapter.getRevision();
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { displayFeeds(revision, feedManager.getFeeds());
try { } catch (DbException e) {
displayFeeds(revision, feedManager.getFeeds()); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) { onLoadError();
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
onLoadError();
}
} }
}); });
} }
private void displayFeeds(final int revision, final List<Feed> feeds) { private void displayFeeds(final int revision, final List<Feed> feeds) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override if (revision == adapter.getRevision()) {
public void run() { adapter.incrementRevision();
if (revision == adapter.getRevision()) { if (feeds.isEmpty()) list.showData();
adapter.incrementRevision(); else adapter.addAll(feeds);
if (feeds.isEmpty()) list.showData(); } else {
else adapter.addAll(feeds); LOG.info("Concurrent update, reloading");
} else { loadFeeds();
LOG.info("Concurrent update, reloading");
loadFeeds();
}
} }
}); });
} }
private void deleteFeed(final Feed feed) { private void deleteFeed(final Feed feed) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { feedManager.removeFeed(feed);
try { onFeedDeleted(feed);
feedManager.removeFeed(feed); } catch (DbException e) {
onFeedDeleted(feed); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) { onDeleteError();
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
onDeleteError();
}
} }
}); });
} }
private void onLoadError() { private void onLoadError() {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override list.setEmptyText(R.string.blogs_rss_feeds_manage_error);
public void run() { list.showData();
list.setEmptyText(R.string.blogs_rss_feeds_manage_error);
list.showData();
}
}); });
} }
private void onFeedDeleted(final Feed feed) { private void onFeedDeleted(final Feed feed) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override adapter.incrementRevision();
public void run() { adapter.remove(feed);
adapter.incrementRevision();
adapter.remove(feed);
}
}); });
} }
private void onDeleteError() { private void onDeleteError() {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> Snackbar.make(list,
@Override R.string.blogs_rss_feeds_manage_delete_error,
public void run() { LENGTH_LONG).show());
Snackbar.make(list,
R.string.blogs_rss_feeds_manage_delete_error,
LENGTH_LONG).show();
}
});
} }
} }

View File

@@ -141,44 +141,35 @@ public class WriteBlogPostActivity extends BriarActivity
} }
private void storePost(final String body) { private void storePost(final String body) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override long now = System.currentTimeMillis();
public void run() { try {
long now = System.currentTimeMillis(); LocalAuthor author = identityManager.getLocalAuthor();
try { BlogPost p = blogPostFactory
LocalAuthor author = identityManager.getLocalAuthor(); .createBlogPost(groupId, now, null, author, body);
BlogPost p = blogPostFactory blogManager.addLocalPost(p);
.createBlogPost(groupId, now, null, author, body); postPublished();
blogManager.addLocalPost(p); } catch (DbException | GeneralSecurityException
postPublished(); | FormatException e) {
} catch (DbException | GeneralSecurityException | FormatException e) { if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
if (LOG.isLoggable(WARNING)) postFailedToPublish();
LOG.log(WARNING, e.toString(), e);
postFailedToPublish();
}
} }
}); });
} }
private void postPublished() { private void postPublished() {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override setResult(RESULT_OK);
public void run() { supportFinishAfterTransition();
setResult(RESULT_OK);
supportFinishAfterTransition();
}
}); });
} }
private void postFailedToPublish() { private void postFailedToPublish() {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override // hide progress bar, show publish button
public void run() { progressBar.setVisibility(GONE);
// hide progress bar, show publish button input.setVisibility(VISIBLE);
progressBar.setVisibility(GONE); // TODO show error
input.setVisibility(VISIBLE);
// TODO show error
}
}); });
} }
} }

View File

@@ -54,11 +54,8 @@ public class ContactItemViewHolder<I extends ContactItem>
} }
} }
layout.setOnClickListener(new View.OnClickListener() { layout.setOnClickListener(v -> {
@Override if (listener != null) listener.onItemClick(avatar, item);
public void onClick(View v) {
if (listener != null) listener.onItemClick(avatar, item);
}
}); });
} }

View File

@@ -114,36 +114,32 @@ public class ContactListFragment extends BaseFragment implements EventListener {
View contentView = inflater.inflate(R.layout.list, container, false); View contentView = inflater.inflate(R.layout.list, container, false);
OnContactClickListener<ContactListItem> onContactClickListener = OnContactClickListener<ContactListItem> onContactClickListener =
new OnContactClickListener<ContactListItem>() { (view, item) -> {
@Override Intent i = new Intent(getActivity(),
public void onItemClick(View view, ContactListItem item) { ConversationActivity.class);
Intent i = new Intent(getActivity(), ContactId contactId = item.getContact().getId();
ConversationActivity.class); i.putExtra(CONTACT_ID, contactId.getInt());
ContactId contactId = item.getContact().getId();
i.putExtra(CONTACT_ID, contactId.getInt());
if (Build.VERSION.SDK_INT >= 23) { if (Build.VERSION.SDK_INT >= 23) {
ContactListItemViewHolder holder = ContactListItemViewHolder holder =
(ContactListItemViewHolder) list (ContactListItemViewHolder) list
.getRecyclerView() .getRecyclerView()
.findViewHolderForAdapterPosition( .findViewHolderForAdapterPosition(
adapter.findItemPosition( adapter.findItemPosition(item));
item)); Pair<View, String> avatar =
Pair<View, String> avatar = Pair.create(holder.avatar,
Pair.create((View) holder.avatar, getTransitionName(holder.avatar));
getTransitionName(holder.avatar)); Pair<View, String> bulb =
Pair<View, String> bulb = Pair.create(holder.bulb,
Pair.create((View) holder.bulb, getTransitionName(holder.bulb));
getTransitionName(holder.bulb)); ActivityOptionsCompat options =
ActivityOptionsCompat options = makeSceneTransitionAnimation(getActivity(),
makeSceneTransitionAnimation(getActivity(), avatar, bulb);
avatar, bulb); ActivityCompat.startActivity(getActivity(), i,
ActivityCompat.startActivity(getActivity(), i, options.toBundle());
options.toBundle()); } else {
} else { // work-around for android bug #224270
// work-around for android bug #224270 startActivity(i);
startActivity(i);
}
} }
}; };
adapter = new ContactListAdapter(getContext(), onContactClickListener); adapter = new ContactListAdapter(getContext(), onContactClickListener);
@@ -196,50 +192,42 @@ public class ContactListFragment extends BaseFragment implements EventListener {
private void loadContacts() { private void loadContacts() {
final int revision = adapter.getRevision(); final int revision = adapter.getRevision();
listener.runOnDbThread(new Runnable() { listener.runOnDbThread(() -> {
@Override try {
public void run() { long now = System.currentTimeMillis();
try { List<ContactListItem> contacts = new ArrayList<>();
long now = System.currentTimeMillis(); for (Contact c : contactManager.getActiveContacts()) {
List<ContactListItem> contacts = new ArrayList<>(); try {
for (Contact c : contactManager.getActiveContacts()) { ContactId id = c.getId();
try { GroupCount count =
ContactId id = c.getId(); conversationManager.getGroupCount(id);
GroupCount count = boolean connected =
conversationManager.getGroupCount(id); connectionRegistry.isConnected(c.getId());
boolean connected = contacts.add(new ContactListItem(c, connected, count));
connectionRegistry.isConnected(c.getId()); } catch (NoSuchContactException e) {
contacts.add(new ContactListItem(c, connected, // Continue
count));
} catch (NoSuchContactException e) {
// Continue
}
} }
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Full load took " + duration + " ms");
displayContacts(revision, contacts);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} }
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Full load took " + duration + " ms");
displayContacts(revision, contacts);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }
private void displayContacts(final int revision, private void displayContacts(final int revision,
final List<ContactListItem> contacts) { final List<ContactListItem> contacts) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override if (revision == adapter.getRevision()) {
public void run() { adapter.incrementRevision();
if (revision == adapter.getRevision()) { if (contacts.isEmpty()) list.showData();
adapter.incrementRevision(); else adapter.addAll(contacts);
if (contacts.isEmpty()) list.showData(); } else {
else adapter.addAll(contacts); LOG.info("Concurrent update, reloading");
} else { loadContacts();
LOG.info("Concurrent update, reloading");
loadContacts();
}
} }
}); });
} }
@@ -295,44 +283,35 @@ public class ContactListFragment extends BaseFragment implements EventListener {
} }
private void updateItem(final ContactId c, final BaseMessageHeader h) { private void updateItem(final ContactId c, final BaseMessageHeader h) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override adapter.incrementRevision();
public void run() { int position = adapter.findItemPosition(c);
adapter.incrementRevision(); ContactListItem item = adapter.getItemAt(position);
int position = adapter.findItemPosition(c); if (item != null) {
ContactListItem item = adapter.getItemAt(position); ConversationItem i = ConversationItem.from(getContext(), h);
if (item != null) { item.addMessage(i);
ConversationItem i = ConversationItem.from(getContext(), h); adapter.updateItemAt(position, item);
item.addMessage(i);
adapter.updateItemAt(position, item);
}
} }
}); });
} }
private void removeItem(final ContactId c) { private void removeItem(final ContactId c) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override adapter.incrementRevision();
public void run() { int position = adapter.findItemPosition(c);
adapter.incrementRevision(); ContactListItem item = adapter.getItemAt(position);
int position = adapter.findItemPosition(c); if (item != null) adapter.remove(item);
ContactListItem item = adapter.getItemAt(position);
if (item != null) adapter.remove(item);
}
}); });
} }
private void setConnected(final ContactId c, final boolean connected) { private void setConnected(final ContactId c, final boolean connected) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override adapter.incrementRevision();
public void run() { int position = adapter.findItemPosition(c);
adapter.incrementRevision(); ContactListItem item = adapter.getItemAt(position);
int position = adapter.findItemPosition(c); if (item != null) {
ContactListItem item = adapter.getItemAt(position); item.setConnected(connected);
if (item != null) { adapter.notifyItemChanged(position);
item.setConnected(connected);
adapter.notifyItemChanged(position);
}
} }
}); });
} }

View File

@@ -289,102 +289,83 @@ public class ConversationActivity extends BriarActivity
} }
private void loadContactDetailsAndMessages() { private void loadContactDetailsAndMessages() {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { long now = System.currentTimeMillis();
try { if (contactName == null || contactAuthorId == null) {
long now = System.currentTimeMillis(); Contact contact = contactManager.getContact(contactId);
if (contactName == null || contactAuthorId == null) { contactName = contact.getAuthor().getName();
Contact contact = contactManager.getContact(contactId); contactAuthorId = contact.getAuthor().getId();
contactName = contact.getAuthor().getName();
contactAuthorId = contact.getAuthor().getId();
}
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading contact took " + duration + " ms");
loadMessages();
displayContactDetails();
} catch (NoSuchContactException e) {
finishOnUiThread();
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} }
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading contact took " + duration + " ms");
loadMessages();
displayContactDetails();
} catch (NoSuchContactException e) {
finishOnUiThread();
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }
private void displayContactDetails() { private void displayContactDetails() {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override //noinspection ConstantConditions
public void run() { toolbarAvatar.setImageDrawable(
//noinspection ConstantConditions new IdenticonDrawable(contactAuthorId.getBytes()));
toolbarAvatar.setImageDrawable( toolbarTitle.setText(contactName);
new IdenticonDrawable(contactAuthorId.getBytes()));
toolbarTitle.setText(contactName);
}
}); });
} }
private void displayContactOnlineStatus() { private void displayContactOnlineStatus() {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override if (connectionRegistry.isConnected(contactId)) {
public void run() { toolbarStatus.setImageDrawable(ContextCompat
if (connectionRegistry.isConnected(contactId)) { .getDrawable(ConversationActivity.this,
toolbarStatus.setImageDrawable(ContextCompat R.drawable.contact_online));
.getDrawable(ConversationActivity.this, toolbarStatus
R.drawable.contact_online)); .setContentDescription(getString(R.string.online));
toolbarStatus } else {
.setContentDescription(getString(R.string.online)); toolbarStatus.setImageDrawable(ContextCompat
} else { .getDrawable(ConversationActivity.this,
toolbarStatus.setImageDrawable(ContextCompat R.drawable.contact_offline));
.getDrawable(ConversationActivity.this, toolbarStatus
R.drawable.contact_offline)); .setContentDescription(getString(R.string.offline));
toolbarStatus
.setContentDescription(getString(R.string.offline));
}
} }
}); });
} }
private void loadMessages() { private void loadMessages() {
final int revision = adapter.getRevision(); final int revision = adapter.getRevision();
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { long now = System.currentTimeMillis();
try { Collection<PrivateMessageHeader> headers =
long now = System.currentTimeMillis(); messagingManager.getMessageHeaders(contactId);
Collection<PrivateMessageHeader> headers = Collection<IntroductionMessage> introductions =
messagingManager.getMessageHeaders(contactId); introductionManager.getIntroductionMessages(contactId);
Collection<IntroductionMessage> introductions = Collection<InvitationMessage> forumInvitations =
introductionManager forumSharingManager.getInvitationMessages(contactId);
.getIntroductionMessages(contactId); Collection<InvitationMessage> blogInvitations =
Collection<InvitationMessage> forumInvitations = blogSharingManager.getInvitationMessages(contactId);
forumSharingManager Collection<InvitationMessage> groupInvitations =
.getInvitationMessages(contactId); groupInvitationManager.getInvitationMessages(contactId);
Collection<InvitationMessage> blogInvitations = List<InvitationMessage> invitations = new ArrayList<>(
blogSharingManager forumInvitations.size() + blogInvitations.size() +
.getInvitationMessages(contactId); groupInvitations.size());
Collection<InvitationMessage> groupInvitations = invitations.addAll(forumInvitations);
groupInvitationManager invitations.addAll(blogInvitations);
.getInvitationMessages(contactId); invitations.addAll(groupInvitations);
List<InvitationMessage> invitations = new ArrayList<>( long duration = System.currentTimeMillis() - now;
forumInvitations.size() + blogInvitations.size() + if (LOG.isLoggable(INFO))
groupInvitations.size()); LOG.info("Loading messages took " + duration + " ms");
invitations.addAll(forumInvitations); displayMessages(revision, headers, introductions, invitations);
invitations.addAll(blogInvitations); } catch (NoSuchContactException e) {
invitations.addAll(groupInvitations); finishOnUiThread();
long duration = System.currentTimeMillis() - now; } catch (DbException e) {
if (LOG.isLoggable(INFO)) if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
LOG.info("Loading messages took " + duration + " ms");
displayMessages(revision, headers, introductions,
invitations);
} catch (NoSuchContactException e) {
finishOnUiThread();
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
}); });
} }
@@ -393,22 +374,19 @@ public class ConversationActivity extends BriarActivity
final Collection<PrivateMessageHeader> headers, final Collection<PrivateMessageHeader> headers,
final Collection<IntroductionMessage> introductions, final Collection<IntroductionMessage> introductions,
final Collection<InvitationMessage> invitations) { final Collection<InvitationMessage> invitations) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override if (revision == adapter.getRevision()) {
public void run() { adapter.incrementRevision();
if (revision == adapter.getRevision()) { textInputView.setSendButtonEnabled(true);
adapter.incrementRevision(); List<ConversationItem> items = createItems(headers,
textInputView.setSendButtonEnabled(true); introductions, invitations);
List<ConversationItem> items = createItems(headers, if (items.isEmpty()) list.showData();
introductions, invitations); else adapter.addAll(items);
if (items.isEmpty()) list.showData(); // Scroll to the bottom
else adapter.addAll(items); list.scrollToPosition(adapter.getItemCount() - 1);
// Scroll to the bottom } else {
list.scrollToPosition(adapter.getItemCount() - 1); LOG.info("Concurrent update, reloading");
} else { loadMessages();
LOG.info("Concurrent update, reloading");
loadMessages();
}
} }
}); });
} }
@@ -459,39 +437,32 @@ public class ConversationActivity extends BriarActivity
} }
private void loadMessageBody(final MessageId m) { private void loadMessageBody(final MessageId m) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { long now = System.currentTimeMillis();
try { String body = messagingManager.getMessageBody(m);
long now = System.currentTimeMillis(); long duration = System.currentTimeMillis() - now;
String body = messagingManager.getMessageBody(m); if (LOG.isLoggable(INFO))
long duration = System.currentTimeMillis() - now; LOG.info("Loading body took " + duration + " ms");
if (LOG.isLoggable(INFO)) displayMessageBody(m, body);
LOG.info("Loading body took " + duration + " ms"); } catch (DbException e) {
displayMessageBody(m, body); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
}); });
} }
private void displayMessageBody(final MessageId m, final String body) { private void displayMessageBody(final MessageId m, final String body) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override bodyCache.put(m, body);
public void run() { SparseArray<ConversationItem> messages =
bodyCache.put(m, body); adapter.getPrivateMessages();
SparseArray<ConversationItem> messages = for (int i = 0; i < messages.size(); i++) {
adapter.getPrivateMessages(); ConversationItem item = messages.valueAt(i);
for (int i = 0; i < messages.size(); i++) { if (item.getId().equals(m)) {
ConversationItem item = messages.valueAt(i); item.setBody(body);
if (item.getId().equals(m)) { adapter.notifyItemChanged(messages.keyAt(i));
item.setBody(body); list.scrollToPosition(adapter.getItemCount() - 1);
adapter.notifyItemChanged(messages.keyAt(i)); return;
list.scrollToPosition(adapter.getItemCount() - 1);
return;
}
} }
} }
}); });
@@ -573,14 +544,11 @@ public class ConversationActivity extends BriarActivity
} }
private void addConversationItem(final ConversationItem item) { private void addConversationItem(final ConversationItem item) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override adapter.incrementRevision();
public void run() { adapter.add(item);
adapter.incrementRevision(); // Scroll to the bottom
adapter.add(item); list.scrollToPosition(adapter.getItemCount() - 1);
// Scroll to the bottom
list.scrollToPosition(adapter.getItemCount() - 1);
}
}); });
} }
@@ -588,24 +556,16 @@ public class ConversationActivity extends BriarActivity
getContactNameTask().addListener(new FutureTaskListener<String>() { getContactNameTask().addListener(new FutureTaskListener<String>() {
@Override @Override
public void onSuccess(final String contactName) { public void onSuccess(final String contactName) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override ConversationItem item = ConversationItem
public void run() { .from(ConversationActivity.this, contactName, m);
ConversationItem item = ConversationItem addConversationItem(item);
.from(ConversationActivity.this, contactName,
m);
addConversationItem(item);
}
}); });
} }
@Override @Override
public void onFailure(final Throwable exception) { public void onFailure(final Throwable exception) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(
@Override () -> handleDbException((DbException) exception));
public void run() {
handleDbException((DbException) exception);
}
});
} }
}); });
} }
@@ -614,24 +574,16 @@ public class ConversationActivity extends BriarActivity
getContactNameTask().addListener(new FutureTaskListener<String>() { getContactNameTask().addListener(new FutureTaskListener<String>() {
@Override @Override
public void onSuccess(final String contactName) { public void onSuccess(final String contactName) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override ConversationItem item = ConversationItem
public void run() { .from(ConversationActivity.this, contactName, m);
ConversationItem item = ConversationItem addConversationItem(item);
.from(ConversationActivity.this, contactName,
m);
addConversationItem(item);
}
}); });
} }
@Override @Override
public void onFailure(final Throwable exception) { public void onFailure(final Throwable exception) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(
@Override () -> handleDbException((DbException) exception));
public void run() {
handleDbException((DbException) exception);
}
});
} }
}); });
} }
@@ -640,24 +592,16 @@ public class ConversationActivity extends BriarActivity
getContactNameTask().addListener(new FutureTaskListener<String>() { getContactNameTask().addListener(new FutureTaskListener<String>() {
@Override @Override
public void onSuccess(final String contactName) { public void onSuccess(final String contactName) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override ConversationItem item = ConversationItem
public void run() { .from(ConversationActivity.this, contactName, m);
ConversationItem item = ConversationItem addConversationItem(item);
.from(ConversationActivity.this, contactName,
m);
addConversationItem(item);
}
}); });
} }
@Override @Override
public void onFailure(final Throwable exception) { public void onFailure(final Throwable exception) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(
@Override () -> handleDbException((DbException) exception));
public void run() {
handleDbException((DbException) exception);
}
});
} }
}); });
} }
@@ -666,44 +610,33 @@ public class ConversationActivity extends BriarActivity
getContactNameTask().addListener(new FutureTaskListener<String>() { getContactNameTask().addListener(new FutureTaskListener<String>() {
@Override @Override
public void onSuccess(final String contactName) { public void onSuccess(final String contactName) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override ConversationItem item = ConversationItem
public void run() { .from(ConversationActivity.this, contactName, m);
ConversationItem item = ConversationItem addConversationItem(item);
.from(ConversationActivity.this, contactName,
m);
addConversationItem(item);
}
}); });
} }
@Override @Override
public void onFailure(final Throwable exception) { public void onFailure(final Throwable exception) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(
@Override () -> handleDbException((DbException) exception));
public void run() {
handleDbException((DbException) exception);
}
});
} }
}); });
} }
private void markMessages(final Collection<MessageId> messageIds, private void markMessages(final Collection<MessageId> messageIds,
final boolean sent, final boolean seen) { final boolean sent, final boolean seen) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override adapter.incrementRevision();
public void run() { Set<MessageId> messages = new HashSet<>(messageIds);
adapter.incrementRevision(); SparseArray<ConversationOutItem> list =
Set<MessageId> messages = new HashSet<>(messageIds); adapter.getOutgoingMessages();
SparseArray<ConversationOutItem> list = for (int i = 0; i < list.size(); i++) {
adapter.getOutgoingMessages(); ConversationOutItem item = list.valueAt(i);
for (int i = 0; i < list.size(); i++) { if (messages.contains(item.getId())) {
ConversationOutItem item = list.valueAt(i); item.setSent(sent);
if (messages.contains(item.getId())) { item.setSeen(seen);
item.setSent(sent); adapter.notifyItemChanged(list.keyAt(i));
item.setSeen(seen);
adapter.notifyItemChanged(list.keyAt(i));
}
} }
} }
}); });
@@ -727,71 +660,54 @@ public class ConversationActivity extends BriarActivity
} }
private void loadGroupId(final String body, final long timestamp) { private void loadGroupId(final String body, final long timestamp) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { messagingGroupId =
try { messagingManager.getConversationId(contactId);
messagingGroupId = createMessage(body, timestamp);
messagingManager.getConversationId(contactId); } catch (DbException e) {
createMessage(body, timestamp); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
}); });
} }
private void createMessage(final String body, final long timestamp) { private void createMessage(final String body, final long timestamp) {
cryptoExecutor.execute(new Runnable() { cryptoExecutor.execute(() -> {
@Override try {
public void run() { //noinspection ConstantConditions init in loadGroupId()
try { storeMessage(privateMessageFactory.createPrivateMessage(
//noinspection ConstantConditions init in loadGroupId() messagingGroupId, timestamp, body), body);
storeMessage(privateMessageFactory.createPrivateMessage( } catch (FormatException e) {throw new RuntimeException(e);
messagingGroupId, timestamp, body), body);
} catch (FormatException e) {
throw new RuntimeException(e);
}
} }
}); });
} }
private void storeMessage(final PrivateMessage m, final String body) { private void storeMessage(final PrivateMessage m, final String body) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { long now = System.currentTimeMillis();
try { messagingManager.addLocalMessage(m);
long now = System.currentTimeMillis(); long duration = System.currentTimeMillis() - now;
messagingManager.addLocalMessage(m); if (LOG.isLoggable(INFO))
long duration = System.currentTimeMillis() - now; LOG.info("Storing message took " + duration + " ms");
if (LOG.isLoggable(INFO)) Message message = m.getMessage();
LOG.info("Storing message took " + duration + " ms"); PrivateMessageHeader h = new PrivateMessageHeader(
Message message = m.getMessage(); message.getId(), message.getGroupId(),
PrivateMessageHeader h = new PrivateMessageHeader( message.getTimestamp(), true, false, false, false);
message.getId(), message.getGroupId(), ConversationItem item = ConversationItem.from(h);
message.getTimestamp(), true, false, false, false); item.setBody(body);
ConversationItem item = ConversationItem.from(h); bodyCache.put(message.getId(), body);
item.setBody(body); addConversationItem(item);
bodyCache.put(message.getId(), body); } catch (DbException e) {
addConversationItem(item); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
}); });
} }
private void askToRemoveContact() { private void askToRemoveContact() {
DialogInterface.OnClickListener okListener = DialogInterface.OnClickListener okListener =
new DialogInterface.OnClickListener() { (dialog, which) -> removeContact();
@Override
public void onClick(DialogInterface dialog, int which) {
removeContact();
}
};
AlertDialog.Builder builder = AlertDialog.Builder builder =
new AlertDialog.Builder(ConversationActivity.this, new AlertDialog.Builder(ConversationActivity.this,
R.style.BriarDialogTheme); R.style.BriarDialogTheme);
@@ -803,118 +719,95 @@ public class ConversationActivity extends BriarActivity
} }
private void removeContact() { private void removeContact() {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { contactManager.removeContact(contactId);
try { } catch (DbException e) {
contactManager.removeContact(contactId); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) { } finally {
if (LOG.isLoggable(WARNING)) finishAfterContactRemoved();
LOG.log(WARNING, e.toString(), e);
} finally {
finishAfterContactRemoved();
}
} }
}); });
} }
private void finishAfterContactRemoved() { private void finishAfterContactRemoved() {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override String deleted = getString(R.string.contact_deleted_toast);
public void run() { Toast.makeText(ConversationActivity.this, deleted, LENGTH_SHORT)
String deleted = getString(R.string.contact_deleted_toast); .show();
Toast.makeText(ConversationActivity.this, deleted, LENGTH_SHORT) supportFinishAfterTransition();
.show();
supportFinishAfterTransition();
}
}); });
} }
private void enableIntroductionActionIfAvailable(final MenuItem item) { private void enableIntroductionActionIfAvailable(final MenuItem item) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { if (contactManager.getActiveContacts().size() > 1) {
try { enableIntroductionAction(item);
if (contactManager.getActiveContacts().size() > 1) { Settings settings =
enableIntroductionAction(item); settingsManager.getSettings(SETTINGS_NAMESPACE);
Settings settings = if (settings.getBoolean(SHOW_ONBOARDING_INTRODUCTION,
settingsManager.getSettings(SETTINGS_NAMESPACE); true)) {
if (settings.getBoolean(SHOW_ONBOARDING_INTRODUCTION, showIntroductionOnboarding();
true)) {
showIntroductionOnboarding();
}
} }
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} }
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }
private void enableIntroductionAction(final MenuItem item) { private void enableIntroductionAction(final MenuItem item) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> item.setEnabled(true));
@Override
public void run() {
item.setEnabled(true);
}
});
} }
private void showIntroductionOnboarding() { private void showIntroductionOnboarding() {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override // find view of overflow icon
public void run() { View target = null;
// find view of overflow icon for (int i = 0; i < toolbar.getChildCount(); i++) {
View target = null; if (toolbar.getChildAt(i) instanceof ActionMenuView) {
for (int i = 0; i < toolbar.getChildCount(); i++) { ActionMenuView menu =
if (toolbar.getChildAt(i) instanceof ActionMenuView) { (ActionMenuView) toolbar.getChildAt(i);
ActionMenuView menu = target = menu.getChildAt(menu.getChildCount() - 1);
(ActionMenuView) toolbar.getChildAt(i); break;
target = menu.getChildAt(menu.getChildCount() - 1);
break;
}
} }
if (target == null) {
LOG.warning("No Overflow Icon found!");
return;
}
OnHidePromptListener listener = new OnHidePromptListener() {
@Override
public void onHidePrompt(MotionEvent motionEvent,
boolean focalClicked) {
introductionOnboardingSeen();
}
@Override
public void onHidePromptComplete() {
}
};
new MaterialTapTargetPrompt.Builder(ConversationActivity.this)
.setTarget(target)
.setPrimaryText(R.string.introduction_onboarding_title)
.setSecondaryText(R.string.introduction_onboarding_text)
.setBackgroundColourFromRes(R.color.briar_primary)
.setIcon(R.drawable.ic_more_vert_accent)
.setOnHidePromptListener(listener)
.show();
} }
if (target == null) {
LOG.warning("No Overflow Icon found!");
return;
}
OnHidePromptListener listener = new OnHidePromptListener() {
@Override
public void onHidePrompt(MotionEvent motionEvent,
boolean focalClicked) {
introductionOnboardingSeen();
}
@Override
public void onHidePromptComplete() {
}
};
new MaterialTapTargetPrompt.Builder(ConversationActivity.this)
.setTarget(target)
.setPrimaryText(R.string.introduction_onboarding_title)
.setSecondaryText(R.string.introduction_onboarding_text)
.setBackgroundColourFromRes(R.color.briar_primary)
.setIcon(R.drawable.ic_more_vert_accent)
.setOnHidePromptListener(listener)
.show();
}); });
} }
private void introductionOnboardingSeen() { private void introductionOnboardingSeen() {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { Settings settings = new Settings();
try { settings.putBoolean(SHOW_ONBOARDING_INTRODUCTION, false);
Settings settings = new Settings(); settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
settings.putBoolean(SHOW_ONBOARDING_INTRODUCTION, false); } catch (DbException e) {
settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
}); });
} }
@@ -925,19 +818,15 @@ public class ConversationActivity extends BriarActivity
} }
private void markMessageRead(final GroupId g, final MessageId m) { private void markMessageRead(final GroupId g, final MessageId m) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { long now = System.currentTimeMillis();
try { messagingManager.setReadFlag(g, m, true);
long now = System.currentTimeMillis(); long duration = System.currentTimeMillis() - now;
messagingManager.setReadFlag(g, m, true); if (LOG.isLoggable(INFO))
long duration = System.currentTimeMillis() - now; LOG.info("Marking read took " + duration + " ms");
if (LOG.isLoggable(INFO)) } catch (DbException e) {
LOG.info("Marking read took " + duration + " ms"); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
}); });
} }
@@ -951,36 +840,33 @@ public class ConversationActivity extends BriarActivity
if (position != INVALID_POSITION) { if (position != INVALID_POSITION) {
adapter.notifyItemChanged(position, item); adapter.notifyItemChanged(position, item);
} }
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override long timestamp = System.currentTimeMillis();
public void run() { timestamp = Math.max(timestamp, getMinTimestampForNewMessage());
long timestamp = System.currentTimeMillis(); try {
timestamp = Math.max(timestamp, getMinTimestampForNewMessage()); switch (item.getRequestType()) {
try { case INTRODUCTION:
switch (item.getRequestType()) { respondToIntroductionRequest(item.getSessionId(),
case INTRODUCTION: accept, timestamp);
respondToIntroductionRequest(item.getSessionId(), break;
accept, timestamp); case FORUM:
break; respondToForumRequest(item.getSessionId(), accept);
case FORUM: break;
respondToForumRequest(item.getSessionId(), accept); case BLOG:
break; respondToBlogRequest(item.getSessionId(), accept);
case BLOG: break;
respondToBlogRequest(item.getSessionId(), accept); case GROUP:
break; respondToGroupRequest(item.getSessionId(), accept);
case GROUP: break;
respondToGroupRequest(item.getSessionId(), accept); default:
break; throw new IllegalArgumentException(
default: "Unknown Request Type");
throw new IllegalArgumentException(
"Unknown Request Type");
}
loadMessages();
} catch (DbException | FormatException e) {
introductionResponseError();
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} }
loadMessages();
} catch (DbException | FormatException e) {
introductionResponseError();
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} }
}); });
} }
@@ -1041,14 +927,10 @@ public class ConversationActivity extends BriarActivity
} }
private void introductionResponseError() { private void introductionResponseError() {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() ->
@Override
public void run() {
Toast.makeText(ConversationActivity.this, Toast.makeText(ConversationActivity.this,
R.string.introduction_response_error, R.string.introduction_response_error,
Toast.LENGTH_SHORT).show(); Toast.LENGTH_SHORT).show());
}
});
} }
private ListenableFutureTask<String> getContactNameTask() { private ListenableFutureTask<String> getContactNameTask() {

View File

@@ -2,7 +2,6 @@ package org.briarproject.briar.android.contact;
import android.support.annotation.UiThread; import android.support.annotation.UiThread;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button; import android.widget.Button;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@@ -35,12 +34,8 @@ class ConversationRequestViewHolder extends ConversationNoticeInViewHolder {
if (item.wasAnswered() && item.canBeOpened()) { if (item.wasAnswered() && item.canBeOpened()) {
acceptButton.setVisibility(VISIBLE); acceptButton.setVisibility(VISIBLE);
acceptButton.setText(R.string.open); acceptButton.setText(R.string.open);
acceptButton.setOnClickListener(new OnClickListener() { acceptButton.setOnClickListener(
@Override v -> listener.openRequestedShareable(item));
public void onClick(View v) {
listener.openRequestedShareable(item);
}
});
declineButton.setVisibility(GONE); declineButton.setVisibility(GONE);
} else if (item.wasAnswered()) { } else if (item.wasAnswered()) {
acceptButton.setVisibility(GONE); acceptButton.setVisibility(GONE);
@@ -48,22 +43,16 @@ class ConversationRequestViewHolder extends ConversationNoticeInViewHolder {
} else { } else {
acceptButton.setVisibility(VISIBLE); acceptButton.setVisibility(VISIBLE);
acceptButton.setText(R.string.accept); acceptButton.setText(R.string.accept);
acceptButton.setOnClickListener(new OnClickListener() { acceptButton.setOnClickListener(v -> {
@Override acceptButton.setEnabled(false);
public void onClick(View v) { declineButton.setEnabled(false);
acceptButton.setEnabled(false); listener.respondToRequest(item, true);
declineButton.setEnabled(false);
listener.respondToRequest(item, true);
}
}); });
declineButton.setVisibility(VISIBLE); declineButton.setVisibility(VISIBLE);
declineButton.setOnClickListener(new OnClickListener() { declineButton.setOnClickListener(v -> {
@Override acceptButton.setEnabled(false);
public void onClick(View v) { declineButton.setEnabled(false);
acceptButton.setEnabled(false); listener.respondToRequest(item, false);
declineButton.setEnabled(false);
listener.respondToRequest(item, false);
}
}); });
} }
} }

View File

@@ -41,26 +41,21 @@ public abstract class ContactSelectorControllerImpl
public void loadContacts(final GroupId g, public void loadContacts(final GroupId g,
final Collection<ContactId> selection, final Collection<ContactId> selection,
final ResultExceptionHandler<Collection<SelectableContactItem>, DbException> handler) { final ResultExceptionHandler<Collection<SelectableContactItem>, DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { Collection<SelectableContactItem> contacts = new ArrayList<>();
try { for (Contact c : contactManager.getActiveContacts()) {
Collection<SelectableContactItem> contacts = // was this contact already selected?
new ArrayList<>(); boolean selected = selection.contains(c.getId());
for (Contact c : contactManager.getActiveContacts()) { // can this contact be selected?
// was this contact already selected? boolean disabled = isDisabled(g, c);
boolean selected = selection.contains(c.getId()); contacts.add(new SelectableContactItem(c, selected,
// can this contact be selected? disabled));
boolean disabled = isDisabled(g, c);
contacts.add(new SelectableContactItem(c, selected,
disabled));
}
handler.onResult(contacts);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
handler.onResult(contacts);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
}); });
} }

View File

@@ -29,16 +29,13 @@ public class DbControllerImpl implements DbController {
@Override @Override
public void runOnDbThread(final Runnable task) { public void runOnDbThread(final Runnable task) {
dbExecutor.execute(new Runnable() { dbExecutor.execute(() -> {
@Override try {
public void run() { lifecycleManager.waitForDatabase();
try { task.run();
lifecycleManager.waitForDatabase(); } catch (InterruptedException e) {
task.run(); LOG.warning("Interrupted while waiting for database");
} catch (InterruptedException e) { Thread.currentThread().interrupt();
LOG.warning("Interrupted while waiting for database");
Thread.currentThread().interrupt();
}
} }
}); });
} }

View File

@@ -60,13 +60,10 @@ public class SharingControllerImpl implements SharingController, EventListener {
private void setConnected(final ContactId c) { private void setConnected(final ContactId c) {
if (listener == null) return; if (listener == null) return;
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(() -> {
@Override if (contacts.contains(c)) {
public void run() { int online = getOnlineCount();
if (contacts.contains(c)) { listener.onSharingInfoUpdated(contacts.size(), online);
int online = getOnlineCount();
listener.onSharingInfoUpdated(contacts.size(), online);
}
} }
}); });
} }

View File

@@ -20,12 +20,7 @@ public abstract class UiExceptionHandler<E extends Exception>
@Override @Override
public void onException(final E exception) { public void onException(final E exception) {
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(() -> onExceptionUi(exception));
@Override
public void run() {
onExceptionUi(exception);
}
});
} }
@UiThread @UiThread

View File

@@ -18,12 +18,7 @@ public abstract class UiResultExceptionHandler<R, E extends Exception>
@Override @Override
public void onResult(final R result) { public void onResult(final R result) {
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(() -> onResultUi(result));
@Override
public void run() {
onResultUi(result);
}
});
} }
@UiThread @UiThread

View File

@@ -14,12 +14,7 @@ public abstract class UiResultHandler<R> implements ResultHandler<R> {
@Override @Override
public void onResult(final R result) { public void onResult(final R result) {
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(() -> onResultUi(result));
@Override
public void run() {
onResultUi(result);
}
});
} }
@UiThread @UiThread

View File

@@ -5,14 +5,9 @@ import android.os.Bundle;
import android.support.design.widget.TextInputLayout; import android.support.design.widget.TextInputLayout;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast; import android.widget.Toast;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
@@ -79,22 +74,13 @@ public class CreateForumActivity extends BriarActivity {
public void afterTextChanged(Editable s) { public void afterTextChanged(Editable s) {
} }
}); });
nameEntry.setOnEditorActionListener(new OnEditorActionListener() { nameEntry.setOnEditorActionListener((v, actionId, e) -> {
@Override createForum();
public boolean onEditorAction(TextView v, int actionId, return true;
KeyEvent e) {
createForum();
return true;
}
}); });
createForumButton = (Button) findViewById(R.id.createForumButton); createForumButton = (Button) findViewById(R.id.createForumButton);
createForumButton.setOnClickListener(new OnClickListener() { createForumButton.setOnClickListener(v -> createForum());
@Override
public void onClick(View v) {
createForum();
}
});
progress = (ProgressBar) findViewById(R.id.createForumProgressBar); progress = (ProgressBar) findViewById(R.id.createForumProgressBar);
} }
@@ -135,38 +121,31 @@ public class CreateForumActivity extends BriarActivity {
} }
private void storeForum(final String name) { private void storeForum(final String name) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { long now = System.currentTimeMillis();
try { Forum f = forumManager.addForum(name);
long now = System.currentTimeMillis(); long duration = System.currentTimeMillis() - now;
Forum f = forumManager.addForum(name); if (LOG.isLoggable(INFO))
long duration = System.currentTimeMillis() - now; LOG.info("Storing forum took " + duration + " ms");
if (LOG.isLoggable(INFO)) displayForum(f);
LOG.info("Storing forum took " + duration + " ms"); } catch (DbException e) {
displayForum(f); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) { finishOnUiThread();
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
finishOnUiThread();
}
} }
}); });
} }
private void displayForum(final Forum f) { private void displayForum(final Forum f) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override Intent i = new Intent(CreateForumActivity.this,
public void run() { ForumActivity.class);
Intent i = new Intent(CreateForumActivity.this, i.putExtra(GROUP_ID, f.getId().getBytes());
ForumActivity.class); i.putExtra(GROUP_NAME, f.getName());
i.putExtra(GROUP_ID, f.getId().getBytes()); startActivity(i);
i.putExtra(GROUP_NAME, f.getName()); Toast.makeText(CreateForumActivity.this,
startActivity(i); R.string.forum_created_toast, LENGTH_LONG).show();
Toast.makeText(CreateForumActivity.this, supportFinishAfterTransition();
R.string.forum_created_toast, LENGTH_LONG).show();
supportFinishAfterTransition();
}
}); });
} }
} }

View File

@@ -1,6 +1,5 @@
package org.briarproject.briar.android.forum; package org.briarproject.briar.android.forum;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener; import android.content.DialogInterface.OnClickListener;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
@@ -11,7 +10,6 @@ import android.support.v7.widget.Toolbar;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View;
import android.widget.Toast; import android.widget.Toast;
import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactId;
@@ -69,16 +67,12 @@ public class ForumActivity extends
// Open member list on Toolbar click // Open member list on Toolbar click
if (toolbar != null) { if (toolbar != null) {
toolbar.setOnClickListener( toolbar.setOnClickListener(v -> {
new View.OnClickListener() { Intent i1 = new Intent(ForumActivity.this,
@Override ForumSharingStatusActivity.class);
public void onClick(View v) { i1.putExtra(GROUP_ID, groupId.getBytes());
Intent i = new Intent(ForumActivity.this, startActivity(i1);
ForumSharingStatusActivity.class); });
i.putExtra(GROUP_ID, groupId.getBytes());
startActivity(i);
}
});
} }
} }
@@ -147,12 +141,7 @@ public class ForumActivity extends
} }
private void showUnsubscribeDialog() { private void showUnsubscribeDialog() {
OnClickListener okListener = new OnClickListener() { OnClickListener okListener = (dialog, which) -> deleteForum();
@Override
public void onClick(DialogInterface dialog, int which) {
deleteForum();
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this, AlertDialog.Builder builder = new AlertDialog.Builder(this,
R.style.BriarDialogTheme); R.style.BriarDialogTheme);
builder.setTitle(getString(R.string.dialog_title_leave_forum)); builder.setTitle(getString(R.string.dialog_title_leave_forum));

View File

@@ -121,21 +121,17 @@ class ForumControllerImpl extends
@Override @Override
public void loadSharingContacts( public void loadSharingContacts(
final ResultExceptionHandler<Collection<ContactId>, DbException> handler) { final ResultExceptionHandler<Collection<ContactId>, DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { Collection<Contact> contacts =
try { forumSharingManager.getSharedWith(getGroupId());
Collection<Contact> contacts = Collection<ContactId> contactIds =
forumSharingManager.getSharedWith(getGroupId()); new ArrayList<>(contacts.size());
Collection<ContactId> contactIds = for (Contact c : contacts) contactIds.add(c.getId());
new ArrayList<>(contacts.size()); handler.onResult(contactIds);
for (Contact c : contacts) contactIds.add(c.getId()); } catch (DbException e) {
handler.onResult(contactIds); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) { handler.onException(e);
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
} }
}); });
} }
@@ -144,22 +140,18 @@ class ForumControllerImpl extends
public void createAndStoreMessage(final String body, public void createAndStoreMessage(final String body,
@Nullable final ForumItem parentItem, @Nullable final ForumItem parentItem,
final ResultExceptionHandler<ForumItem, DbException> handler) { final ResultExceptionHandler<ForumItem, DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { LocalAuthor author = identityManager.getLocalAuthor();
try { GroupCount count = forumManager.getGroupCount(getGroupId());
LocalAuthor author = identityManager.getLocalAuthor(); long timestamp = max(count.getLatestMsgTime() + 1,
GroupCount count = forumManager.getGroupCount(getGroupId()); clock.currentTimeMillis());
long timestamp = max(count.getLatestMsgTime() + 1, MessageId parentId = parentItem != null ?
clock.currentTimeMillis()); parentItem.getId() : null;
MessageId parentId = parentItem != null ? createMessage(body, timestamp, parentId, author, handler);
parentItem.getId() : null; } catch (DbException e) {
createMessage(body, timestamp, parentId, author, handler); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) { handler.onException(e);
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
} }
}); });
} }
@@ -167,15 +159,11 @@ class ForumControllerImpl extends
private void createMessage(final String body, final long timestamp, private void createMessage(final String body, final long timestamp,
final @Nullable MessageId parentId, final LocalAuthor author, final @Nullable MessageId parentId, final LocalAuthor author,
final ResultExceptionHandler<ForumItem, DbException> handler) { final ResultExceptionHandler<ForumItem, DbException> handler) {
cryptoExecutor.execute(new Runnable() { cryptoExecutor.execute(() -> {
@Override LOG.info("Creating forum post...");
public void run() { ForumPost msg = forumManager.createLocalPost(getGroupId(), body,
LOG.info("Creating forum post..."); timestamp, parentId, author);
ForumPost msg = forumManager storePost(msg, body, handler);
.createLocalPost(getGroupId(), body, timestamp,
parentId, author);
storePost(msg, body, handler);
}
}); });
} }
@@ -197,30 +185,17 @@ class ForumControllerImpl extends
private void onForumPostReceived(ForumPostHeader h, String body) { private void onForumPostReceived(ForumPostHeader h, String body) {
final ForumItem item = buildItem(h, body); final ForumItem item = buildItem(h, body);
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(
@Override () -> listener.onItemReceived(item));
public void run() {
listener.onItemReceived(item);
}
});
} }
private void onForumInvitationAccepted(final ContactId c) { private void onForumInvitationAccepted(final ContactId c) {
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(
@Override () -> listener.onInvitationAccepted(c));
public void run() {
listener.onInvitationAccepted(c);
}
});
} }
private void onForumLeft(final ContactId c) { private void onForumLeft(final ContactId c) {
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(() -> listener.onForumLeft(c));
@Override
public void run() {
listener.onForumLeft(c);
}
});
} }
} }

View File

@@ -77,15 +77,12 @@ class ForumListAdapter
} }
// Open Forum on Click // Open Forum on Click
ui.layout.setOnClickListener(new View.OnClickListener() { ui.layout.setOnClickListener(v -> {
@Override Intent i = new Intent(ctx, ForumActivity.class);
public void onClick(View v) { Forum f = item.getForum();
Intent i = new Intent(ctx, ForumActivity.class); i.putExtra(GROUP_ID, f.getId().getBytes());
Forum f = item.getForum(); i.putExtra(GROUP_NAME, f.getName());
i.putExtra(GROUP_ID, f.getId().getBytes()); ctx.startActivity(i);
i.putExtra(GROUP_NAME, f.getName());
ctx.startActivity(i);
}
}); });
} }

View File

@@ -155,82 +155,67 @@ public class ForumListFragment extends BaseEventFragment implements
private void loadForums() { private void loadForums() {
final int revision = adapter.getRevision(); final int revision = adapter.getRevision();
listener.runOnDbThread(new Runnable() { listener.runOnDbThread(() -> {
@Override try {
public void run() { long now = System.currentTimeMillis();
try { Collection<ForumListItem> forums = new ArrayList<>();
long now = System.currentTimeMillis(); for (Forum f : forumManager.getForums()) {
Collection<ForumListItem> forums = new ArrayList<>(); try {
for (Forum f : forumManager.getForums()) { GroupCount count =
try { forumManager.getGroupCount(f.getId());
GroupCount count = forums.add(new ForumListItem(f, count));
forumManager.getGroupCount(f.getId()); } catch (NoSuchGroupException e) {
forums.add(new ForumListItem(f, count)); // Continue
} catch (NoSuchGroupException e) {
// Continue
}
} }
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Full load took " + duration + " ms");
displayForums(revision, forums);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} }
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Full load took " + duration + " ms");
displayForums(revision, forums);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }
private void displayForums(final int revision, private void displayForums(final int revision,
final Collection<ForumListItem> forums) { final Collection<ForumListItem> forums) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override if (revision == adapter.getRevision()) {
public void run() { adapter.incrementRevision();
if (revision == adapter.getRevision()) { if (forums.isEmpty()) list.showData();
adapter.incrementRevision(); else adapter.addAll(forums);
if (forums.isEmpty()) list.showData(); } else {
else adapter.addAll(forums); LOG.info("Concurrent update, reloading");
} else { loadForums();
LOG.info("Concurrent update, reloading");
loadForums();
}
} }
}); });
} }
private void loadAvailableForums() { private void loadAvailableForums() {
listener.runOnDbThread(new Runnable() { listener.runOnDbThread(() -> {
@Override try {
public void run() { long now = System.currentTimeMillis();
try { int available = forumSharingManager.getInvitations().size();
long now = System.currentTimeMillis(); long duration = System.currentTimeMillis() - now;
int available = if (LOG.isLoggable(INFO))
forumSharingManager.getInvitations().size(); LOG.info("Loading available took " + duration + " ms");
long duration = System.currentTimeMillis() - now; displayAvailableForums(available);
if (LOG.isLoggable(INFO)) } catch (DbException e) {
LOG.info("Loading available took " + duration + " ms"); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
displayAvailableForums(available);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
}); });
} }
private void displayAvailableForums(final int availableCount) { private void displayAvailableForums(final int availableCount) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override if (availableCount == 0) {
public void run() { snackbar.dismiss();
if (availableCount == 0) { } else {
snackbar.dismiss(); snackbar.setText(getResources().getQuantityString(
} else { R.plurals.forums_shared, availableCount,
snackbar.setText(getResources().getQuantityString( availableCount));
R.plurals.forums_shared, availableCount, if (!snackbar.isShownOrQueued()) snackbar.show();
availableCount));
if (!snackbar.isShownOrQueued()) snackbar.show();
}
} }
}); });
} }
@@ -263,29 +248,23 @@ public class ForumListFragment extends BaseEventFragment implements
} }
private void updateItem(final GroupId g, final ForumPostHeader m) { private void updateItem(final GroupId g, final ForumPostHeader m) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override adapter.incrementRevision();
public void run() { int position = adapter.findItemPosition(g);
adapter.incrementRevision(); ForumListItem item = adapter.getItemAt(position);
int position = adapter.findItemPosition(g); if (item != null) {
ForumListItem item = adapter.getItemAt(position); item.addHeader(m);
if (item != null) { adapter.updateItemAt(position, item);
item.addHeader(m);
adapter.updateItemAt(position, item);
}
} }
}); });
} }
private void removeForum(final GroupId g) { private void removeForum(final GroupId g) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override adapter.incrementRevision();
public void run() { int position = adapter.findItemPosition(g);
adapter.incrementRevision(); ForumListItem item = adapter.getItemAt(position);
int position = adapter.findItemPosition(g); if (item != null) adapter.remove(item);
ForumListItem item = adapter.getItemAt(position);
if (item != null) adapter.remove(item);
}
}); });
} }

View File

@@ -82,14 +82,11 @@ public abstract class BaseFragment extends Fragment
public void runOnUiThreadUnlessDestroyed(final Runnable r) { public void runOnUiThreadUnlessDestroyed(final Runnable r) {
final Activity activity = getActivity(); final Activity activity = getActivity();
if (activity != null) { if (activity != null) {
activity.runOnUiThread(new Runnable() { activity.runOnUiThread(() -> {
@Override // Note that we don't have to check if the activity has
public void run() { // been destroyed as the Fragment has not been detached yet
// Note that we don't have to check if the activity has if (!isDetached() && !activity.isFinishing()) {
// been destroyed as the Fragment has not been detached yet r.run();
if (!isDetached() && !activity.isFinishing()) {
r.run();
}
} }
}); });
} }

View File

@@ -1,7 +1,6 @@
package org.briarproject.briar.android.fragment; package org.briarproject.briar.android.fragment;
import android.app.Dialog; import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.DialogFragment; import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
@@ -35,12 +34,7 @@ public class ScreenFilterDialogFragment extends DialogFragment {
builder.setMessage(getString(R.string.screen_filter_body, builder.setMessage(getString(R.string.screen_filter_body,
TextUtils.join("\n", apps))); TextUtils.join("\n", apps)));
builder.setNeutralButton(R.string.continue_button, builder.setNeutralButton(R.string.continue_button,
new DialogInterface.OnClickListener() { (dialog, which) -> dialog.dismiss());
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
return builder.create(); return builder.create();
} }
} }

View File

@@ -71,13 +71,10 @@ public class ContactChooserFragment extends BaseFragment {
View contentView = inflater.inflate(R.layout.list, container, false); View contentView = inflater.inflate(R.layout.list, container, false);
OnContactClickListener<ContactListItem> onContactClickListener = OnContactClickListener<ContactListItem> onContactClickListener =
new OnContactClickListener<ContactListItem>() { (view, item) -> {
@Override if (c1 == null) throw new IllegalStateException();
public void onItemClick(View view, ContactListItem item) { Contact c2 = item.getContact();
if (c1 == null) throw new IllegalStateException(); showMessageScreen(c1, c2);
Contact c2 = item.getContact();
showMessageScreen(c1, c2);
}
}; };
adapter = new ContactListAdapter(getActivity(), onContactClickListener); adapter = new ContactListAdapter(getActivity(), onContactClickListener);
@@ -115,40 +112,32 @@ public class ContactChooserFragment extends BaseFragment {
} }
private void loadContacts() { private void loadContacts() {
listener.runOnDbThread(new Runnable() { listener.runOnDbThread(() -> {
@Override try {
public void run() { List<ContactListItem> contacts = new ArrayList<>();
try { for (Contact c : contactManager.getActiveContacts()) {
List<ContactListItem> contacts = new ArrayList<>(); if (c.getId().equals(contactId)) {
for (Contact c : contactManager.getActiveContacts()) { c1 = c;
if (c.getId().equals(contactId)) { } else {
c1 = c; ContactId id = c.getId();
} else { GroupCount count =
ContactId id = c.getId(); conversationManager.getGroupCount(id);
GroupCount count = boolean connected =
conversationManager.getGroupCount(id); connectionRegistry.isConnected(c.getId());
boolean connected = contacts.add(new ContactListItem(c, connected, count));
connectionRegistry.isConnected(c.getId());
contacts.add(new ContactListItem(c, connected,
count));
}
} }
displayContacts(contacts);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} }
displayContacts(contacts);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }
private void displayContacts(final List<ContactListItem> contacts) { private void displayContacts(final List<ContactListItem> contacts) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override if (contacts.isEmpty()) list.showData();
public void run() { else adapter.addAll(contacts);
if (contacts.isEmpty()) list.showData();
else adapter.addAll(contacts);
}
}); });
} }

View File

@@ -120,48 +120,41 @@ public class IntroductionMessageFragment extends BaseFragment
private void prepareToSetUpViews(final int contactId1, private void prepareToSetUpViews(final int contactId1,
final int contactId2) { final int contactId2) {
introductionActivity.runOnDbThread(new Runnable() { introductionActivity.runOnDbThread(() -> {
@Override try {
public void run() { Contact c1 = contactManager.getContact(
try { new ContactId(contactId1));
Contact c1 = contactManager.getContact( Contact c2 = contactManager.getContact(
new ContactId(contactId1)); new ContactId(contactId2));
Contact c2 = contactManager.getContact( setUpViews(c1, c2);
new ContactId(contactId2)); } catch (DbException e) {
setUpViews(c1, c2); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
}); });
} }
private void setUpViews(final Contact c1, final Contact c2) { private void setUpViews(final Contact c1, final Contact c2) {
introductionActivity.runOnUiThreadUnlessDestroyed(new Runnable() { introductionActivity.runOnUiThreadUnlessDestroyed(() -> {
@Override contact1 = c1;
public void run() { contact2 = c2;
contact1 = c1;
contact2 = c2;
// set avatars // set avatars
ui.avatar1.setImageDrawable(new IdenticonDrawable( ui.avatar1.setImageDrawable(new IdenticonDrawable(
c1.getAuthor().getId().getBytes())); c1.getAuthor().getId().getBytes()));
ui.avatar2.setImageDrawable(new IdenticonDrawable( ui.avatar2.setImageDrawable(new IdenticonDrawable(
c2.getAuthor().getId().getBytes())); c2.getAuthor().getId().getBytes()));
// set contact names // set contact names
ui.contactName1.setText(c1.getAuthor().getName()); ui.contactName1.setText(c1.getAuthor().getName());
ui.contactName2.setText(c2.getAuthor().getName()); ui.contactName2.setText(c2.getAuthor().getName());
// set button action // set button action
ui.message.setListener(IntroductionMessageFragment.this); ui.message.setListener(IntroductionMessageFragment.this);
// hide progress bar and show views // hide progress bar and show views
ui.progressBar.setVisibility(GONE); ui.progressBar.setVisibility(GONE);
ui.message.setSendButtonEnabled(true); ui.message.setSendButtonEnabled(true);
ui.message.showSoftKeyboard(); ui.message.showSoftKeyboard();
}
}); });
} }
@@ -194,31 +187,22 @@ public class IntroductionMessageFragment extends BaseFragment
private void makeIntroduction(final Contact c1, final Contact c2, private void makeIntroduction(final Contact c1, final Contact c2,
final String msg) { final String msg) {
introductionActivity.runOnDbThread(new Runnable() { introductionActivity.runOnDbThread(() -> {
@Override // actually make the introduction
public void run() { try {
// actually make the introduction long timestamp = System.currentTimeMillis();
try { introductionManager.makeIntroduction(c1, c2, msg, timestamp);
long timestamp = System.currentTimeMillis(); } catch (DbException | FormatException e) {
introductionManager.makeIntroduction(c1, c2, msg, if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
timestamp); introductionError();
} catch (DbException | FormatException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
introductionError();
}
} }
}); });
} }
private void introductionError() { private void introductionError() {
introductionActivity.runOnUiThreadUnlessDestroyed(new Runnable() { introductionActivity.runOnUiThreadUnlessDestroyed(
@Override () -> Toast.makeText(introductionActivity,
public void run() { R.string.introduction_error, LENGTH_SHORT).show());
Toast.makeText(introductionActivity,
R.string.introduction_error, LENGTH_SHORT).show();
}
});
} }
private static class ViewHolder { private static class ViewHolder {

View File

@@ -353,15 +353,11 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
@Override @Override
public void surfaceCreated(final SurfaceHolder holder) { public void surfaceCreated(final SurfaceHolder holder) {
post(new Runnable() { post(() -> {
@Override try {
public void run() { surfaceCreatedUi(holder);
try { } catch (CameraException e) {
surfaceCreatedUi(holder); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (CameraException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
}); });
} }
@@ -381,15 +377,11 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
@Override @Override
public void surfaceChanged(final SurfaceHolder holder, int format, public void surfaceChanged(final SurfaceHolder holder, int format,
final int w, final int h) { final int w, final int h) {
post(new Runnable() { post(() -> {
@Override try {
public void run() { surfaceChangedUi(holder, w, h);
try { } catch (CameraException e) {
surfaceChangedUi(holder, w, h); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (CameraException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
}); });
} }
@@ -420,12 +412,7 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
@Override @Override
public void surfaceDestroyed(final SurfaceHolder holder) { public void surfaceDestroyed(final SurfaceHolder holder) {
post(new Runnable() { post(() -> surfaceDestroyedUi(holder));
@Override
public void run() {
surfaceDestroyedUi(holder);
}
});
} }
@UiThread @UiThread
@@ -442,12 +429,7 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
@Override @Override
public void onAutoFocus(boolean success, final Camera camera) { public void onAutoFocus(boolean success, final Camera camera) {
LOG.info("Auto focus succeeded: " + success); LOG.info("Auto focus succeeded: " + success);
postDelayed(new Runnable() { postDelayed(this::retryAutoFocus, AUTO_FOCUS_RETRY_DELAY);
@Override
public void run() {
retryAutoFocus();
}
}, AUTO_FOCUS_RETRY_DELAY);
} }
@UiThread @UiThread

View File

@@ -4,7 +4,6 @@ import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ScrollView; import android.widget.ScrollView;
@@ -66,24 +65,14 @@ public class IntroFragment extends BaseFragment {
false); false);
scrollView = (ScrollView) v.findViewById(R.id.scrollView); scrollView = (ScrollView) v.findViewById(R.id.scrollView);
View button = v.findViewById(R.id.continueButton); View button = v.findViewById(R.id.continueButton);
button.setOnClickListener(new OnClickListener() { button.setOnClickListener(view -> screenSeenListener.showNextScreen());
@Override
public void onClick(View view) {
screenSeenListener.showNextScreen();
}
});
return v; return v;
} }
@Override @Override
public void onStart() { public void onStart() {
super.onStart(); super.onStart();
scrollView.post(new Runnable() { scrollView.post(() -> scrollView.fullScroll(FOCUS_DOWN));
@Override
public void run() {
scrollView.fullScroll(FOCUS_DOWN);
}
});
} }
} }

View File

@@ -1,6 +1,5 @@
package org.briarproject.briar.android.keyagreement; package org.briarproject.briar.android.keyagreement;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener; import android.content.DialogInterface.OnClickListener;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.UiThread; import android.support.annotation.UiThread;
@@ -144,12 +143,8 @@ public class KeyAgreementActivity extends BriarActivity implements
// Should we show an explanation? // Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this, if (ActivityCompat.shouldShowRequestPermissionRationale(this,
CAMERA)) { CAMERA)) {
OnClickListener continueListener = new OnClickListener() { OnClickListener continueListener =
@Override (dialog, which) -> requestPermission();
public void onClick(DialogInterface dialog, int which) {
requestPermission();
}
};
Builder builder = new Builder(this, style.BriarDialogTheme); Builder builder = new Builder(this, style.BriarDialogTheme);
builder.setTitle(string.permission_camera_title); builder.setTitle(string.permission_camera_title);
builder.setMessage(string.permission_camera_request_body); builder.setMessage(string.permission_camera_request_body);
@@ -183,12 +178,8 @@ public class KeyAgreementActivity extends BriarActivity implements
if (!ActivityCompat.shouldShowRequestPermissionRationale(this, if (!ActivityCompat.shouldShowRequestPermissionRationale(this,
CAMERA)) { CAMERA)) {
// The user has permanently denied the request // The user has permanently denied the request
OnClickListener cancelListener = new OnClickListener() { OnClickListener cancelListener =
@Override (dialog, which) -> supportFinishAfterTransition();
public void onClick(DialogInterface dialog, int which) {
supportFinishAfterTransition();
}
};
Builder builder = new Builder(this, style.BriarDialogTheme); Builder builder = new Builder(this, style.BriarDialogTheme);
builder.setTitle(string.permission_camera_title); builder.setTitle(string.permission_camera_title);
builder.setMessage(string.permission_camera_denied_body); builder.setMessage(string.permission_camera_denied_body);
@@ -214,77 +205,57 @@ public class KeyAgreementActivity extends BriarActivity implements
} }
private void keyAgreementFinished(final KeyAgreementResult result) { private void keyAgreementFinished(final KeyAgreementResult result) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> startContactExchange(result));
@Override
public void run() {
startContactExchange(result);
}
});
} }
private void startContactExchange(final KeyAgreementResult result) { private void startContactExchange(final KeyAgreementResult result) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override LocalAuthor localAuthor;
public void run() { // Load the local pseudonym
LocalAuthor localAuthor; try {
// Load the local pseudonym localAuthor = identityManager.getLocalAuthor();
try { } catch (DbException e) {
localAuthor = identityManager.getLocalAuthor(); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) { contactExchangeFailed();
if (LOG.isLoggable(WARNING)) return;
LOG.log(WARNING, e.toString(), e);
contactExchangeFailed();
return;
}
// Exchange contact details
contactExchangeTask.startExchange(KeyAgreementActivity.this,
localAuthor, result.getMasterKey(),
result.getConnection(), result.getTransportId(),
result.wasAlice());
} }
// Exchange contact details
contactExchangeTask.startExchange(KeyAgreementActivity.this,
localAuthor, result.getMasterKey(),
result.getConnection(), result.getTransportId(),
result.wasAlice());
}); });
} }
@Override @Override
public void contactExchangeSucceeded(final Author remoteAuthor) { public void contactExchangeSucceeded(final Author remoteAuthor) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override String contactName = remoteAuthor.getName();
public void run() { String format = getString(string.contact_added_toast);
String contactName = remoteAuthor.getName(); String text = String.format(format, contactName);
String format = getString(R.string.contact_added_toast); Toast.makeText(KeyAgreementActivity.this, text, LENGTH_LONG).show();
String text = String.format(format, contactName); supportFinishAfterTransition();
Toast.makeText(KeyAgreementActivity.this, text, LENGTH_LONG)
.show();
supportFinishAfterTransition();
}
}); });
} }
@Override @Override
public void duplicateContact(final Author remoteAuthor) { public void duplicateContact(final Author remoteAuthor) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override String contactName = remoteAuthor.getName();
public void run() { String format = getString(string.contact_already_exists);
String contactName = remoteAuthor.getName(); String text = String.format(format, contactName);
String format = getString(R.string.contact_already_exists); Toast.makeText(KeyAgreementActivity.this, text, LENGTH_LONG).show();
String text = String.format(format, contactName); finish();
Toast.makeText(KeyAgreementActivity.this, text, LENGTH_LONG)
.show();
finish();
}
}); });
} }
@Override @Override
public void contactExchangeFailed() { public void contactExchangeFailed() {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override Toast.makeText(KeyAgreementActivity.this,
public void run() { string.contact_exchange_failed, LENGTH_LONG).show();
Toast.makeText(KeyAgreementActivity.this, finish();
R.string.contact_exchange_failed, LENGTH_LONG).show();
finish();
}
}); });
} }
} }

View File

@@ -192,23 +192,17 @@ public class ShowQrCodeFragment extends BaseEventFragment
final KeyAgreementTask oldTask = task; final KeyAgreementTask oldTask = task;
final KeyAgreementTask newTask = keyAgreementTaskFactory.createTask(); final KeyAgreementTask newTask = keyAgreementTaskFactory.createTask();
task = newTask; task = newTask;
ioExecutor.execute(new Runnable() { ioExecutor.execute(() -> {
@Override if (oldTask != null) oldTask.stopListening();
public void run() { newTask.listen();
if (oldTask != null) oldTask.stopListening();
newTask.listen();
}
}); });
} }
@UiThread @UiThread
private void stopListening() { private void stopListening() {
final KeyAgreementTask oldTask = task; final KeyAgreementTask oldTask = task;
ioExecutor.execute(new Runnable() { ioExecutor.execute(() -> {
@Override if (oldTask != null) oldTask.stopListening();
public void run() {
if (oldTask != null) oldTask.stopListening();
}
}); });
} }
@@ -255,13 +249,9 @@ public class ShowQrCodeFragment extends BaseEventFragment
KeyAgreementAbortedEvent event = (KeyAgreementAbortedEvent) e; KeyAgreementAbortedEvent event = (KeyAgreementAbortedEvent) e;
keyAgreementAborted(event.didRemoteAbort()); keyAgreementAborted(event.didRemoteAbort());
} else if (e instanceof KeyAgreementFinishedEvent) { } else if (e instanceof KeyAgreementFinishedEvent) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override mainProgressContainer.setVisibility(VISIBLE);
public void run() { mainProgressTitle.setText(R.string.exchanging_contact_details);
mainProgressContainer.setVisibility(VISIBLE);
mainProgressTitle.setText(
R.string.exchanging_contact_details);
}
}); });
} }
} }
@@ -297,75 +287,54 @@ public class ShowQrCodeFragment extends BaseEventFragment
} }
private void setQrCode(final Payload localPayload) { private void setQrCode(final Payload localPayload) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> generateBitmapQR(localPayload));
@Override
public void run() {
generateBitmapQR(localPayload);
}
});
} }
private void keyAgreementFailed() { private void keyAgreementFailed() {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override reset();
public void run() { // TODO show failure somewhere persistent?
reset(); Toast.makeText(getActivity(), R.string.connection_failed,
// TODO show failure somewhere persistent? LENGTH_LONG).show();
Toast.makeText(getActivity(), R.string.connection_failed,
LENGTH_LONG).show();
}
}); });
} }
private void keyAgreementWaiting() { private void keyAgreementWaiting() {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(
@Override () -> status.setText(R.string.waiting_for_contact_to_scan));
public void run() {
status.setText(R.string.waiting_for_contact_to_scan);
}
});
} }
private void keyAgreementStarted() { private void keyAgreementStarted() {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override mainProgressContainer.setVisibility(VISIBLE);
public void run() { mainProgressTitle.setText(R.string.authenticating_with_device);
mainProgressContainer.setVisibility(VISIBLE);
mainProgressTitle.setText(R.string.authenticating_with_device);
}
}); });
} }
private void keyAgreementAborted(final boolean remoteAborted) { private void keyAgreementAborted(final boolean remoteAborted) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override reset();
public void run() { mainProgressContainer.setVisibility(INVISIBLE);
reset(); mainProgressTitle.setText("");
mainProgressContainer.setVisibility(INVISIBLE); // TODO show abort somewhere persistent?
mainProgressTitle.setText(""); Toast.makeText(getActivity(),
// TODO show abort somewhere persistent? remoteAborted ? R.string.connection_aborted_remote :
Toast.makeText(getActivity(), R.string.connection_aborted_local, LENGTH_LONG)
remoteAborted ? R.string.connection_aborted_remote : .show();
R.string.connection_aborted_local, LENGTH_LONG)
.show();
}
}); });
} }
@Override @Override
public void handleResult(final Result result) { public void handleResult(final Result result) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override LOG.info("Got result from decoder");
public void run() { // Ignore results until the KeyAgreementTask is ready
LOG.info("Got result from decoder"); if (!gotLocalPayload) {
// Ignore results until the KeyAgreementTask is ready return;
if (!gotLocalPayload) { }
return; if (!gotRemotePayload) {
} gotRemotePayload = true;
if (!gotRemotePayload) { qrCodeScanned(result.getText());
gotRemotePayload = true;
qrCodeScanned(result.getText());
}
} }
}); });
} }

View File

@@ -1,6 +1,5 @@
package org.briarproject.briar.android.login; package org.briarproject.briar.android.login;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
@@ -8,13 +7,10 @@ import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.ActivityComponent;
@@ -61,13 +57,9 @@ public class PasswordActivity extends BaseActivity {
progress = (ProgressBar) findViewById(R.id.progress_wheel); progress = (ProgressBar) findViewById(R.id.progress_wheel);
input = (TextInputLayout) findViewById(R.id.password_layout); input = (TextInputLayout) findViewById(R.id.password_layout);
password = (EditText) findViewById(R.id.edit_password); password = (EditText) findViewById(R.id.edit_password);
password.setOnEditorActionListener(new OnEditorActionListener() { password.setOnEditorActionListener((v, actionId, event) -> {
@Override validatePassword();
public boolean onEditorAction(TextView v, int actionId, return true;
KeyEvent event) {
validatePassword();
return true;
}
}); });
password.addTextChangedListener(new TextWatcher() { password.addTextChangedListener(new TextWatcher() {
@@ -131,12 +123,7 @@ public class PasswordActivity extends BaseActivity {
builder.setMessage(R.string.dialog_message_lost_password); builder.setMessage(R.string.dialog_message_lost_password);
builder.setPositiveButton(R.string.cancel, null); builder.setPositiveButton(R.string.cancel, null);
builder.setNegativeButton(R.string.delete, builder.setNegativeButton(R.string.delete,
new DialogInterface.OnClickListener() { (dialog, which) -> deleteAccount());
@Override
public void onClick(DialogInterface dialog, int which) {
deleteAccount();
}
});
AlertDialog dialog = builder.create(); AlertDialog dialog = builder.create();
dialog.show(); dialog.show();
} }

View File

@@ -50,16 +50,13 @@ public class PasswordControllerImpl extends ConfigControllerImpl
public void validatePassword(final String password, public void validatePassword(final String password,
final ResultHandler<Boolean> resultHandler) { final ResultHandler<Boolean> resultHandler) {
final byte[] encrypted = getEncryptedKey(); final byte[] encrypted = getEncryptedKey();
cryptoExecutor.execute(new Runnable() { cryptoExecutor.execute(() -> {
@Override byte[] key = crypto.decryptWithPassword(encrypted, password);
public void run() { if (key == null) {
byte[] key = crypto.decryptWithPassword(encrypted, password); resultHandler.onResult(false);
if (key == null) { } else {
resultHandler.onResult(false); databaseConfig.setEncryptionKey(new SecretKey(key));
} else { resultHandler.onResult(true);
databaseConfig.setEncryptionKey(new SecretKey(key));
resultHandler.onResult(true);
}
} }
}); });
} }
@@ -68,18 +65,15 @@ public class PasswordControllerImpl extends ConfigControllerImpl
public void changePassword(final String password, final String newPassword, public void changePassword(final String password, final String newPassword,
final ResultHandler<Boolean> resultHandler) { final ResultHandler<Boolean> resultHandler) {
final byte[] encrypted = getEncryptedKey(); final byte[] encrypted = getEncryptedKey();
cryptoExecutor.execute(new Runnable() { cryptoExecutor.execute(() -> {
@Override byte[] key = crypto.decryptWithPassword(encrypted, password);
public void run() { if (key == null) {
byte[] key = crypto.decryptWithPassword(encrypted, password); resultHandler.onResult(false);
if (key == null) { } else {
resultHandler.onResult(false); String hex =
} else { encryptDatabaseKey(new SecretKey(key), newPassword);
String hex = storeEncryptedDatabaseKey(hex);
encryptDatabaseKey(new SecretKey(key), newPassword); resultHandler.onResult(true);
storeEncryptedDatabaseKey(hex);
resultHandler.onResult(true);
}
} }
}); });
} }

View File

@@ -86,16 +86,13 @@ public class SetupControllerImpl extends PasswordControllerImpl
public void createAccount(final ResultHandler<Void> resultHandler) { public void createAccount(final ResultHandler<Void> resultHandler) {
if (authorName == null || password == null) if (authorName == null || password == null)
throw new IllegalStateException(); throw new IllegalStateException();
cryptoExecutor.execute(new Runnable() { cryptoExecutor.execute(() -> {
@Override databaseConfig.setLocalAuthorName(authorName);
public void run() { SecretKey key = crypto.generateSecretKey();
databaseConfig.setLocalAuthorName(authorName); databaseConfig.setEncryptionKey(key);
SecretKey key = crypto.generateSecretKey(); String hex = encryptDatabaseKey(key, password);
databaseConfig.setEncryptionKey(key); storeEncryptedDatabaseKey(hex);
String hex = encryptDatabaseKey(key, password); resultHandler.onResult(null);
storeEncryptedDatabaseKey(hex);
resultHandler.onResult(null);
}
}); });
} }

View File

@@ -307,12 +307,9 @@ public class NavDrawerActivity extends BriarActivity implements
daysUntilExpiry, daysUntilExpiry)); daysUntilExpiry, daysUntilExpiry));
} }
expiryWarningClose.setOnClickListener(new View.OnClickListener() { expiryWarningClose.setOnClickListener(v -> {
@Override controller.expiryWarningDismissed();
public void onClick(View v) { expiryWarning.setVisibility(GONE);
controller.expiryWarningDismissed();
expiryWarning.setVisibility(GONE);
}
}); });
expiryWarning.setVisibility(VISIBLE); expiryWarning.setVisibility(VISIBLE);
@@ -411,16 +408,13 @@ public class NavDrawerActivity extends BriarActivity implements
} }
private void setTransport(final TransportId id, final boolean enabled) { private void setTransport(final TransportId id, final boolean enabled) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override if (transports == null || transportsAdapter == null) return;
public void run() { for (Transport t : transports) {
if (transports == null || transportsAdapter == null) return; if (t.id.equals(id)) {
for (Transport t : transports) { t.enabled = enabled;
if (t.id.equals(id)) { transportsAdapter.notifyDataSetChanged();
t.enabled = enabled; break;
transportsAdapter.notifyDataSetChanged();
break;
}
} }
} }
}); });

View File

@@ -98,71 +98,59 @@ public class NavDrawerControllerImpl extends DbControllerImpl
private void transportStateUpdate(final TransportId id, private void transportStateUpdate(final TransportId id,
final boolean enabled) { final boolean enabled) {
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(
@Override () -> listener.stateUpdate(id, enabled));
public void run() {
listener.stateUpdate(id, enabled);
}
});
} }
@Override @Override
public void showExpiryWarning(final ResultHandler<ExpiryWarning> handler) { public void showExpiryWarning(final ResultHandler<ExpiryWarning> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { Settings settings =
try { settingsManager.getSettings(SETTINGS_NAMESPACE);
Settings settings = int warningInt = settings.getInt(EXPIRY_DATE_WARNING, 0);
settingsManager.getSettings(SETTINGS_NAMESPACE); boolean showUpdate =
int warningInt = settings.getInt(EXPIRY_DATE_WARNING, 0); settings.getBoolean(EXPIRY_SHOW_UPDATE, true);
boolean showUpdate =
settings.getBoolean(EXPIRY_SHOW_UPDATE, true);
if (warningInt == 0) { if (warningInt == 0) {
// we have not warned before // we have not warned before
handler.onResult(SHOW);
} else {
long warningLong = warningInt * 1000L;
long now = System.currentTimeMillis();
long daysSinceLastWarning =
(now - warningLong) / 1000 / 60 / 60 / 24;
long daysBeforeExpiry =
(EXPIRY_DATE - now) / 1000 / 60 / 60 / 24;
if (showUpdate) {
handler.onResult(UPDATE);
} else if (daysSinceLastWarning >= 30) {
handler.onResult(SHOW);
} else if (daysBeforeExpiry <= 3 &&
daysSinceLastWarning > 0) {
handler.onResult(SHOW); handler.onResult(SHOW);
} else { } else {
long warningLong = warningInt * 1000L; handler.onResult(NO);
long now = System.currentTimeMillis();
long daysSinceLastWarning =
(now - warningLong) / 1000 / 60 / 60 / 24;
long daysBeforeExpiry =
(EXPIRY_DATE - now) / 1000 / 60 / 60 / 24;
if (showUpdate) {
handler.onResult(UPDATE);
} else if (daysSinceLastWarning >= 30) {
handler.onResult(SHOW);
} else if (daysBeforeExpiry <= 3 &&
daysSinceLastWarning > 0) {
handler.onResult(SHOW);
} else {
handler.onResult(NO);
}
} }
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} }
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }
@Override @Override
public void expiryWarningDismissed() { public void expiryWarningDismissed() {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { Settings settings = new Settings();
try { int date = (int) (System.currentTimeMillis() / 1000L);
Settings settings = new Settings(); settings.putInt(EXPIRY_DATE_WARNING, date);
int date = (int) (System.currentTimeMillis() / 1000L); settings.putBoolean(EXPIRY_SHOW_UPDATE, false);
settings.putInt(EXPIRY_DATE_WARNING, date); settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
settings.putBoolean(EXPIRY_SHOW_UPDATE, false); } catch (DbException e) {
settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
}); });
} }

View File

@@ -12,7 +12,6 @@ import android.os.Bundle;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.support.v7.preference.CheckBoxPreference; import android.support.v7.preference.CheckBoxPreference;
import android.support.v7.preference.ListPreference; import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceFragmentCompat; import android.support.v7.preference.PreferenceFragmentCompat;
import android.text.TextUtils; import android.text.TextUtils;
@@ -92,51 +91,39 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
entryValues.toArray(new CharSequence[entryValues.size()])); entryValues.toArray(new CharSequence[entryValues.size()]));
panicAppPref.setDefaultValue(Panic.PACKAGE_NAME_NONE); panicAppPref.setDefaultValue(Panic.PACKAGE_NAME_NONE);
panicAppPref.setOnPreferenceChangeListener( panicAppPref.setOnPreferenceChangeListener((preference, newValue) -> {
new Preference.OnPreferenceChangeListener() { String packageName = (String) newValue;
@Override PanicResponder.setTriggerPackageName(getActivity(), packageName);
public boolean onPreferenceChange(Preference preference, showPanicApp(packageName);
Object newValue) {
String packageName = (String) newValue;
PanicResponder.setTriggerPackageName(getActivity(),
packageName);
showPanicApp(packageName);
if (packageName.equals(Panic.PACKAGE_NAME_NONE)) { if (packageName.equals(Panic.PACKAGE_NAME_NONE)) {
lockPref.setEnabled(false); lockPref.setEnabled(false);
purgePref.setChecked(false); purgePref.setChecked(false);
purgePref.setEnabled(false); purgePref.setEnabled(false);
uninstallPref.setChecked(false); uninstallPref.setChecked(false);
uninstallPref.setEnabled(false); uninstallPref.setEnabled(false);
getActivity().setResult(Activity.RESULT_CANCELED); getActivity().setResult(Activity.RESULT_CANCELED);
} else { } else {
lockPref.setEnabled(true); lockPref.setEnabled(true);
purgePref.setEnabled(true); purgePref.setEnabled(true);
uninstallPref.setEnabled(true); uninstallPref.setEnabled(true);
} }
return true; return true;
} });
});
if (entries.size() <= 1) { if (entries.size() <= 1) {
panicAppPref.setOnPreferenceClickListener( panicAppPref.setOnPreferenceClickListener(preference -> {
new Preference.OnPreferenceClickListener() { Intent intent = new Intent(Intent.ACTION_VIEW);
@Override intent.setData(Uri.parse(
public boolean onPreferenceClick( "market://details?id=info.guardianproject.ripple"));
Preference preference) { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Intent intent = new Intent(Intent.ACTION_VIEW); if (intent.resolveActivity(getActivity().getPackageManager())
intent.setData(Uri.parse( != null) {
"market://details?id=info.guardianproject.ripple")); startActivity(intent);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); }
if (intent.resolveActivity( return true;
getActivity().getPackageManager()) != });
null) {
startActivity(intent);
}
return true;
}
});
} }
} }
@@ -219,26 +206,15 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
} }
private void showOptInDialog() { private void showOptInDialog() {
DialogInterface.OnClickListener okListener = DialogInterface.OnClickListener okListener = (dialog, which) -> {
new DialogInterface.OnClickListener() { PanicResponder.setTriggerPackageName(getActivity());
@Override showPanicApp(PanicResponder.getTriggerPackageName(getActivity()));
public void onClick(DialogInterface dialog, getActivity().setResult(Activity.RESULT_OK);
int which) { };
PanicResponder.setTriggerPackageName(getActivity()); DialogInterface.OnClickListener cancelListener = (dialog, which) -> {
showPanicApp(PanicResponder getActivity().setResult(Activity.RESULT_CANCELED);
.getTriggerPackageName(getActivity())); getActivity().finish();
getActivity().setResult(Activity.RESULT_OK); };
}
};
DialogInterface.OnClickListener cancelListener =
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
getActivity().setResult(Activity.RESULT_CANCELED);
getActivity().finish();
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(getContext(), AlertDialog.Builder builder = new AlertDialog.Builder(getContext(),
R.style.BriarDialogTheme); R.style.BriarDialogTheme);

View File

@@ -93,18 +93,15 @@ public class PanicResponderActivity extends BriarActivity {
} }
private void deleteAllData() { private void deleteAllData() {
androidExecutor.runOnBackgroundThread(new Runnable() { androidExecutor.runOnBackgroundThread(() -> {
@Override configController.deleteAccount(PanicResponderActivity.this);
public void run() { // TODO somehow delete/shred the database more thoroughly
configController.deleteAccount(PanicResponderActivity.this); PanicResponder.deleteAllAppData(PanicResponderActivity.this);
// TODO somehow delete/shred the database more thoroughly
PanicResponder.deleteAllAppData(PanicResponderActivity.this);
// nothing left to do after everything is deleted, // nothing left to do after everything is deleted,
// so still sign out // so still sign out
LOG.info("Signing out..."); LOG.info("Signing out...");
signOut(true); signOut(true);
}
}); });
} }
} }

View File

@@ -11,7 +11,6 @@ import android.support.v7.widget.Toolbar;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View;
import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
@@ -76,16 +75,12 @@ public class GroupActivity extends
// Open member list on Toolbar click // Open member list on Toolbar click
if (toolbar != null) { if (toolbar != null) {
toolbar.setOnClickListener( toolbar.setOnClickListener(v -> {
new View.OnClickListener() { Intent i1 = new Intent(GroupActivity.this,
@Override GroupMemberListActivity.class);
public void onClick(View v) { i1.putExtra(GROUP_ID, groupId.getBytes());
Intent i = new Intent(GroupActivity.this, startActivity(i1);
GroupMemberListActivity.class); });
i.putExtra(GROUP_ID, groupId.getBytes());
startActivity(i);
}
});
} }
setGroupEnabled(false); setGroupEnabled(false);

View File

@@ -85,24 +85,16 @@ class GroupControllerImpl extends
LOG.info("Group message received, adding..."); LOG.info("Group message received, adding...");
final GroupMessageItem item = final GroupMessageItem item =
buildItem(g.getHeader(), g.getBody()); buildItem(g.getHeader(), g.getBody());
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(
@Override () -> listener.onItemReceived(item));
public void run() {
listener.onItemReceived(item);
}
});
} }
} else if (e instanceof ContactRelationshipRevealedEvent) { } else if (e instanceof ContactRelationshipRevealedEvent) {
final ContactRelationshipRevealedEvent c = final ContactRelationshipRevealedEvent c =
(ContactRelationshipRevealedEvent) e; (ContactRelationshipRevealedEvent) e;
if (getGroupId().equals(c.getGroupId())) { if (getGroupId().equals(c.getGroupId())) {
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(() ->
@Override
public void run() {
listener.onContactRelationshipRevealed(c.getMemberId(), listener.onContactRelationshipRevealed(c.getMemberId(),
c.getContactId(), c.getVisibility()); c.getContactId(), c.getVisibility()));
}
});
} }
} else if (e instanceof GroupInvitationResponseReceivedEvent) { } else if (e instanceof GroupInvitationResponseReceivedEvent) {
GroupInvitationResponseReceivedEvent g = GroupInvitationResponseReceivedEvent g =
@@ -110,22 +102,14 @@ class GroupControllerImpl extends
final GroupInvitationResponse r = final GroupInvitationResponse r =
(GroupInvitationResponse) g.getResponse(); (GroupInvitationResponse) g.getResponse();
if (getGroupId().equals(r.getShareableId()) && r.wasAccepted()) { if (getGroupId().equals(r.getShareableId()) && r.wasAccepted()) {
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(
@Override () -> listener.onInvitationAccepted(r.getContactId()));
public void run() {
listener.onInvitationAccepted(r.getContactId());
}
});
} }
} else if (e instanceof GroupDissolvedEvent) { } else if (e instanceof GroupDissolvedEvent) {
GroupDissolvedEvent g = (GroupDissolvedEvent) e; GroupDissolvedEvent g = (GroupDissolvedEvent) e;
if (getGroupId().equals(g.getGroupId())) { if (getGroupId().equals(g.getGroupId())) {
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(
@Override () -> listener.onGroupDissolved());
public void run() {
listener.onGroupDissolved();
}
});
} }
} }
} }
@@ -158,23 +142,19 @@ class GroupControllerImpl extends
@Override @Override
public void loadSharingContacts( public void loadSharingContacts(
final ResultExceptionHandler<Collection<ContactId>, DbException> handler) { final ResultExceptionHandler<Collection<ContactId>, DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { Collection<GroupMember> members =
try { privateGroupManager.getMembers(getGroupId());
Collection<GroupMember> members = Collection<ContactId> contactIds = new ArrayList<>();
privateGroupManager.getMembers(getGroupId()); for (GroupMember m : members) {
Collection<ContactId> contactIds = new ArrayList<>(); if (m.getContactId() != null)
for (GroupMember m : members) { contactIds.add(m.getContactId());
if (m.getContactId() != null)
contactIds.add(m.getContactId());
}
handler.onResult(contactIds);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
handler.onResult(contactIds);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
}); });
} }
@@ -183,26 +163,22 @@ class GroupControllerImpl extends
public void createAndStoreMessage(final String body, public void createAndStoreMessage(final String body,
@Nullable final GroupMessageItem parentItem, @Nullable final GroupMessageItem parentItem,
final ResultExceptionHandler<GroupMessageItem, DbException> handler) { final ResultExceptionHandler<GroupMessageItem, DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { LocalAuthor author = identityManager.getLocalAuthor();
try { MessageId parentId = null;
LocalAuthor author = identityManager.getLocalAuthor(); MessageId previousMsgId =
MessageId parentId = null; privateGroupManager.getPreviousMsgId(getGroupId());
MessageId previousMsgId = GroupCount count =
privateGroupManager.getPreviousMsgId(getGroupId()); privateGroupManager.getGroupCount(getGroupId());
GroupCount count = long timestamp = count.getLatestMsgTime();
privateGroupManager.getGroupCount(getGroupId()); if (parentItem != null) parentId = parentItem.getId();
long timestamp = count.getLatestMsgTime(); timestamp = max(clock.currentTimeMillis(), timestamp + 1);
if (parentItem != null) parentId = parentItem.getId(); createMessage(body, timestamp, parentId, author, previousMsgId,
timestamp = max(clock.currentTimeMillis(), timestamp + 1); handler);
createMessage(body, timestamp, parentId, author, } catch (DbException e) {
previousMsgId, handler); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) { handler.onException(e);
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
} }
}); });
} }
@@ -211,15 +187,12 @@ class GroupControllerImpl extends
final @Nullable MessageId parentId, final LocalAuthor author, final @Nullable MessageId parentId, final LocalAuthor author,
final MessageId previousMsgId, final MessageId previousMsgId,
final ResultExceptionHandler<GroupMessageItem, DbException> handler) { final ResultExceptionHandler<GroupMessageItem, DbException> handler) {
cryptoExecutor.execute(new Runnable() { cryptoExecutor.execute(() -> {
@Override LOG.info("Creating group message...");
public void run() { GroupMessage msg = groupMessageFactory
LOG.info("Creating group message..."); .createGroupMessage(getGroupId(), timestamp,
GroupMessage msg = groupMessageFactory parentId, author, body, previousMsgId);
.createGroupMessage(getGroupId(), timestamp, storePost(msg, body, handler);
parentId, author, body, previousMsgId);
storePost(msg, body, handler);
}
}); });
} }
@@ -246,17 +219,13 @@ class GroupControllerImpl extends
@Override @Override
public void loadLocalAuthor( public void loadLocalAuthor(
final ResultExceptionHandler<LocalAuthor, DbException> handler) { final ResultExceptionHandler<LocalAuthor, DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { LocalAuthor author = identityManager.getLocalAuthor();
try { handler.onResult(author);
LocalAuthor author = identityManager.getLocalAuthor(); } catch (DbException e) {
handler.onResult(author); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) { handler.onException(e);
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
} }
}); });
} }
@@ -264,18 +233,14 @@ class GroupControllerImpl extends
@Override @Override
public void isDissolved(final public void isDissolved(final
ResultExceptionHandler<Boolean, DbException> handler) { ResultExceptionHandler<Boolean, DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { boolean isDissolved =
try { privateGroupManager.isDissolved(getGroupId());
boolean isDissolved = handler.onResult(isDissolved);
privateGroupManager.isDissolved(getGroupId()); } catch (DbException e) {
handler.onResult(isDissolved); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) { handler.onException(e);
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
} }
}); });
} }

View File

@@ -76,17 +76,13 @@ class CreateGroupControllerImpl extends ContactSelectorControllerImpl
@Override @Override
public void createGroup(final String name, public void createGroup(final String name,
final ResultExceptionHandler<GroupId, DbException> handler) { final ResultExceptionHandler<GroupId, DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { LocalAuthor author = identityManager.getLocalAuthor();
try { createGroupAndMessages(author, name, handler);
LocalAuthor author = identityManager.getLocalAuthor(); } catch (DbException e) {
createGroupAndMessages(author, name, handler); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) { handler.onException(e);
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
} }
}); });
} }
@@ -94,36 +90,29 @@ class CreateGroupControllerImpl extends ContactSelectorControllerImpl
private void createGroupAndMessages(final LocalAuthor author, private void createGroupAndMessages(final LocalAuthor author,
final String name, final String name,
final ResultExceptionHandler<GroupId, DbException> handler) { final ResultExceptionHandler<GroupId, DbException> handler) {
cryptoExecutor.execute(new Runnable() { cryptoExecutor.execute(() -> {
@Override LOG.info("Creating group...");
public void run() { PrivateGroup group =
LOG.info("Creating group..."); groupFactory.createPrivateGroup(name, author);
PrivateGroup group = LOG.info("Creating new join announcement...");
groupFactory.createPrivateGroup(name, author); GroupMessage joinMsg =
LOG.info("Creating new join announcement..."); groupMessageFactory.createJoinMessage(group.getId(),
GroupMessage joinMsg = groupMessageFactory clock.currentTimeMillis(), author);
.createJoinMessage(group.getId(), storeGroup(group, joinMsg, handler);
clock.currentTimeMillis(), author);
storeGroup(group, joinMsg, handler);
}
}); });
} }
private void storeGroup(final PrivateGroup group, private void storeGroup(final PrivateGroup group,
final GroupMessage joinMsg, final GroupMessage joinMsg,
final ResultExceptionHandler<GroupId, DbException> handler) { final ResultExceptionHandler<GroupId, DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override LOG.info("Adding group to database...");
public void run() { try {
LOG.info("Adding group to database..."); groupManager.addPrivateGroup(group, joinMsg, true);
try { handler.onResult(group.getId());
groupManager.addPrivateGroup(group, joinMsg, true); } catch (DbException e) {
handler.onResult(group.getId()); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) { handler.onException(e);
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
} }
}); });
} }
@@ -137,25 +126,21 @@ class CreateGroupControllerImpl extends ContactSelectorControllerImpl
public void sendInvitation(final GroupId g, public void sendInvitation(final GroupId g,
final Collection<ContactId> contactIds, final String message, final Collection<ContactId> contactIds, final String message,
final ResultExceptionHandler<Void, DbException> handler) { final ResultExceptionHandler<Void, DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { LocalAuthor localAuthor = identityManager.getLocalAuthor();
try { List<Contact> contacts = new ArrayList<>();
LocalAuthor localAuthor = identityManager.getLocalAuthor(); for (ContactId c : contactIds) {
List<Contact> contacts = new ArrayList<>(); try {
for (ContactId c : contactIds) { contacts.add(contactManager.getContact(c));
try { } catch (NoSuchContactException e) {
contacts.add(contactManager.getContact(c)); // Continue
} catch (NoSuchContactException e) {
// Continue
}
} }
signInvitations(g, localAuthor, contacts, message, handler);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
signInvitations(g, localAuthor, contacts, message, handler);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
}); });
} }
@@ -163,46 +148,39 @@ class CreateGroupControllerImpl extends ContactSelectorControllerImpl
private void signInvitations(final GroupId g, final LocalAuthor localAuthor, private void signInvitations(final GroupId g, final LocalAuthor localAuthor,
final Collection<Contact> contacts, final String message, final Collection<Contact> contacts, final String message,
final ResultExceptionHandler<Void, DbException> handler) { final ResultExceptionHandler<Void, DbException> handler) {
cryptoExecutor.execute(new Runnable() { cryptoExecutor.execute(() -> {
@Override long timestamp = clock.currentTimeMillis();
public void run() { List<InvitationContext> contexts = new ArrayList<>();
long timestamp = clock.currentTimeMillis(); for (Contact c : contacts) {
List<InvitationContext> contexts = new ArrayList<>(); byte[] signature = groupInvitationFactory.signInvitation(c, g,
for (Contact c : contacts) { timestamp, localAuthor.getPrivateKey());
byte[] signature = groupInvitationFactory.signInvitation(c, contexts.add(new InvitationContext(c.getId(), timestamp,
g, timestamp, localAuthor.getPrivateKey()); signature));
contexts.add(new InvitationContext(c.getId(), timestamp,
signature));
}
sendInvitations(g, contexts, message, handler);
} }
sendInvitations(g, contexts, message, handler);
}); });
} }
private void sendInvitations(final GroupId g, private void sendInvitations(final GroupId g,
final Collection<InvitationContext> contexts, final String message, final Collection<InvitationContext> contexts, final String message,
final ResultExceptionHandler<Void, DbException> handler) { final ResultExceptionHandler<Void, DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { String msg = message.isEmpty() ? null : message;
try { for (InvitationContext context : contexts) {
String msg = message.isEmpty() ? null : message; try {
for (InvitationContext context : contexts) { groupInvitationManager.sendInvitation(g,
try { context.contactId, msg, context.timestamp,
groupInvitationManager.sendInvitation(g, context.signature);
context.contactId, msg, context.timestamp, } catch (NoSuchContactException e) {
context.signature); // Continue
} catch (NoSuchContactException e) {
// Continue
}
} }
//noinspection ConstantConditions
handler.onResult(null);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
//noinspection ConstantConditions
handler.onResult(null);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
}); });
} }

View File

@@ -5,16 +5,12 @@ import android.os.Bundle;
import android.support.design.widget.TextInputLayout; import android.support.design.widget.TextInputLayout;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import org.briarproject.bramble.util.StringUtils; import org.briarproject.bramble.util.StringUtils;
import org.briarproject.briar.R; import org.briarproject.briar.R;
@@ -65,24 +61,15 @@ public class CreateGroupFragment extends BaseFragment {
public void afterTextChanged(Editable s) { public void afterTextChanged(Editable s) {
} }
}); });
nameEntry.setOnEditorActionListener(new OnEditorActionListener() { nameEntry.setOnEditorActionListener((v1, actionId, e) -> {
@Override createGroup();
public boolean onEditorAction(TextView v, int actionId, return true;
KeyEvent e) {
createGroup();
return true;
}
}); });
nameLayout = (TextInputLayout) v.findViewById(R.id.nameLayout); nameLayout = (TextInputLayout) v.findViewById(R.id.nameLayout);
createGroupButton = (Button) v.findViewById(R.id.button); createGroupButton = (Button) v.findViewById(R.id.button);
createGroupButton.setOnClickListener(new OnClickListener() { createGroupButton.setOnClickListener(v1 -> createGroup());
@Override
public void onClick(View v) {
createGroup();
}
});
progress = (ProgressBar) v.findViewById(R.id.progressBar); progress = (ProgressBar) v.findViewById(R.id.progressBar);

View File

@@ -67,18 +67,14 @@ class GroupInvitationControllerImpl
public void respondToInvitation(final GroupInvitationItem item, public void respondToInvitation(final GroupInvitationItem item,
final boolean accept, final boolean accept,
final ExceptionHandler<DbException> handler) { final ExceptionHandler<DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { PrivateGroup g = item.getShareable();
try { ContactId c = item.getCreator().getId();
PrivateGroup g = item.getShareable(); groupInvitationManager.respondToInvitation(c, g, accept);
ContactId c = item.getCreator().getId(); } catch (DbException e) {
groupInvitationManager.respondToInvitation(c, g, accept); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) { handler.onException(e);
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
} }
}); });
} }

View File

@@ -120,80 +120,54 @@ class GroupListControllerImpl extends DbControllerImpl
} }
private void onGroupMessageAdded(final GroupMessageHeader h) { private void onGroupMessageAdded(final GroupMessageHeader h) {
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(
@Override () -> listener.onGroupMessageAdded(h));
public void run() {
listener.onGroupMessageAdded(h);
}
});
} }
private void onGroupInvitationReceived() { private void onGroupInvitationReceived() {
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(
@Override () -> listener.onGroupInvitationReceived());
public void run() {
listener.onGroupInvitationReceived();
}
});
} }
private void onGroupAdded(final GroupId g) { private void onGroupAdded(final GroupId g) {
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(() -> listener.onGroupAdded(g));
@Override
public void run() {
listener.onGroupAdded(g);
}
});
} }
private void onGroupRemoved(final GroupId g) { private void onGroupRemoved(final GroupId g) {
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(() -> listener.onGroupRemoved(g));
@Override
public void run() {
listener.onGroupRemoved(g);
}
});
} }
private void onGroupDissolved(final GroupId g) { private void onGroupDissolved(final GroupId g) {
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(
@Override () -> listener.onGroupDissolved(g));
public void run() {
listener.onGroupDissolved(g);
}
});
} }
@Override @Override
public void loadGroups( public void loadGroups(
final ResultExceptionHandler<Collection<GroupItem>, DbException> handler) { final ResultExceptionHandler<Collection<GroupItem>, DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { long now = System.currentTimeMillis();
try { Collection<PrivateGroup> groups =
long now = System.currentTimeMillis(); groupManager.getPrivateGroups();
Collection<PrivateGroup> groups = List<GroupItem> items = new ArrayList<>(groups.size());
groupManager.getPrivateGroups(); for (PrivateGroup g : groups) {
List<GroupItem> items = new ArrayList<>(groups.size()); try {
for (PrivateGroup g : groups) { GroupId id = g.getId();
try { GroupCount count = groupManager.getGroupCount(id);
GroupId id = g.getId(); boolean dissolved = groupManager.isDissolved(id);
GroupCount count = groupManager.getGroupCount(id); items.add(new GroupItem(g, count, dissolved));
boolean dissolved = groupManager.isDissolved(id); } catch (NoSuchGroupException e) {
items.add(new GroupItem(g, count, dissolved)); // Continue
} catch (NoSuchGroupException e) {
// Continue
}
} }
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading groups took " + duration + " ms");
handler.onResult(items);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading groups took " + duration + " ms");
handler.onResult(items);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
}); });
} }
@@ -201,20 +175,16 @@ class GroupListControllerImpl extends DbControllerImpl
@Override @Override
public void removeGroup(final GroupId g, public void removeGroup(final GroupId g,
final ExceptionHandler<DbException> handler) { final ExceptionHandler<DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { long now = System.currentTimeMillis();
try { groupManager.removePrivateGroup(g);
long now = System.currentTimeMillis(); long duration = System.currentTimeMillis() - now;
groupManager.removePrivateGroup(g); if (LOG.isLoggable(INFO))
long duration = System.currentTimeMillis() - now; LOG.info("Removing group took " + duration + " ms");
if (LOG.isLoggable(INFO)) } catch (DbException e) {
LOG.info("Removing group took " + duration + " ms"); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) { handler.onException(e);
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
} }
}); });
} }
@@ -222,17 +192,13 @@ class GroupListControllerImpl extends DbControllerImpl
@Override @Override
public void loadAvailableGroups( public void loadAvailableGroups(
final ResultExceptionHandler<Integer, DbException> handler) { final ResultExceptionHandler<Integer, DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { handler.onResult(
try { groupInvitationManager.getInvitations().size());
handler.onResult( } catch (DbException e) {
groupInvitationManager.getInvitations().size()); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) { handler.onException(e);
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
} }
}); });
} }

View File

@@ -4,7 +4,6 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Button; import android.widget.Button;
import android.widget.TextView; import android.widget.TextView;
@@ -107,25 +106,17 @@ class GroupViewHolder extends RecyclerView.ViewHolder {
status status
.setText(ctx.getString(R.string.groups_group_is_dissolved)); .setText(ctx.getString(R.string.groups_group_is_dissolved));
status.setVisibility(VISIBLE); status.setVisibility(VISIBLE);
remove.setOnClickListener(new OnClickListener() { remove.setOnClickListener(v -> listener.onGroupRemoveClick(group));
@Override
public void onClick(View v) {
listener.onGroupRemoveClick(group);
}
});
remove.setVisibility(VISIBLE); remove.setVisibility(VISIBLE);
} }
// Open Group on Click // Open Group on Click
layout.setOnClickListener(new OnClickListener() { layout.setOnClickListener(v -> {
@Override Intent i = new Intent(ctx, GroupActivity.class);
public void onClick(View v) { GroupId id = group.getId();
Intent i = new Intent(ctx, GroupActivity.class); i.putExtra(GROUP_ID, id.getBytes());
GroupId id = group.getId(); i.putExtra(GROUP_NAME, group.getName());
i.putExtra(GROUP_ID, id.getBytes()); ctx.startActivity(i);
i.putExtra(GROUP_NAME, group.getName());
ctx.startActivity(i);
}
}); });
} }

View File

@@ -42,26 +42,22 @@ class GroupMemberListControllerImpl extends DbControllerImpl
@Override @Override
public void loadMembers(final GroupId groupId, final public void loadMembers(final GroupId groupId, final
ResultExceptionHandler<Collection<MemberListItem>, DbException> handler) { ResultExceptionHandler<Collection<MemberListItem>, DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { Collection<MemberListItem> items = new ArrayList<>();
try { Collection<GroupMember> members =
Collection<MemberListItem> items = new ArrayList<>(); privateGroupManager.getMembers(groupId);
Collection<GroupMember> members = for (GroupMember m : members) {
privateGroupManager.getMembers(groupId); ContactId c = m.getContactId();
for (GroupMember m : members) { boolean online = false;
ContactId c = m.getContactId(); if (c != null)
boolean online = false; online = connectionRegistry.isConnected(c);
if (c != null) items.add(new MemberListItem(m, online));
online = connectionRegistry.isConnected(c);
items.add(new MemberListItem(m, online));
}
handler.onResult(items);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
handler.onResult(items);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
}); });
} }

View File

@@ -1,6 +1,5 @@
package org.briarproject.briar.android.privategroup.reveal; package org.briarproject.briar.android.privategroup.reveal;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.LayoutRes; import android.support.annotation.LayoutRes;
@@ -110,19 +109,8 @@ public class RevealContactsActivity extends ContactSelectorActivity
new AlertDialog.Builder(this, R.style.OnboardingDialogTheme) new AlertDialog.Builder(this, R.style.OnboardingDialogTheme)
.setMessage(getString(R.string.groups_reveal_dialog_message)) .setMessage(getString(R.string.groups_reveal_dialog_message))
.setNeutralButton(R.string.got_it, .setNeutralButton(R.string.got_it,
new DialogInterface.OnClickListener() { (dialog, which) -> dialog.cancel())
@Override .setOnCancelListener(dialog -> onboardingShown())
public void onClick(DialogInterface dialog,
int which) {
dialog.cancel();
}
})
.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
onboardingShown();
}
})
.show(); .show();
} }

View File

@@ -62,18 +62,12 @@ class RevealContactsControllerImpl extends DbControllerImpl
public void loadContacts(final GroupId g, public void loadContacts(final GroupId g,
final Collection<ContactId> selection, final Collection<ContactId> selection,
final ResultExceptionHandler<Collection<RevealableContactItem>, DbException> handler) { final ResultExceptionHandler<Collection<RevealableContactItem>, DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { handler.onResult(getItems(g, selection));
try { } catch (DbException e) {
Collection<RevealableContactItem> items = if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
getItems(g, selection); handler.onException(e);
handler.onResult(items);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
} }
}); });
} }
@@ -105,38 +99,31 @@ class RevealContactsControllerImpl extends DbControllerImpl
@Override @Override
public void isOnboardingNeeded( public void isOnboardingNeeded(
final ResultExceptionHandler<Boolean, DbException> handler) { final ResultExceptionHandler<Boolean, DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { Settings settings =
try { settingsManager.getSettings(SETTINGS_NAMESPACE);
Settings settings = handler.onResult(
settingsManager.getSettings(SETTINGS_NAMESPACE); settings.getBoolean(SHOW_ONBOARDING_REVEAL_CONTACTS,
handler.onResult( true));
settings.getBoolean(SHOW_ONBOARDING_REVEAL_CONTACTS, } catch (DbException e) {
true)); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) { handler.onException(e);
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
} }
}); });
} }
@Override @Override
public void onboardingShown(ExceptionHandler<DbException> handler) { public void onboardingShown(ExceptionHandler<DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { Settings settings = new Settings();
try { settings.putBoolean(SHOW_ONBOARDING_REVEAL_CONTACTS, false);
Settings settings = new Settings(); settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
settings.putBoolean(SHOW_ONBOARDING_REVEAL_CONTACTS, false); } catch (DbException e) {
settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE); if (LOG.isLoggable(WARNING))
} catch (DbException e) { LOG.log(WARNING, e.toString(), e);
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
}); });
} }
@@ -144,22 +131,19 @@ class RevealContactsControllerImpl extends DbControllerImpl
@Override @Override
public void reveal(final GroupId g, final Collection<ContactId> contacts, public void reveal(final GroupId g, final Collection<ContactId> contacts,
final ExceptionHandler<DbException> handler) { final ExceptionHandler<DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override for (ContactId c : contacts) {
public void run() { try {
for (ContactId c : contacts) { groupInvitationManager.revealRelationship(c, g);
try { } catch (ProtocolStateException e) {
groupInvitationManager.revealRelationship(c, g); // action is outdated, move to next contact
} catch (ProtocolStateException e) { if (LOG.isLoggable(INFO))
// action is outdated, move to next contact LOG.log(INFO, e.toString(), e);
if (LOG.isLoggable(INFO)) } catch (DbException e) {
LOG.log(INFO, e.toString(), e); if (LOG.isLoggable(WARNING))
} catch (DbException e) { LOG.log(WARNING, e.toString(), e);
if (LOG.isLoggable(WARNING)) handler.onException(e);
LOG.log(WARNING, e.toString(), e); break;
handler.onException(e);
break;
}
} }
} }
}); });

View File

@@ -256,12 +256,9 @@ public class BriarReportPrimer implements ReportPrimer {
Looper.prepare(); Looper.prepare();
Handler handler = new Handler(); Handler handler = new Handler();
handler.post(runnable); handler.post(runnable);
handler.post(new Runnable() { handler.post(() -> {
@Override Looper looper = Looper.myLooper();
public void run() { if (looper != null) looper.quit();
Looper looper = Looper.myLooper();
if (looper != null) looper.quit();
}
}); });
Looper.loop(); Looper.loop();
} }

View File

@@ -1,6 +1,5 @@
package org.briarproject.briar.android.reporting; package org.briarproject.briar.android.reporting;
import android.content.Context;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
@@ -37,6 +36,7 @@ import java.util.logging.Logger;
import static android.view.View.GONE; import static android.view.View.GONE;
import static android.view.View.INVISIBLE; import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE; import static android.view.View.VISIBLE;
import static android.view.inputmethod.InputMethodManager.SHOW_FORCED;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.acra.ACRAConstants.EXTRA_REPORT_FILE; import static org.acra.ACRAConstants.EXTRA_REPORT_FILE;
import static org.acra.ReportField.ANDROID_VERSION; import static org.acra.ReportField.ANDROID_VERSION;
@@ -115,37 +115,22 @@ public class DevReportActivity extends BaseCrashReportDialog
includeDebugReport.setChecked(true); includeDebugReport.setChecked(true);
} }
findViewById(R.id.acceptButton).setOnClickListener( findViewById(R.id.acceptButton).setOnClickListener(v -> {
new View.OnClickListener() { reviewing = true;
@Override requestReport.setVisibility(GONE);
public void onClick(View v) { ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE))
reviewing = true; .showSoftInput(userCommentView, SHOW_FORCED);
requestReport.setVisibility(GONE); });
((InputMethodManager) getSystemService( findViewById(R.id.declineButton).setOnClickListener(v -> closeReport());
Context.INPUT_METHOD_SERVICE)) chevron.setOnClickListener(v -> {
.showSoftInput(userCommentView, boolean show =
InputMethodManager.SHOW_FORCED); chevron.getText().equals(getString(R.string.show));
} if (show) {
}); chevron.setText(R.string.hide);
findViewById(R.id.declineButton).setOnClickListener( refresh();
new View.OnClickListener() { } else {
@Override chevron.setText(R.string.show);
public void onClick(View v) { report.setVisibility(GONE);
closeReport();
}
});
chevron.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean show =
chevron.getText().equals(getString(R.string.show));
if (show) {
chevron.setText(R.string.hide);
refresh();
} else {
chevron.setText(R.string.show);
report.setVisibility(GONE);
}
} }
}); });

View File

@@ -141,54 +141,39 @@ public class SettingsFragment extends PreferenceFragmentCompat
notifyLockscreen.setVisible(true); notifyLockscreen.setVisible(true);
notifyLockscreen.setOnPreferenceChangeListener(this); notifyLockscreen.setOnPreferenceChangeListener(this);
} }
notifySound.setOnPreferenceClickListener( notifySound.setOnPreferenceClickListener(preference -> {
new Preference.OnPreferenceClickListener() { String title = getString(R.string.choose_ringtone_title);
@Override Intent i = new Intent(ACTION_RINGTONE_PICKER);
public boolean onPreferenceClick(Preference preference) { i.putExtra(EXTRA_RINGTONE_TYPE, TYPE_NOTIFICATION);
String title = i.putExtra(EXTRA_RINGTONE_TITLE, title);
getString(R.string.choose_ringtone_title); i.putExtra(EXTRA_RINGTONE_DEFAULT_URI, DEFAULT_NOTIFICATION_URI);
Intent i = new Intent(ACTION_RINGTONE_PICKER); i.putExtra(EXTRA_RINGTONE_SHOW_SILENT, true);
i.putExtra(EXTRA_RINGTONE_TYPE, TYPE_NOTIFICATION); if (settings.getBoolean(PREF_NOTIFY_SOUND, true)) {
i.putExtra(EXTRA_RINGTONE_TITLE, title); Uri uri;
i.putExtra(EXTRA_RINGTONE_DEFAULT_URI, String ringtoneUri = settings.get(PREF_NOTIFY_RINGTONE_URI);
DEFAULT_NOTIFICATION_URI); if (StringUtils.isNullOrEmpty(ringtoneUri))
i.putExtra(EXTRA_RINGTONE_SHOW_SILENT, true); uri = DEFAULT_NOTIFICATION_URI;
if (settings.getBoolean(PREF_NOTIFY_SOUND, true)) { else uri = Uri.parse(ringtoneUri);
Uri uri; i.putExtra(EXTRA_RINGTONE_EXISTING_URI, uri);
String ringtoneUri = }
settings.get(PREF_NOTIFY_RINGTONE_URI); startActivityForResult(i, REQUEST_RINGTONE);
if (StringUtils.isNullOrEmpty(ringtoneUri)) return true;
uri = DEFAULT_NOTIFICATION_URI; });
else uri = Uri.parse(ringtoneUri);
i.putExtra(EXTRA_RINGTONE_EXISTING_URI, uri);
}
startActivityForResult(i, REQUEST_RINGTONE);
return true;
}
});
findPreference("pref_key_send_feedback").setOnPreferenceClickListener( findPreference("pref_key_send_feedback").setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() { preference -> {
@Override triggerFeedback();
public boolean onPreferenceClick(Preference preference) { return true;
triggerFeedback();
return true;
}
}); });
Preference testData = findPreference("pref_key_test_data"); Preference testData = findPreference("pref_key_test_data");
if (IS_DEBUG_BUILD) { if (IS_DEBUG_BUILD) {
testData.setOnPreferenceClickListener( testData.setOnPreferenceClickListener(preference -> {
new Preference.OnPreferenceClickListener() { LOG.info("Creating test data");
@Override testDataCreator.createTestData();
public boolean onPreferenceClick( getActivity().finish();
Preference preference) { return true;
LOG.info("Creating test data"); });
testDataCreator.createTestData();
getActivity().finish();
return true;
}
});
} else { } else {
testData.setVisible(false); testData.setVisible(false);
} }
@@ -209,83 +194,69 @@ public class SettingsFragment extends PreferenceFragmentCompat
} }
private void loadSettings() { private void loadSettings() {
listener.runOnDbThread(new Runnable() { listener.runOnDbThread(() -> {
@Override try {
public void run() { long now = System.currentTimeMillis();
try { settings = settingsManager.getSettings(SETTINGS_NAMESPACE);
long now = System.currentTimeMillis(); Settings btSettings = settingsManager.getSettings(BT_NAMESPACE);
settings = settingsManager.getSettings(SETTINGS_NAMESPACE); Settings torSettings =
Settings btSettings = settingsManager.getSettings(TOR_NAMESPACE);
settingsManager.getSettings(BT_NAMESPACE); long duration = System.currentTimeMillis() - now;
Settings torSettings = if (LOG.isLoggable(INFO))
settingsManager.getSettings(TOR_NAMESPACE); LOG.info("Loading settings took " + duration + " ms");
long duration = System.currentTimeMillis() - now; boolean btSetting =
if (LOG.isLoggable(INFO)) btSettings.getBoolean(PREF_BT_ENABLE, false);
LOG.info("Loading settings took " + duration + " ms"); int torSetting = torSettings.getInt(PREF_TOR_NETWORK,
boolean btSetting = PREF_TOR_NETWORK_ALWAYS);
btSettings.getBoolean(PREF_BT_ENABLE, false); displaySettings(btSetting, torSetting);
int torSetting = torSettings.getInt(PREF_TOR_NETWORK, } catch (DbException e) {
PREF_TOR_NETWORK_ALWAYS); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
displaySettings(btSetting, torSetting);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
}); });
} }
private void displaySettings(final boolean btSetting, private void displaySettings(final boolean btSetting,
final int torSetting) { final int torSetting) {
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(() -> {
@Override enableBluetooth.setValue(Boolean.toString(btSetting));
public void run() { torNetwork.setValue(Integer.toString(torSetting));
enableBluetooth.setValue(Boolean.toString(btSetting));
torNetwork.setValue(Integer.toString(torSetting));
notifyPrivateMessages.setChecked(settings.getBoolean( notifyPrivateMessages.setChecked(settings.getBoolean(
PREF_NOTIFY_PRIVATE, true)); PREF_NOTIFY_PRIVATE, true));
notifyGroupMessages.setChecked(settings.getBoolean( notifyGroupMessages.setChecked(settings.getBoolean(
PREF_NOTIFY_GROUP, true)); PREF_NOTIFY_GROUP, true));
notifyForumPosts.setChecked(settings.getBoolean( notifyForumPosts.setChecked(settings.getBoolean(
PREF_NOTIFY_FORUM, true)); PREF_NOTIFY_FORUM, true));
notifyBlogPosts.setChecked(settings.getBoolean( notifyBlogPosts.setChecked(settings.getBoolean(
PREF_NOTIFY_BLOG, true)); PREF_NOTIFY_BLOG, true));
notifyVibration.setChecked(settings.getBoolean( notifyVibration.setChecked(settings.getBoolean(
PREF_NOTIFY_VIBRATION, true)); PREF_NOTIFY_VIBRATION, true));
notifyLockscreen.setChecked(settings.getBoolean( notifyLockscreen.setChecked(settings.getBoolean(
PREF_NOTIFY_LOCK_SCREEN, false)); PREF_NOTIFY_LOCK_SCREEN, false));
String text; String text;
if (settings.getBoolean(PREF_NOTIFY_SOUND, true)) { if (settings.getBoolean(PREF_NOTIFY_SOUND, true)) {
String ringtoneName = String ringtoneName = settings.get(PREF_NOTIFY_RINGTONE_NAME);
settings.get(PREF_NOTIFY_RINGTONE_NAME); if (StringUtils.isNullOrEmpty(ringtoneName)) {
if (StringUtils.isNullOrEmpty(ringtoneName)) { text = getString(R.string.notify_sound_setting_default);
text = getString(R.string.notify_sound_setting_default);
} else {
text = ringtoneName;
}
} else { } else {
text = getString(R.string.notify_sound_setting_disabled); text = ringtoneName;
} }
notifySound.setSummary(text); } else {
text = getString(R.string.notify_sound_setting_disabled);
} }
notifySound.setSummary(text);
}); });
} }
private void triggerFeedback() { private void triggerFeedback() {
androidExecutor.runOnBackgroundThread(new Runnable() { androidExecutor.runOnBackgroundThread(() -> ACRA.getErrorReporter()
@Override .handleException(new UserFeedback(), false));
public void run() {
ACRA.getErrorReporter().handleException(new UserFeedback(),
false);
}
});
} }
@Override @Override
@@ -331,59 +302,47 @@ public class SettingsFragment extends PreferenceFragmentCompat
} }
private void storeTorSettings(final int torSetting) { private void storeTorSettings(final int torSetting) {
listener.runOnDbThread(new Runnable() { listener.runOnDbThread(() -> {
@Override try {
public void run() { Settings s = new Settings();
try { s.putInt(PREF_TOR_NETWORK, torSetting);
Settings s = new Settings(); long now = System.currentTimeMillis();
s.putInt(PREF_TOR_NETWORK, torSetting); settingsManager.mergeSettings(s, TOR_NAMESPACE);
long now = System.currentTimeMillis(); long duration = System.currentTimeMillis() - now;
settingsManager.mergeSettings(s, TOR_NAMESPACE); if (LOG.isLoggable(INFO))
long duration = System.currentTimeMillis() - now; LOG.info("Merging settings took " + duration + " ms");
if (LOG.isLoggable(INFO)) } catch (DbException e) {
LOG.info("Merging settings took " + duration + " ms"); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
}); });
} }
private void storeBluetoothSettings(final boolean btSetting) { private void storeBluetoothSettings(final boolean btSetting) {
listener.runOnDbThread(new Runnable() { listener.runOnDbThread(() -> {
@Override try {
public void run() { Settings s = new Settings();
try { s.putBoolean(PREF_BT_ENABLE, btSetting);
Settings s = new Settings(); long now = System.currentTimeMillis();
s.putBoolean(PREF_BT_ENABLE, btSetting); settingsManager.mergeSettings(s, BT_NAMESPACE);
long now = System.currentTimeMillis(); long duration = System.currentTimeMillis() - now;
settingsManager.mergeSettings(s, BT_NAMESPACE); if (LOG.isLoggable(INFO))
long duration = System.currentTimeMillis() - now; LOG.info("Merging settings took " + duration + " ms");
if (LOG.isLoggable(INFO)) } catch (DbException e) {
LOG.info("Merging settings took " + duration + " ms"); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
}); });
} }
private void storeSettings(final Settings settings) { private void storeSettings(final Settings settings) {
listener.runOnDbThread(new Runnable() { listener.runOnDbThread(() -> {
@Override try {
public void run() { long now = System.currentTimeMillis();
try { settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
long now = System.currentTimeMillis(); long duration = System.currentTimeMillis() - now;
settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE); if (LOG.isLoggable(INFO))
long duration = System.currentTimeMillis() - now; LOG.info("Merging settings took " + duration + " ms");
if (LOG.isLoggable(INFO)) } catch (DbException e) {
LOG.info("Merging settings took " + duration + " ms"); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
}); });
} }

View File

@@ -61,20 +61,16 @@ class BlogInvitationControllerImpl
public void respondToInvitation(final SharingInvitationItem item, public void respondToInvitation(final SharingInvitationItem item,
final boolean accept, final boolean accept,
final ExceptionHandler<DbException> handler) { final ExceptionHandler<DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { Blog f = (Blog) item.getShareable();
try { for (Contact c : item.getNewSharers()) {
Blog f = (Blog) item.getShareable(); // TODO: What happens if a contact has been removed?
for (Contact c : item.getNewSharers()) { blogSharingManager.respondToInvitation(f, c, accept);
// TODO: What happens if a contact has been removed?
blogSharingManager.respondToInvitation(f, c, accept);
}
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
}); });
} }

View File

@@ -62,20 +62,16 @@ class ForumInvitationControllerImpl
public void respondToInvitation(final SharingInvitationItem item, public void respondToInvitation(final SharingInvitationItem item,
final boolean accept, final boolean accept,
final ExceptionHandler<DbException> handler) { final ExceptionHandler<DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { Forum f = (Forum) item.getShareable();
try { for (Contact c : item.getNewSharers()) {
Forum f = (Forum) item.getShareable(); // TODO: What happens if a contact has been removed?
for (Contact c : item.getNewSharers()) { forumSharingManager.respondToInvitation(f, c, accept);
// TODO: What happens if a contact has been removed?
forumSharingManager.respondToInvitation(f, c, accept);
}
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
}); });
} }

View File

@@ -123,20 +123,17 @@ public abstract class InvitationActivity<I extends InvitationItem>
protected void displayInvitations(final int revision, protected void displayInvitations(final int revision,
final Collection<I> invitations, final boolean clear) { final Collection<I> invitations, final boolean clear) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override if (invitations.isEmpty()) {
public void run() { LOG.info("No more invitations available, finishing");
if (invitations.isEmpty()) { supportFinishAfterTransition();
LOG.info("No more invitations available, finishing"); } else if (revision == adapter.getRevision()) {
supportFinishAfterTransition(); adapter.incrementRevision();
} else if (revision == adapter.getRevision()) { if (clear) adapter.setItems(invitations);
adapter.incrementRevision(); else adapter.addAll(invitations);
if (clear) adapter.setItems(invitations); } else {
else adapter.addAll(invitations); LOG.info("Concurrent update, reloading");
} else { loadInvitations(clear);
LOG.info("Concurrent update, reloading");
loadInvitations(clear);
}
} }
}); });
} }

View File

@@ -93,23 +93,18 @@ public abstract class InvitationControllerImpl<I extends InvitationItem>
@Override @Override
public void loadInvitations(final boolean clear, public void loadInvitations(final boolean clear,
final ResultExceptionHandler<Collection<I>, DbException> handler) { final ResultExceptionHandler<Collection<I>, DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override Collection<I> invitations = new ArrayList<>();
public void run() { try {
Collection<I> invitations = new ArrayList<>(); long now = System.currentTimeMillis();
try { invitations.addAll(getInvitations());
long now = System.currentTimeMillis(); long duration = System.currentTimeMillis() - now;
invitations.addAll(getInvitations()); if (LOG.isLoggable(INFO))
long duration = System.currentTimeMillis() - now; LOG.info("Loading invitations took " + duration + " ms");
if (LOG.isLoggable(INFO)) handler.onResult(invitations);
LOG.info( } catch (DbException e) {
"Loading invitations took " + duration + " ms"); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
handler.onResult(invitations); handler.onException(e);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
} }
}); });
} }

View File

@@ -53,18 +53,8 @@ public class InvitationViewHolder<I extends InvitationItem>
subscribed.setVisibility(GONE); subscribed.setVisibility(GONE);
} }
accept.setOnClickListener(new View.OnClickListener() { accept.setOnClickListener(v -> listener.onItemClick(item, true));
@Override decline.setOnClickListener(v -> listener.onItemClick(item, false));
public void onClick(View v) {
listener.onItemClick(item, true);
}
});
decline.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
listener.onItemClick(item, false);
}
});
} }
} }

View File

@@ -58,27 +58,23 @@ class ShareBlogControllerImpl extends ContactSelectorControllerImpl
public void share(final GroupId g, final Collection<ContactId> contacts, public void share(final GroupId g, final Collection<ContactId> contacts,
final String message, final String message,
final ExceptionHandler<DbException> handler) { final ExceptionHandler<DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { String msg = isNullOrEmpty(message) ? null : message;
try { for (ContactId c : contacts) {
String msg = isNullOrEmpty(message) ? null : message; try {
for (ContactId c : contacts) { long time = Math.max(clock.currentTimeMillis(),
try { conversationManager.getGroupCount(c)
long time = Math.max(clock.currentTimeMillis(), .getLatestMsgTime() + 1);
conversationManager.getGroupCount(c) blogSharingManager.sendInvitation(g, c, msg, time);
.getLatestMsgTime() + 1); } catch (NoSuchContactException | NoSuchGroupException e) {
blogSharingManager.sendInvitation(g, c, msg, time); if (LOG.isLoggable(WARNING))
} catch (NoSuchContactException | NoSuchGroupException e) { LOG.log(WARNING, e.toString(), e);
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
}); });
} }

View File

@@ -58,27 +58,23 @@ class ShareForumControllerImpl extends ContactSelectorControllerImpl
public void share(final GroupId g, final Collection<ContactId> contacts, public void share(final GroupId g, final Collection<ContactId> contacts,
final String message, final String message,
final ExceptionHandler<DbException> handler) { final ExceptionHandler<DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { String msg = isNullOrEmpty(message) ? null : message;
try { for (ContactId c : contacts) {
String msg = isNullOrEmpty(message) ? null : message; try {
for (ContactId c : contacts) { long time = Math.max(clock.currentTimeMillis(),
try { conversationManager.getGroupCount(c)
long time = Math.max(clock.currentTimeMillis(), .getLatestMsgTime() + 1);
conversationManager.getGroupCount(c) forumSharingManager.sendInvitation(g, c, msg, time);
.getLatestMsgTime() + 1); } catch (NoSuchContactException | NoSuchGroupException e) {
forumSharingManager.sendInvitation(g, c, msg, time); if (LOG.isLoggable(WARNING))
} catch (NoSuchContactException | NoSuchGroupException e) { LOG.log(WARNING, e.toString(), e);
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
}); });
} }

View File

@@ -100,33 +100,25 @@ abstract class SharingStatusActivity extends BriarActivity {
} }
private void loadSharedWith() { private void loadSharedWith() {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { List<ContactItem> contactItems = new ArrayList<>();
try { for (Contact c : getSharedWith()) {
List<ContactItem> contactItems = new ArrayList<>(); boolean online = connectionRegistry.isConnected(c.getId());
for (Contact c : getSharedWith()) { ContactItem item = new ContactItem(c, online);
boolean online = contactItems.add(item);
connectionRegistry.isConnected(c.getId());
ContactItem item = new ContactItem(c, online);
contactItems.add(item);
}
displaySharedWith(contactItems);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} }
displaySharedWith(contactItems);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }
private void displaySharedWith(final List<ContactItem> contacts) { private void displaySharedWith(final List<ContactItem> contacts) {
runOnUiThreadUnlessDestroyed(new Runnable() { runOnUiThreadUnlessDestroyed(() -> {
@Override if (contacts.isEmpty()) list.showData();
public void run() { else adapter.addAll(contacts);
if (contacts.isEmpty()) list.showData();
else adapter.addAll(contacts);
}
}); });
} }

View File

@@ -43,12 +43,9 @@ public class SplashScreenActivity extends BaseActivity {
setContentView(R.layout.splash); setContentView(R.layout.splash);
new Handler().postDelayed(new Runnable() { new Handler().postDelayed(() -> {
@Override startNextActivity();
public void run() { supportFinishAfterTransition();
startNextActivity();
supportFinishAfterTransition();
}
}, 500); }, 500);
} }
@@ -72,12 +69,8 @@ public class SplashScreenActivity extends BaseActivity {
} }
private void setPreferencesDefaults() { private void setPreferencesDefaults() {
androidExecutor.runOnBackgroundThread(new Runnable() { androidExecutor.runOnBackgroundThread(() ->
@Override
public void run() {
PreferenceManager.setDefaultValues(SplashScreenActivity.this, PreferenceManager.setDefaultValues(SplashScreenActivity.this,
R.xml.panic_preferences, false); R.xml.panic_preferences, false));
}
});
} }
} }

View File

@@ -85,13 +85,8 @@ public abstract class BaseThreadItemViewHolder<I extends ThreadItem>
public void onAnimationRepeat(Animator animation) { public void onAnimationRepeat(Animator animation) {
} }
}); });
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { anim.addUpdateListener(valueAnimator -> layout.setBackgroundColor(
@Override (Integer) valueAnimator.getAnimatedValue()));
public void onAnimationUpdate(ValueAnimator valueAnimator) {
layout.setBackgroundColor(
(Integer) valueAnimator.getAnimatedValue());
}
});
anim.setDuration(ANIMATION_DURATION); anim.setDuration(ANIMATION_DURATION);
anim.start(); anim.start();
} }

View File

@@ -10,7 +10,6 @@ import android.support.v7.app.ActionBar;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View;
import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
@@ -117,22 +116,16 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
}); });
upButton = (UnreadMessageButton) findViewById(R.id.upButton); upButton = (UnreadMessageButton) findViewById(R.id.upButton);
downButton = (UnreadMessageButton) findViewById(R.id.downButton); downButton = (UnreadMessageButton) findViewById(R.id.downButton);
upButton.setOnClickListener(new View.OnClickListener() { upButton.setOnClickListener(v -> {
@Override int position = adapter.getVisibleUnreadPosTop();
public void onClick(View v) { if (position != NO_POSITION) {
int position = adapter.getVisibleUnreadPosTop(); list.getRecyclerView().scrollToPosition(position);
if (position != NO_POSITION) {
list.getRecyclerView().scrollToPosition(position);
}
} }
}); });
downButton.setOnClickListener(new View.OnClickListener() { downButton.setOnClickListener(v -> {
@Override int position = adapter.getVisibleUnreadPosBottom();
public void onClick(View v) { if (position != NO_POSITION) {
int position = adapter.getVisibleUnreadPosBottom(); list.getRecyclerView().scrollToPosition(position);
if (position != NO_POSITION) {
list.getRecyclerView().scrollToPosition(position);
}
} }
}); });

View File

@@ -101,16 +101,12 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
public void onActivityDestroy() { public void onActivityDestroy() {
final MessageId messageId = listener.getFirstVisibleMessageId(); final MessageId messageId = listener.getFirstVisibleMessageId();
if (messageId != null) { if (messageId != null) {
dbExecutor.execute(new Runnable() { dbExecutor.execute(() -> {
@Override try {
public void run() { messageTracker.storeMessageId(groupId, messageId);
try { } catch (DbException e) {
messageTracker if (LOG.isLoggable(WARNING))
.storeMessageId(groupId, messageId); LOG.log(WARNING, e.toString(), e);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
} }
}); });
} }
@@ -123,12 +119,8 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
GroupRemovedEvent s = (GroupRemovedEvent) e; GroupRemovedEvent s = (GroupRemovedEvent) e;
if (s.getGroup().getId().equals(getGroupId())) { if (s.getGroup().getId().equals(getGroupId())) {
LOG.info("Group removed"); LOG.info("Group removed");
listener.runOnUiThreadUnlessDestroyed(new Runnable() { listener.runOnUiThreadUnlessDestroyed(
@Override () -> listener.onGroupRemoved());
public void run() {
listener.onGroupRemoved();
}
});
} }
} }
} }
@@ -137,21 +129,18 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
public void loadNamedGroup( public void loadNamedGroup(
final ResultExceptionHandler<G, DbException> handler) { final ResultExceptionHandler<G, DbException> handler) {
checkGroupId(); checkGroupId();
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { long now = System.currentTimeMillis();
try { G groupItem = loadNamedGroup();
long now = System.currentTimeMillis(); long duration = System.currentTimeMillis() - now;
G groupItem = loadNamedGroup(); if (LOG.isLoggable(INFO))
long duration = System.currentTimeMillis() - now; LOG.info("Loading group took " + duration + " ms");
if (LOG.isLoggable(INFO)) handler.onResult(groupItem);
LOG.info("Loading group took " + duration + " ms"); } catch (DbException e) {
handler.onResult(groupItem); if (LOG.isLoggable(WARNING))
} catch (DbException e) { LOG.log(WARNING, e.toString(), e);
if (LOG.isLoggable(WARNING)) handler.onException(e);
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
} }
}); });
} }
@@ -163,36 +152,32 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
public void loadItems( public void loadItems(
final ResultExceptionHandler<ThreadItemList<I>, DbException> handler) { final ResultExceptionHandler<ThreadItemList<I>, DbException> handler) {
checkGroupId(); checkGroupId();
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { // Load headers
try { long now = System.currentTimeMillis();
// Load headers Collection<H> headers = loadHeaders();
long now = System.currentTimeMillis(); long duration = System.currentTimeMillis() - now;
Collection<H> headers = loadHeaders(); if (LOG.isLoggable(INFO))
long duration = System.currentTimeMillis() - now; LOG.info("Loading headers took " + duration + " ms");
if (LOG.isLoggable(INFO))
LOG.info("Loading headers took " + duration + " ms");
// Load bodies into cache // Load bodies into cache
now = System.currentTimeMillis(); now = System.currentTimeMillis();
for (H header : headers) { for (H header : headers) {
if (!bodyCache.containsKey(header.getId())) { if (!bodyCache.containsKey(header.getId())) {
bodyCache.put(header.getId(), bodyCache.put(header.getId(),
loadMessageBody(header)); loadMessageBody(header));
}
} }
duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading bodies took " + duration + " ms");
// Build and hand over items
handler.onResult(buildItems(headers));
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading bodies took " + duration + " ms");
// Build and hand over items
handler.onResult(buildItems(headers));
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
handler.onException(e);
} }
}); });
} }
@@ -210,21 +195,17 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
@Override @Override
public void markItemsRead(final Collection<I> items) { public void markItemsRead(final Collection<I> items) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { long now = System.currentTimeMillis();
try { for (I i : items) {
long now = System.currentTimeMillis(); markRead(i.getId());
for (I i : items) {
markRead(i.getId());
}
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Marking read took " + duration + " ms");
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} }
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Marking read took " + duration + " ms");
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }
@@ -234,22 +215,18 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
protected void storePost(final M msg, final String body, protected void storePost(final M msg, final String body,
final ResultExceptionHandler<I, DbException> resultHandler) { final ResultExceptionHandler<I, DbException> resultHandler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { long now = System.currentTimeMillis();
try { H header = addLocalMessage(msg);
long now = System.currentTimeMillis(); bodyCache.put(msg.getMessage().getId(), body);
H header = addLocalMessage(msg); long duration = System.currentTimeMillis() - now;
bodyCache.put(msg.getMessage().getId(), body); if (LOG.isLoggable(INFO))
long duration = System.currentTimeMillis() - now; LOG.info("Storing message took " + duration + " ms");
if (LOG.isLoggable(INFO)) resultHandler.onResult(buildItem(header, body));
LOG.info("Storing message took " + duration + " ms"); } catch (DbException e) {
resultHandler.onResult(buildItem(header, body)); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) { resultHandler.onException(e);
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
resultHandler.onException(e);
}
} }
}); });
} }
@@ -259,21 +236,17 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
@Override @Override
public void deleteNamedGroup(final ExceptionHandler<DbException> handler) { public void deleteNamedGroup(final ExceptionHandler<DbException> handler) {
runOnDbThread(new Runnable() { runOnDbThread(() -> {
@Override try {
public void run() { long now = System.currentTimeMillis();
try { G groupItem = loadNamedGroup();
long now = System.currentTimeMillis(); deleteNamedGroup(groupItem);
G groupItem = loadNamedGroup(); long duration = System.currentTimeMillis() - now;
deleteNamedGroup(groupItem); if (LOG.isLoggable(INFO))
long duration = System.currentTimeMillis() - now; LOG.info("Removing group took " + duration + " ms");
if (LOG.isLoggable(INFO)) } catch (DbException e) {
LOG.info("Removing group took " + duration + " ms"); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (DbException e) { handler.onException(e);
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
} }
}); });
} }

View File

@@ -50,12 +50,7 @@ public class ThreadPostViewHolder<I extends ThreadItem>
lvlText.setVisibility(GONE); lvlText.setVisibility(GONE);
} }
replyButton.setOnClickListener(new View.OnClickListener() { replyButton.setOnClickListener(v -> listener.onReplyClick(item));
@Override
public void onClick(View v) {
listener.onReplyClick(item);
}
});
} }
} }

View File

@@ -3,7 +3,6 @@ package org.briarproject.briar.android.util;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener; import android.content.DialogInterface.OnClickListener;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
@@ -143,16 +142,13 @@ public class UiUtils {
public static OnClickListener getGoToSettingsListener( public static OnClickListener getGoToSettingsListener(
final Context context) { final Context context) {
return new OnClickListener() { return (dialog, which) -> {
@Override Intent i = new Intent();
public void onClick(DialogInterface dialog, int which) { i.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
Intent i = new Intent(); i.addCategory(CATEGORY_DEFAULT);
i.setAction("android.settings.APPLICATION_DETAILS_SETTINGS"); i.setData(Uri.parse("package:" + APPLICATION_ID));
i.addCategory(CATEGORY_DEFAULT); i.addFlags(FLAG_ACTIVITY_NEW_TASK);
i.setData(Uri.parse("package:" + APPLICATION_ID)); context.startActivity(i);
i.addFlags(FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}; };
} }
@@ -160,13 +156,7 @@ public class UiUtils {
new AlertDialog.Builder(ctx, R.style.OnboardingDialogTheme) new AlertDialog.Builder(ctx, R.style.OnboardingDialogTheme)
.setMessage(text) .setMessage(text)
.setNeutralButton(R.string.got_it, .setNeutralButton(R.string.got_it,
new DialogInterface.OnClickListener() { (dialog, which) -> dialog.cancel())
@Override
public void onClick(DialogInterface dialog,
int which) {
dialog.cancel();
}
})
.show(); .show();
} }

View File

@@ -94,24 +94,13 @@ public class BriarRecyclerView extends FrameLayout {
} }
private void addLayoutChangeListener() { private void addLayoutChangeListener() {
recyclerView.addOnLayoutChangeListener( recyclerView.addOnLayoutChangeListener((v, left, top, right, bottom,
new OnLayoutChangeListener() { oldLeft, oldTop, oldRight, oldBottom) -> {
@Override if (bottom < oldBottom) {
public void onLayoutChange(View v, int left, int top, recyclerView.postDelayed(() -> scrollToPosition(
int right, int bottom, int oldLeft, int oldTop, recyclerView.getAdapter().getItemCount() - 1), 100);
int oldRight, int oldBottom) { }
if (bottom < oldBottom) { });
recyclerView.postDelayed(new Runnable() {
@Override
public void run() {
scrollToPosition(
recyclerView.getAdapter()
.getItemCount() - 1);
}
}, 100);
}
}
});
} }
public void setLayoutManager(RecyclerView.LayoutManager layout) { public void setLayoutManager(RecyclerView.LayoutManager layout) {
@@ -191,14 +180,11 @@ public class BriarRecyclerView extends FrameLayout {
if (recyclerView == null || recyclerView.getAdapter() == null) { if (recyclerView == null || recyclerView.getAdapter() == null) {
throw new IllegalStateException("Need to call setAdapter() first!"); throw new IllegalStateException("Need to call setAdapter() first!");
} }
refresher = new Runnable() { refresher = () -> {
@Override LOG.info("Updating Content...");
public void run() { Adapter adapter = recyclerView.getAdapter();
LOG.info("Updating Content..."); adapter.notifyItemRangeChanged(0, adapter.getItemCount());
Adapter adapter = recyclerView.getAdapter(); handler.postDelayed(refresher, MIN_DATE_RESOLUTION);
adapter.notifyItemRangeChanged(0, adapter.getItemCount());
handler.postDelayed(refresher, MIN_DATE_RESOLUTION);
}
}; };
LOG.info("Adding Handler Callback"); LOG.info("Adding Handler Callback");
handler.postDelayed(refresher, MIN_DATE_RESOLUTION); handler.postDelayed(refresher, MIN_DATE_RESOLUTION);

View File

@@ -75,34 +75,18 @@ public class TextInputView extends KeyboardAwareLinearLayout
} }
ui.emojiToggle.attach(ui.emojiDrawer); ui.emojiToggle.attach(ui.emojiDrawer);
ui.emojiToggle.setOnClickListener(new OnClickListener() { ui.emojiToggle.setOnClickListener(v -> onEmojiToggleClicked());
@Override ui.editText.setOnClickListener(v -> showSoftKeyboard());
public void onClick(View v) { ui.editText.setOnKeyListener((v, keyCode, event) -> {
onEmojiToggleClicked(); if (keyCode == KEYCODE_BACK && isEmojiDrawerOpen()) {
hideEmojiDrawer();
return true;
} }
return false;
}); });
ui.editText.setOnClickListener(new OnClickListener() { ui.sendButton.setOnClickListener(v -> {
@Override if (listener != null) {
public void onClick(View v) { listener.onSendClick(ui.editText.getText().toString());
showSoftKeyboard();
}
});
ui.editText.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KEYCODE_BACK && isEmojiDrawerOpen()) {
hideEmojiDrawer();
return true;
}
return false;
}
});
ui.sendButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
listener.onSendClick(ui.editText.getText().toString());
}
} }
}); });
ui.emojiDrawer.setEmojiEventListener(this); ui.emojiDrawer.setEmojiEventListener(this);
@@ -167,22 +151,13 @@ public class TextInputView extends KeyboardAwareLinearLayout
if (isKeyboardOpen()) return; if (isKeyboardOpen()) return;
if (ui.emojiDrawer.isShowing()) { if (ui.emojiDrawer.isShowing()) {
postOnKeyboardOpen(new Runnable() { postOnKeyboardOpen(this::hideEmojiDrawer);
@Override
public void run() {
hideEmojiDrawer();
}
});
} }
ui.editText.post(new Runnable() { ui.editText.post(() -> {
@Override ui.editText.requestFocus();
public void run() { InputMethodManager imm = (InputMethodManager)
ui.editText.requestFocus(); getContext().getSystemService(INPUT_METHOD_SERVICE);
InputMethodManager imm = imm.showSoftInput(ui.editText, SHOW_IMPLICIT);
(InputMethodManager) getContext()
.getSystemService(INPUT_METHOD_SERVICE);
imm.showSoftInput(ui.editText, SHOW_IMPLICIT);
}
}); });
} }
@@ -194,11 +169,7 @@ public class TextInputView extends KeyboardAwareLinearLayout
public void showEmojiDrawer() { public void showEmojiDrawer() {
if (isKeyboardOpen()) { if (isKeyboardOpen()) {
postOnKeyboardClose(new Runnable() { postOnKeyboardClose(() -> ui.emojiDrawer.show(getKeyboardHeight()));
@Override public void run() {
ui.emojiDrawer.show(getKeyboardHeight());
}
});
hideSoftKeyboard(); hideSoftKeyboard();
} else { } else {
ui.emojiDrawer.show(getKeyboardHeight()); ui.emojiDrawer.show(getKeyboardHeight());

View File

@@ -8,7 +8,6 @@ import android.os.Bundle;
import android.support.v4.app.DialogFragment; import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Button; import android.widget.Button;
import android.widget.TextView; import android.widget.TextView;
@@ -62,21 +61,13 @@ public class LinkDialogFragment extends DialogFragment {
getString(R.string.link_warning_open_link)) : i; getString(R.string.link_warning_open_link)) : i;
Button openButton = (Button) v.findViewById(R.id.openButton); Button openButton = (Button) v.findViewById(R.id.openButton);
openButton.setOnClickListener(new OnClickListener() { openButton.setOnClickListener(v1 -> {
@Override startActivity(intent);
public void onClick(View v) { getDialog().dismiss();
startActivity(intent);
getDialog().dismiss();
}
}); });
Button cancelButton = (Button) v.findViewById(R.id.cancelButton); Button cancelButton = (Button) v.findViewById(R.id.cancelButton);
cancelButton.setOnClickListener(new OnClickListener() { cancelButton.setOnClickListener(v1 -> getDialog().cancel());
@Override
public void onClick(View v) {
getDialog().cancel();
}
});
return v; return v;
} }

Some files were not shown because too many files have changed in this diff Show More