mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-16 04:39:54 +01:00
Lambdas.
This commit is contained in:
@@ -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);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
@@ -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
Reference in New Issue
Block a user