mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-18 21:59:54 +01:00
Merge branch '1580-offline-state' into 'master'
Add offline state for pending contacts Closes #1580 See merge request briar/briar!1138
This commit is contained in:
@@ -3,6 +3,7 @@ package org.briarproject.bramble.api.contact;
|
|||||||
public enum PendingContactState {
|
public enum PendingContactState {
|
||||||
|
|
||||||
WAITING_FOR_CONNECTION,
|
WAITING_FOR_CONNECTION,
|
||||||
|
OFFLINE,
|
||||||
CONNECTING,
|
CONNECTING,
|
||||||
ADDING_CONTACT,
|
ADDING_CONTACT,
|
||||||
FAILED
|
FAILED
|
||||||
|
|||||||
@@ -147,7 +147,6 @@ class ContactManagerImpl implements ContactManager, EventListener {
|
|||||||
} finally {
|
} finally {
|
||||||
db.endTransaction(txn);
|
db.endTransaction(txn);
|
||||||
}
|
}
|
||||||
states.put(p.getId(), WAITING_FOR_CONNECTION);
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ import static java.util.logging.Level.WARNING;
|
|||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.api.contact.PendingContactState.ADDING_CONTACT;
|
import static org.briarproject.bramble.api.contact.PendingContactState.ADDING_CONTACT;
|
||||||
import static org.briarproject.bramble.api.contact.PendingContactState.FAILED;
|
import static org.briarproject.bramble.api.contact.PendingContactState.FAILED;
|
||||||
|
import static org.briarproject.bramble.api.contact.PendingContactState.OFFLINE;
|
||||||
import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION;
|
import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION;
|
||||||
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNull;
|
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNull;
|
||||||
import static org.briarproject.bramble.rendezvous.RendezvousConstants.POLLING_INTERVAL_MS;
|
import static org.briarproject.bramble.rendezvous.RendezvousConstants.POLLING_INTERVAL_MS;
|
||||||
@@ -158,9 +159,7 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
|
|||||||
private void addPendingContact(PendingContact p) {
|
private void addPendingContact(PendingContact p) {
|
||||||
long now = clock.currentTimeMillis();
|
long now = clock.currentTimeMillis();
|
||||||
long expiry = p.getTimestamp() + RENDEZVOUS_TIMEOUT_MS;
|
long expiry = p.getTimestamp() + RENDEZVOUS_TIMEOUT_MS;
|
||||||
if (expiry > now) {
|
if (expiry <= now) {
|
||||||
broadcastState(p.getId(), WAITING_FOR_CONNECTION);
|
|
||||||
} else {
|
|
||||||
broadcastState(p.getId(), FAILED);
|
broadcastState(p.getId(), FAILED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -180,9 +179,13 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
|
|||||||
for (PluginState ps : pluginStates.values()) {
|
for (PluginState ps : pluginStates.values()) {
|
||||||
RendezvousEndpoint endpoint =
|
RendezvousEndpoint endpoint =
|
||||||
createEndpoint(ps.plugin, p.getId(), cs);
|
createEndpoint(ps.plugin, p.getId(), cs);
|
||||||
if (endpoint != null)
|
if (endpoint != null) {
|
||||||
requireNull(ps.endpoints.put(p.getId(), endpoint));
|
requireNull(ps.endpoints.put(p.getId(), endpoint));
|
||||||
|
cs.numEndpoints++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (cs.numEndpoints == 0) broadcastState(p.getId(), OFFLINE);
|
||||||
|
else broadcastState(p.getId(), WAITING_FOR_CONNECTION);
|
||||||
} catch (DbException | GeneralSecurityException e) {
|
} catch (DbException | GeneralSecurityException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
}
|
}
|
||||||
@@ -328,9 +331,14 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
|
|||||||
TransportId t = plugin.getId();
|
TransportId t = plugin.getId();
|
||||||
Map<PendingContactId, RendezvousEndpoint> endpoints = new HashMap<>();
|
Map<PendingContactId, RendezvousEndpoint> endpoints = new HashMap<>();
|
||||||
for (Entry<PendingContactId, CryptoState> e : cryptoStates.entrySet()) {
|
for (Entry<PendingContactId, CryptoState> e : cryptoStates.entrySet()) {
|
||||||
RendezvousEndpoint endpoint =
|
PendingContactId p = e.getKey();
|
||||||
createEndpoint(plugin, e.getKey(), e.getValue());
|
CryptoState cs = e.getValue();
|
||||||
if (endpoint != null) endpoints.put(e.getKey(), endpoint);
|
RendezvousEndpoint endpoint = createEndpoint(plugin, p, cs);
|
||||||
|
if (endpoint != null) {
|
||||||
|
endpoints.put(p, endpoint);
|
||||||
|
if (++cs.numEndpoints == 1)
|
||||||
|
broadcastState(p, WAITING_FOR_CONNECTION);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
requireNull(pluginStates.put(t, new PluginState(plugin, endpoints)));
|
requireNull(pluginStates.put(t, new PluginState(plugin, endpoints)));
|
||||||
}
|
}
|
||||||
@@ -344,8 +352,11 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
|
|||||||
private void removeTransport(TransportId t) {
|
private void removeTransport(TransportId t) {
|
||||||
PluginState ps = pluginStates.remove(t);
|
PluginState ps = pluginStates.remove(t);
|
||||||
if (ps != null) {
|
if (ps != null) {
|
||||||
for (RendezvousEndpoint endpoint : ps.endpoints.values()) {
|
for (Entry<PendingContactId, RendezvousEndpoint> e :
|
||||||
tryToClose(endpoint, LOG, INFO);
|
ps.endpoints.entrySet()) {
|
||||||
|
tryToClose(e.getValue(), LOG, INFO);
|
||||||
|
CryptoState cs = cryptoStates.get(e.getKey());
|
||||||
|
if (--cs.numEndpoints == 0) broadcastState(e.getKey(), OFFLINE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -391,6 +402,8 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
|
|||||||
private final boolean alice;
|
private final boolean alice;
|
||||||
private final long expiry;
|
private final long expiry;
|
||||||
|
|
||||||
|
private int numEndpoints = 0;
|
||||||
|
|
||||||
private CryptoState(SecretKey rendezvousKey, boolean alice,
|
private CryptoState(SecretKey rendezvousKey, boolean alice,
|
||||||
long expiry) {
|
long expiry) {
|
||||||
this.rendezvousKey = rendezvousKey;
|
this.rendezvousKey = rendezvousKey;
|
||||||
|
|||||||
@@ -6,11 +6,15 @@ import org.briarproject.bramble.api.contact.ContactManager;
|
|||||||
import org.briarproject.bramble.api.contact.PendingContact;
|
import org.briarproject.bramble.api.contact.PendingContact;
|
||||||
import org.briarproject.bramble.api.contact.PendingContactState;
|
import org.briarproject.bramble.api.contact.PendingContactState;
|
||||||
import org.briarproject.bramble.api.contact.event.ContactAddedEvent;
|
import org.briarproject.bramble.api.contact.event.ContactAddedEvent;
|
||||||
|
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent;
|
||||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
|
import org.briarproject.bramble.api.event.Event;
|
||||||
|
import org.briarproject.bramble.api.event.EventListener;
|
||||||
import org.briarproject.bramble.api.identity.Identity;
|
import org.briarproject.bramble.api.identity.Identity;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.test.BrambleTestCase;
|
import org.briarproject.bramble.test.BrambleTestCase;
|
||||||
import org.briarproject.bramble.test.TestDatabaseConfigModule;
|
import org.briarproject.bramble.test.TestDatabaseConfigModule;
|
||||||
import org.briarproject.bramble.test.TestDuplexTransportConnection;
|
import org.briarproject.bramble.test.TestDuplexTransportConnection;
|
||||||
@@ -27,7 +31,7 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
|||||||
import static junit.framework.TestCase.assertNotNull;
|
import static junit.framework.TestCase.assertNotNull;
|
||||||
import static junit.framework.TestCase.assertNull;
|
import static junit.framework.TestCase.assertNull;
|
||||||
import static junit.framework.TestCase.fail;
|
import static junit.framework.TestCase.fail;
|
||||||
import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION;
|
import static org.briarproject.bramble.api.contact.PendingContactState.OFFLINE;
|
||||||
import static org.briarproject.bramble.test.TestDuplexTransportConnection.createPair;
|
import static org.briarproject.bramble.test.TestDuplexTransportConnection.createPair;
|
||||||
import static org.briarproject.bramble.test.TestPluginConfigModule.DUPLEX_TRANSPORT_ID;
|
import static org.briarproject.bramble.test.TestPluginConfigModule.DUPLEX_TRANSPORT_ID;
|
||||||
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
|
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
|
||||||
@@ -188,9 +192,14 @@ public class ContactExchangeIntegrationTest extends BrambleTestCase {
|
|||||||
private PendingContact addPendingContact(
|
private PendingContact addPendingContact(
|
||||||
ContactExchangeIntegrationTestComponent local,
|
ContactExchangeIntegrationTestComponent local,
|
||||||
ContactExchangeIntegrationTestComponent remote) throws Exception {
|
ContactExchangeIntegrationTestComponent remote) throws Exception {
|
||||||
|
EventWaiter waiter = new EventWaiter();
|
||||||
|
local.getEventBus().addListener(waiter);
|
||||||
String link = remote.getContactManager().getHandshakeLink();
|
String link = remote.getContactManager().getHandshakeLink();
|
||||||
String alias = remote.getIdentityManager().getLocalAuthor().getName();
|
String alias = remote.getIdentityManager().getLocalAuthor().getName();
|
||||||
return local.getContactManager().addPendingContact(link, alias);
|
PendingContact pendingContact =
|
||||||
|
local.getContactManager().addPendingContact(link, alias);
|
||||||
|
waiter.latch.await(TIMEOUT, MILLISECONDS);
|
||||||
|
return pendingContact;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertContacts(boolean verified,
|
private void assertContacts(boolean verified,
|
||||||
@@ -237,7 +246,7 @@ public class ContactExchangeIntegrationTest extends BrambleTestCase {
|
|||||||
assertEquals(1, pairs.size());
|
assertEquals(1, pairs.size());
|
||||||
Pair<PendingContact, PendingContactState> pair =
|
Pair<PendingContact, PendingContactState> pair =
|
||||||
pairs.iterator().next();
|
pairs.iterator().next();
|
||||||
assertEquals(WAITING_FOR_CONNECTION, pair.getSecond());
|
assertEquals(OFFLINE, pair.getSecond());
|
||||||
PendingContact pendingContact = pair.getFirst();
|
PendingContact pendingContact = pair.getFirst();
|
||||||
assertEquals(expectedIdentity.getLocalAuthor().getName(),
|
assertEquals(expectedIdentity.getLocalAuthor().getName(),
|
||||||
pendingContact.getAlias());
|
pendingContact.getAlias());
|
||||||
@@ -261,4 +270,19 @@ public class ContactExchangeIntegrationTest extends BrambleTestCase {
|
|||||||
tearDown(bob);
|
tearDown(bob);
|
||||||
deleteTestDirectory(testDir);
|
deleteTestDirectory(testDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNullByDefault
|
||||||
|
private static class EventWaiter implements EventListener {
|
||||||
|
|
||||||
|
private final CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eventOccurred(Event e) {
|
||||||
|
if (e instanceof PendingContactStateChangedEvent) {
|
||||||
|
PendingContactStateChangedEvent p =
|
||||||
|
(PendingContactStateChangedEvent) e;
|
||||||
|
if (p.getPendingContactState() == OFFLINE) latch.countDown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import static java.util.Collections.singletonList;
|
|||||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
import static org.briarproject.bramble.api.contact.PendingContactState.ADDING_CONTACT;
|
import static org.briarproject.bramble.api.contact.PendingContactState.ADDING_CONTACT;
|
||||||
import static org.briarproject.bramble.api.contact.PendingContactState.FAILED;
|
import static org.briarproject.bramble.api.contact.PendingContactState.FAILED;
|
||||||
|
import static org.briarproject.bramble.api.contact.PendingContactState.OFFLINE;
|
||||||
import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION;
|
import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION;
|
||||||
import static org.briarproject.bramble.rendezvous.RendezvousConstants.POLLING_INTERVAL_MS;
|
import static org.briarproject.bramble.rendezvous.RendezvousConstants.POLLING_INTERVAL_MS;
|
||||||
import static org.briarproject.bramble.rendezvous.RendezvousConstants.RENDEZVOUS_TIMEOUT_MS;
|
import static org.briarproject.bramble.rendezvous.RendezvousConstants.RENDEZVOUS_TIMEOUT_MS;
|
||||||
@@ -120,7 +121,7 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
|||||||
will(returnValue(beforeExpiry));
|
will(returnValue(beforeExpiry));
|
||||||
oneOf(eventBus).broadcast(with(new PredicateMatcher<>(
|
oneOf(eventBus).broadcast(with(new PredicateMatcher<>(
|
||||||
PendingContactStateChangedEvent.class, e ->
|
PendingContactStateChangedEvent.class, e ->
|
||||||
e.getPendingContactState() == WAITING_FOR_CONNECTION)));
|
e.getPendingContactState() == OFFLINE)));
|
||||||
// Capture the poll task
|
// Capture the poll task
|
||||||
oneOf(scheduler).scheduleAtFixedRate(with(any(Runnable.class)),
|
oneOf(scheduler).scheduleAtFixedRate(with(any(Runnable.class)),
|
||||||
with(POLLING_INTERVAL_MS), with(POLLING_INTERVAL_MS),
|
with(POLLING_INTERVAL_MS), with(POLLING_INTERVAL_MS),
|
||||||
@@ -184,7 +185,7 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
|||||||
context.assertIsSatisfied();
|
context.assertIsSatisfied();
|
||||||
|
|
||||||
// Add the pending contact - endpoint should be created and polled
|
// Add the pending contact - endpoint should be created and polled
|
||||||
expectAddUnexpiredPendingContact(beforeExpiry);
|
expectAddPendingContact(beforeExpiry, WAITING_FOR_CONNECTION);
|
||||||
expectDeriveRendezvousKey();
|
expectDeriveRendezvousKey();
|
||||||
expectCreateEndpoint();
|
expectCreateEndpoint();
|
||||||
|
|
||||||
@@ -205,9 +206,7 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
|||||||
context.assertIsSatisfied();
|
context.assertIsSatisfied();
|
||||||
|
|
||||||
// Remove the pending contact - endpoint should be closed
|
// Remove the pending contact - endpoint should be closed
|
||||||
context.checking(new Expectations() {{
|
expectCloseEndpoint();
|
||||||
oneOf(rendezvousEndpoint).close();
|
|
||||||
}});
|
|
||||||
|
|
||||||
rendezvousPoller.eventOccurred(
|
rendezvousPoller.eventOccurred(
|
||||||
new PendingContactRemovedEvent(pendingContact.getId()));
|
new PendingContactRemovedEvent(pendingContact.getId()));
|
||||||
@@ -238,7 +237,7 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
|||||||
context.assertIsSatisfied();
|
context.assertIsSatisfied();
|
||||||
|
|
||||||
// Add the pending contact - endpoint should be created and polled
|
// Add the pending contact - endpoint should be created and polled
|
||||||
expectAddUnexpiredPendingContact(beforeExpiry);
|
expectAddPendingContact(beforeExpiry, WAITING_FOR_CONNECTION);
|
||||||
expectDeriveRendezvousKey();
|
expectDeriveRendezvousKey();
|
||||||
expectCreateEndpoint();
|
expectCreateEndpoint();
|
||||||
|
|
||||||
@@ -260,10 +259,7 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
|||||||
|
|
||||||
// Run the poll task - pending contact expires, endpoint is closed
|
// Run the poll task - pending contact expires, endpoint is closed
|
||||||
expectPendingContactExpires(afterExpiry);
|
expectPendingContactExpires(afterExpiry);
|
||||||
|
expectCloseEndpoint();
|
||||||
context.checking(new Expectations() {{
|
|
||||||
oneOf(rendezvousEndpoint).close();
|
|
||||||
}});
|
|
||||||
|
|
||||||
capturePollTask.get().run();
|
capturePollTask.get().run();
|
||||||
context.assertIsSatisfied();
|
context.assertIsSatisfied();
|
||||||
@@ -289,7 +285,7 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
|||||||
context.assertIsSatisfied();
|
context.assertIsSatisfied();
|
||||||
|
|
||||||
// Add the pending contact - no endpoints should be created yet
|
// Add the pending contact - no endpoints should be created yet
|
||||||
expectAddUnexpiredPendingContact(beforeExpiry);
|
expectAddPendingContact(beforeExpiry, OFFLINE);
|
||||||
expectDeriveRendezvousKey();
|
expectDeriveRendezvousKey();
|
||||||
|
|
||||||
rendezvousPoller.eventOccurred(
|
rendezvousPoller.eventOccurred(
|
||||||
@@ -299,14 +295,14 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
|||||||
// Enable the transport - endpoint should be created
|
// Enable the transport - endpoint should be created
|
||||||
expectGetPlugin();
|
expectGetPlugin();
|
||||||
expectCreateEndpoint();
|
expectCreateEndpoint();
|
||||||
|
expectStateChangedEvent(WAITING_FOR_CONNECTION);
|
||||||
|
|
||||||
rendezvousPoller.eventOccurred(new TransportEnabledEvent(transportId));
|
rendezvousPoller.eventOccurred(new TransportEnabledEvent(transportId));
|
||||||
context.assertIsSatisfied();
|
context.assertIsSatisfied();
|
||||||
|
|
||||||
// Disable the transport - endpoint should be closed
|
// Disable the transport - endpoint should be closed
|
||||||
context.checking(new Expectations() {{
|
expectCloseEndpoint();
|
||||||
oneOf(rendezvousEndpoint).close();
|
expectStateChangedEvent(OFFLINE);
|
||||||
}});
|
|
||||||
|
|
||||||
rendezvousPoller.eventOccurred(new TransportDisabledEvent(transportId));
|
rendezvousPoller.eventOccurred(new TransportDisabledEvent(transportId));
|
||||||
context.assertIsSatisfied();
|
context.assertIsSatisfied();
|
||||||
@@ -482,13 +478,14 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
|||||||
return capturePollTask;
|
return capturePollTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void expectAddUnexpiredPendingContact(long now) {
|
private void expectAddPendingContact(long now,
|
||||||
|
PendingContactState initialState) {
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(clock).currentTimeMillis();
|
oneOf(clock).currentTimeMillis();
|
||||||
will(returnValue(now));
|
will(returnValue(now));
|
||||||
oneOf(eventBus).broadcast(with(new PredicateMatcher<>(
|
oneOf(eventBus).broadcast(with(new PredicateMatcher<>(
|
||||||
PendingContactStateChangedEvent.class, e ->
|
PendingContactStateChangedEvent.class, e ->
|
||||||
e.getPendingContactState() == WAITING_FOR_CONNECTION)));
|
e.getPendingContactState() == initialState)));
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,7 +543,7 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
|||||||
will(returnValue(now));
|
will(returnValue(now));
|
||||||
oneOf(eventBus).broadcast(with(new PredicateMatcher<>(
|
oneOf(eventBus).broadcast(with(new PredicateMatcher<>(
|
||||||
PendingContactStateChangedEvent.class, e ->
|
PendingContactStateChangedEvent.class, e ->
|
||||||
e.getPendingContactState() == WAITING_FOR_CONNECTION)));
|
e.getPendingContactState() == OFFLINE)));
|
||||||
// Capture the poll task
|
// Capture the poll task
|
||||||
oneOf(scheduler).scheduleAtFixedRate(with(any(Runnable.class)),
|
oneOf(scheduler).scheduleAtFixedRate(with(any(Runnable.class)),
|
||||||
with(POLLING_INTERVAL_MS), with(POLLING_INTERVAL_MS),
|
with(POLLING_INTERVAL_MS), with(POLLING_INTERVAL_MS),
|
||||||
@@ -576,4 +573,10 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
|||||||
e.getPendingContactState() == state)));
|
e.getPendingContactState() == state)));
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void expectCloseEndpoint() throws Exception {
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
oneOf(rendezvousEndpoint).close();
|
||||||
|
}});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,11 @@ class PendingContactViewHolder extends ViewHolder {
|
|||||||
.getColor(status.getContext(), R.color.briar_yellow);
|
.getColor(status.getContext(), R.color.briar_yellow);
|
||||||
status.setText(R.string.waiting_for_contact_to_come_online);
|
status.setText(R.string.waiting_for_contact_to_come_online);
|
||||||
break;
|
break;
|
||||||
|
case OFFLINE:
|
||||||
|
color = ContextCompat
|
||||||
|
.getColor(status.getContext(), R.color.briar_yellow);
|
||||||
|
status.setText("");
|
||||||
|
break;
|
||||||
case CONNECTING:
|
case CONNECTING:
|
||||||
status.setText(R.string.connecting);
|
status.setText(R.string.connecting);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ This will return a JSON array of pending contacts and their states:
|
|||||||
The state can be one of these values:
|
The state can be one of these values:
|
||||||
|
|
||||||
* `waiting_for_connection`
|
* `waiting_for_connection`
|
||||||
|
* `offline`
|
||||||
* `connecting`
|
* `connecting`
|
||||||
* `adding_contact`
|
* `adding_contact`
|
||||||
* `failed`
|
* `failed`
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ internal fun PendingContact.output() = JsonDict(
|
|||||||
|
|
||||||
internal fun PendingContactState.output() = when(this) {
|
internal fun PendingContactState.output() = when(this) {
|
||||||
WAITING_FOR_CONNECTION -> "waiting_for_connection"
|
WAITING_FOR_CONNECTION -> "waiting_for_connection"
|
||||||
|
OFFLINE -> "offline"
|
||||||
CONNECTING -> "connecting"
|
CONNECTING -> "connecting"
|
||||||
ADDING_CONTACT -> "adding_contact"
|
ADDING_CONTACT -> "adding_contact"
|
||||||
FAILED -> "failed"
|
FAILED -> "failed"
|
||||||
|
|||||||
Reference in New Issue
Block a user