diff --git a/briar-android/src/org/briarproject/android/AndroidModule.java b/briar-android/src/org/briarproject/android/AndroidModule.java
index d3a7d8a4d..9dc8fcd88 100644
--- a/briar-android/src/org/briarproject/android/AndroidModule.java
+++ b/briar-android/src/org/briarproject/android/AndroidModule.java
@@ -93,10 +93,8 @@ public class AndroidModule {
AndroidNotificationManager provideAndroidNotificationManager(
LifecycleManager lifecycleManager, EventBus eventBus,
AndroidNotificationManagerImpl notificationManager) {
- lifecycleManager.register(notificationManager);
+ lifecycleManager.registerService(notificationManager);
eventBus.addListener(notificationManager);
-
return notificationManager;
}
-
}
diff --git a/briar-api/src/org/briarproject/api/clients/Client.java b/briar-api/src/org/briarproject/api/clients/Client.java
new file mode 100644
index 000000000..28954c238
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/clients/Client.java
@@ -0,0 +1,12 @@
+package org.briarproject.api.clients;
+
+import org.briarproject.api.db.DbException;
+import org.briarproject.api.db.Transaction;
+
+public interface Client {
+
+ /**
+ * Called at startup to create any local state needed by the client.
+ */
+ void createLocalState(Transaction txn) throws DbException;
+}
diff --git a/briar-api/src/org/briarproject/api/clients/PrivateGroupFactory.java b/briar-api/src/org/briarproject/api/clients/PrivateGroupFactory.java
index 3a8777572..01e268017 100644
--- a/briar-api/src/org/briarproject/api/clients/PrivateGroupFactory.java
+++ b/briar-api/src/org/briarproject/api/clients/PrivateGroupFactory.java
@@ -6,6 +6,9 @@ import org.briarproject.api.sync.Group;
public interface PrivateGroupFactory {
+ /** Creates a group that is not shared with any contacts. */
+ Group createLocalGroup(ClientId clientId);
+
/** Creates a group for the given client to share with the given contact. */
Group createPrivateGroup(ClientId clientId, Contact contact);
}
diff --git a/briar-api/src/org/briarproject/api/db/DatabaseComponent.java b/briar-api/src/org/briarproject/api/db/DatabaseComponent.java
index a360fa98b..2a627fb8a 100644
--- a/briar-api/src/org/briarproject/api/db/DatabaseComponent.java
+++ b/briar-api/src/org/briarproject/api/db/DatabaseComponent.java
@@ -44,6 +44,7 @@ public interface DatabaseComponent {
*
* This method acquires locks, so it must not be called while holding a
* lock.
+ *
* @param readOnly true if the transaction will only be used for reading.
*/
Transaction startTransaction(boolean readOnly) throws DbException;
@@ -90,13 +91,27 @@ public interface DatabaseComponent {
void addTransportKeys(Transaction txn, ContactId c, TransportKeys k)
throws DbException;
+ /**
+ * Returns true if the database contains the given contact for the given
+ * local pseudonym.
+ */
+ boolean containsContact(Transaction txn, AuthorId remote, AuthorId local)
+ throws DbException;
+
+ /**
+ * Returns true if the database contains the given group.
+ */
+ boolean containsGroup(Transaction txn, GroupId g) throws DbException;
+
/**
* Deletes the message with the given ID. The message ID and any other
* associated data are not deleted.
*/
void deleteMessage(Transaction txn, MessageId m) throws DbException;
- /** Deletes any metadata associated with the given message. */
+ /**
+ * Deletes any metadata associated with the given message.
+ */
void deleteMessageMetadata(Transaction txn, MessageId m) throws DbException;
/**
@@ -162,13 +177,6 @@ public interface DatabaseComponent {
Collection getContacts(Transaction txn, AuthorId a)
throws DbException;
- /**
- * Returns true if the database contains the given contact for the given
- * local pseudonym.
- */
- boolean containsContact(Transaction txn, AuthorId remote, AuthorId local)
- throws DbException;
-
/**
* Returns the unique ID for this device.
*
@@ -359,7 +367,7 @@ public interface DatabaseComponent {
* Marks the given contact as active or inactive.
*/
void setContactActive(Transaction txn, ContactId c, boolean active)
- throws DbException;
+ throws DbException;
/**
* Marks the given message as shared or unshared.
diff --git a/briar-api/src/org/briarproject/api/lifecycle/LifecycleManager.java b/briar-api/src/org/briarproject/api/lifecycle/LifecycleManager.java
index 5f75237c2..536c9c309 100644
--- a/briar-api/src/org/briarproject/api/lifecycle/LifecycleManager.java
+++ b/briar-api/src/org/briarproject/api/lifecycle/LifecycleManager.java
@@ -1,32 +1,49 @@
package org.briarproject.api.lifecycle;
+import org.briarproject.api.clients.Client;
+
import java.util.concurrent.ExecutorService;
/**
- * Manages the lifecycle of the app, starting and stopping {@link Service
- * Services}, shutting down {@link java.util.concurrent.ExecutorService
+ * Manages the lifecycle of the app, starting {@link
+ * org.briarproject.api.clients.Client Clients}, starting and stopping {@link
+ * Service Services}, shutting down {@link java.util.concurrent.ExecutorService
* ExecutorServices}, and opening and closing the {@link
* org.briarproject.api.db.DatabaseComponent DatabaseComponent}.
*/
public interface LifecycleManager {
- /** The result of calling {@link LifecycleManager#startServices()}. */
- enum StartResult { ALREADY_RUNNING, DB_ERROR, SERVICE_ERROR, SUCCESS }
+ /**
+ * The result of calling {@link LifecycleManager#startServices()}.
+ */
+ enum StartResult {
+ ALREADY_RUNNING, DB_ERROR, SERVICE_ERROR, SUCCESS
+ }
- /** Registers a {@link Service} to be started and stopped. */
- public void register(Service s);
+ /**
+ * Registers a {@link Service} to be started and stopped.
+ */
+ void registerService(Service s);
+
+ /**
+ * Registers a {@link org.briarproject.api.clients.Client Client} to be
+ * started.
+ */
+ void registerClient(Client c);
/**
* Registers an {@link java.util.concurrent.ExecutorService ExecutorService}
* to be shut down.
*/
- public void registerForShutdown(ExecutorService e);
+ void registerForShutdown(ExecutorService e);
/**
- * Starts any registered {@link Service Services} and opens the {@link
- * org.briarproject.api.db.DatabaseComponent DatabaseComponent}.
+ * Opens the {@link org.briarproject.api.db.DatabaseComponent
+ * DatabaseComponent} and starts any registered {@link
+ * org.briarproject.api.clients.Client Clients} and {@link Service
+ * Services}.
*/
- public StartResult startServices();
+ StartResult startServices();
/**
* Stops any registered {@link Service Services}, shuts down any
@@ -34,20 +51,21 @@ public interface LifecycleManager {
* and closes the {@link org.briarproject.api.db.DatabaseComponent
* DatabaseComponent}.
*/
- public void stopServices();
+ void stopServices();
/**
* Waits for the {@link org.briarproject.api.db.DatabaseComponent
* DatabaseComponent} to be opened before returning.
*/
- public void waitForDatabase() throws InterruptedException;
+ void waitForDatabase() throws InterruptedException;
/**
* Waits for the {@link org.briarproject.api.db.DatabaseComponent
- * DatabaseComponent} to be opened and all registered {@link Service
+ * DatabaseComponent} to be opened and all registered {@link
+ * org.briarproject.api.clients.Client Clients} and {@link Service
* Services} to start before returning.
*/
- public void waitForStartup() throws InterruptedException;
+ void waitForStartup() throws InterruptedException;
/**
* Waits for all registered {@link Service Services} to stop, all
@@ -55,5 +73,5 @@ public interface LifecycleManager {
* to shut down, and the {@link org.briarproject.api.db.DatabaseComponent
* DatabaseComponent} to be closed before returning.
*/
- public void waitForShutdown() throws InterruptedException;
+ void waitForShutdown() throws InterruptedException;
}
\ No newline at end of file
diff --git a/briar-core/src/org/briarproject/clients/PrivateGroupFactoryImpl.java b/briar-core/src/org/briarproject/clients/PrivateGroupFactoryImpl.java
index bb0ede944..56ed9f530 100644
--- a/briar-core/src/org/briarproject/clients/PrivateGroupFactoryImpl.java
+++ b/briar-core/src/org/briarproject/clients/PrivateGroupFactoryImpl.java
@@ -16,6 +16,8 @@ import javax.inject.Inject;
class PrivateGroupFactoryImpl implements PrivateGroupFactory {
+ private static final byte[] LOCAL_GROUP_DESCRIPTOR = new byte[0];
+
private final GroupFactory groupFactory;
private final ClientHelper clientHelper;
@@ -26,6 +28,11 @@ class PrivateGroupFactoryImpl implements PrivateGroupFactory {
this.clientHelper = clientHelper;
}
+ @Override
+ public Group createLocalGroup(ClientId clientId) {
+ return groupFactory.createGroup(clientId, LOCAL_GROUP_DESCRIPTOR);
+ }
+
@Override
public Group createPrivateGroup(ClientId clientId, Contact contact) {
AuthorId local = contact.getLocalAuthorId();
diff --git a/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java b/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java
index 1b4d1c1b5..79ff34325 100644
--- a/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java
+++ b/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java
@@ -231,6 +231,20 @@ class DatabaseComponentImpl implements DatabaseComponent {
db.addTransportKeys(txn, c, k);
}
+ public boolean containsContact(Transaction transaction, AuthorId remote,
+ AuthorId local) throws DbException {
+ T txn = unbox(transaction);
+ if (!db.containsLocalAuthor(txn, local))
+ throw new NoSuchLocalAuthorException();
+ return db.containsContact(txn, remote, local);
+ }
+
+ public boolean containsGroup(Transaction transaction, GroupId g)
+ throws DbException {
+ T txn = unbox(transaction);
+ return db.containsGroup(txn, g);
+ }
+
public void deleteMessage(Transaction transaction, MessageId m)
throws DbException {
if (transaction.isReadOnly()) throw new IllegalArgumentException();
@@ -345,14 +359,6 @@ class DatabaseComponentImpl implements DatabaseComponent {
return db.getContacts(txn, a);
}
- public boolean containsContact(Transaction transaction, AuthorId remote,
- AuthorId local) throws DbException {
- T txn = unbox(transaction);
- if (!db.containsLocalAuthor(txn, local))
- throw new NoSuchLocalAuthorException();
- return db.containsContact(txn, remote, local);
- }
-
public DeviceId getDeviceId(Transaction transaction) throws DbException {
T txn = unbox(transaction);
return db.getDeviceId(txn);
diff --git a/briar-core/src/org/briarproject/forum/ForumModule.java b/briar-core/src/org/briarproject/forum/ForumModule.java
index 4a51872e7..f801e2770 100644
--- a/briar-core/src/org/briarproject/forum/ForumModule.java
+++ b/briar-core/src/org/briarproject/forum/ForumModule.java
@@ -3,14 +3,13 @@ package org.briarproject.forum;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent;
-import org.briarproject.api.data.BdfReaderFactory;
import org.briarproject.api.data.MetadataEncoder;
-import org.briarproject.api.data.MetadataParser;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.forum.ForumManager;
import org.briarproject.api.forum.ForumPostFactory;
import org.briarproject.api.forum.ForumSharingManager;
import org.briarproject.api.identity.AuthorFactory;
+import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.sync.ValidationManager;
import org.briarproject.api.system.Clock;
@@ -73,9 +72,11 @@ public class ForumModule {
@Provides
@Singleton
ForumSharingManager provideForumSharingManager(
+ LifecycleManager lifecycleManager,
ContactManager contactManager,
ValidationManager validationManager,
ForumSharingManagerImpl forumSharingManager) {
+ lifecycleManager.registerClient(forumSharingManager);
contactManager.registerAddContactHook(forumSharingManager);
contactManager.registerRemoveContactHook(forumSharingManager);
validationManager.registerIncomingMessageHook(
diff --git a/briar-core/src/org/briarproject/forum/ForumSharingManagerImpl.java b/briar-core/src/org/briarproject/forum/ForumSharingManagerImpl.java
index c30834e8f..b975a4537 100644
--- a/briar-core/src/org/briarproject/forum/ForumSharingManagerImpl.java
+++ b/briar-core/src/org/briarproject/forum/ForumSharingManagerImpl.java
@@ -1,6 +1,7 @@
package org.briarproject.forum;
import org.briarproject.api.FormatException;
+import org.briarproject.api.clients.Client;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.PrivateGroupFactory;
import org.briarproject.api.contact.Contact;
@@ -43,15 +44,13 @@ import static org.briarproject.api.forum.ForumConstants.FORUM_SALT_LENGTH;
import static org.briarproject.api.forum.ForumConstants.MAX_FORUM_NAME_LENGTH;
import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
-class ForumSharingManagerImpl implements ForumSharingManager, AddContactHook,
- RemoveContactHook, IncomingMessageHook {
+class ForumSharingManagerImpl implements ForumSharingManager, Client,
+ AddContactHook, RemoveContactHook, IncomingMessageHook {
static final ClientId CLIENT_ID = new ClientId(StringUtils.fromHexString(
"cd11a5d04dccd9e2931d6fc3df456313"
+ "63bb3e9d9d0e9405fccdb051f41f5449"));
- private static final byte[] LOCAL_GROUP_DESCRIPTOR = new byte[0];
-
private final DatabaseComponent db;
private final ForumManager forumManager;
private final ClientHelper clientHelper;
@@ -73,8 +72,14 @@ class ForumSharingManagerImpl implements ForumSharingManager, AddContactHook,
this.privateGroupFactory = privateGroupFactory;
this.random = random;
this.clock = clock;
- localGroup = groupFactory.createGroup(CLIENT_ID,
- LOCAL_GROUP_DESCRIPTOR);
+ localGroup = privateGroupFactory.createLocalGroup(CLIENT_ID);
+ }
+
+ @Override
+ public void createLocalState(Transaction txn) throws DbException {
+ db.addGroup(txn, localGroup);
+ // Ensure we've set things up for any pre-existing contacts
+ for (Contact c : db.getContacts(txn)) addingContact(txn, c);
}
@Override
@@ -82,6 +87,8 @@ class ForumSharingManagerImpl implements ForumSharingManager, AddContactHook,
try {
// Create a group to share with the contact
Group g = getContactGroup(c);
+ // Return if we've already set things up for this contact
+ if (db.containsGroup(txn, g.getId())) return;
// Store the group and share it with the contact
db.addGroup(txn, g);
db.setVisibleToContact(txn, c.getId(), g.getId(), true);
@@ -297,8 +304,6 @@ class ForumSharingManagerImpl implements ForumSharingManager, AddContactHook,
private List getForumsSharedWithAllContacts(Transaction txn)
throws DbException, FormatException {
- // Ensure the local group exists
- db.addGroup(txn, localGroup);
// Find the latest update in the local group
LatestUpdate latest = findLatest(txn, localGroup.getId(), true);
if (latest == null) return Collections.emptyList();
diff --git a/briar-core/src/org/briarproject/introduction/IntroductionManagerImpl.java b/briar-core/src/org/briarproject/introduction/IntroductionManagerImpl.java
index a01c62b10..e28af29e4 100644
--- a/briar-core/src/org/briarproject/introduction/IntroductionManagerImpl.java
+++ b/briar-core/src/org/briarproject/introduction/IntroductionManagerImpl.java
@@ -1,6 +1,7 @@
package org.briarproject.introduction;
import org.briarproject.api.FormatException;
+import org.briarproject.api.clients.Client;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.PrivateGroupFactory;
@@ -31,7 +32,6 @@ import org.briarproject.api.introduction.SessionId;
import org.briarproject.api.properties.TransportPropertyManager;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group;
-import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId;
@@ -82,14 +82,13 @@ import static org.briarproject.api.introduction.IntroductionConstants.TYPE_REQUE
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_RESPONSE;
class IntroductionManagerImpl extends BdfIncomingMessageHook
- implements IntroductionManager, AddContactHook, RemoveContactHook {
+ implements IntroductionManager, Client, AddContactHook,
+ RemoveContactHook {
static final ClientId CLIENT_ID = new ClientId(StringUtils.fromHexString(
"23b1897c198a90ae75b976ac023d0f32"
+ "80ca67b12f2346b2c23a34f34e2434c3"));
- private static final byte[] LOCAL_GROUP_DESCRIPTOR = new byte[0];
-
private static final Logger LOG =
Logger.getLogger(IntroductionManagerImpl.class.getName());
@@ -104,8 +103,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
@Inject
IntroductionManagerImpl(DatabaseComponent db,
MessageQueueManager messageQueueManager,
- ClientHelper clientHelper, GroupFactory groupFactory,
- PrivateGroupFactory privateGroupFactory,
+ ClientHelper clientHelper, PrivateGroupFactory privateGroupFactory,
MetadataEncoder metadataEncoder, MetadataParser metadataParser,
CryptoComponent cryptoComponent,
TransportPropertyManager transportPropertyManager,
@@ -117,6 +115,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
this.messageQueueManager = messageQueueManager;
this.privateGroupFactory = privateGroupFactory;
this.metadataEncoder = metadataEncoder;
+ // TODO: Inject these dependencies for easier testing
this.introducerManager =
new IntroducerManager(this, clientHelper, clock,
cryptoComponent);
@@ -124,8 +123,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
new IntroduceeManager(db, this, clientHelper, clock,
cryptoComponent, transportPropertyManager,
authorFactory, contactManager);
- localGroup =
- groupFactory.createGroup(CLIENT_ID, LOCAL_GROUP_DESCRIPTOR);
+ localGroup = privateGroupFactory.createLocalGroup(CLIENT_ID);
}
@Override
@@ -133,11 +131,21 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
return CLIENT_ID;
}
+ @Override
+ public void createLocalState(Transaction txn) throws DbException {
+ db.addGroup(txn, localGroup);
+ // Ensure we've set things up for any pre-existing contacts
+ for (Contact c : db.getContacts(txn)) addingContact(txn, c);
+ }
+
@Override
public void addingContact(Transaction txn, Contact c) throws DbException {
try {
- // create an introduction group for sending introduction messages
+ // Create an introduction group for sending introduction messages
Group g = getIntroductionGroup(c);
+ // Return if we've already set things up for this contact
+ if (db.containsGroup(txn, g.getId())) return;
+ // Store the group and share it with the contact
db.addGroup(txn, g);
db.setVisibleToContact(txn, c.getId(), g.getId(), true);
// Attach the contact ID to the group
@@ -169,7 +177,6 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
introducerManager.abort(txn, d);
}
}
-
}
} catch (FormatException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
@@ -189,9 +196,6 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
protected void incomingMessage(Transaction txn, Message m, BdfList body,
BdfDictionary message) throws DbException {
- // add local group for engine states to make sure it exists
- db.addGroup(txn, localGroup);
-
// Get message data and type
GroupId groupId = m.getGroupId();
message.put(GROUP_ID, groupId);
@@ -265,15 +269,13 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
public void makeIntroduction(Contact c1, Contact c2, String msg)
throws DbException, FormatException {
- Transaction txn = db.startTransaction(false);
- try {
- // add local group for session states to make sure it exists
- db.addGroup(txn, getLocalGroup());
- introducerManager.makeIntroduction(txn, c1, c2, msg);
- txn.setComplete();
- } finally {
- db.endTransaction(txn);
- }
+ Transaction txn = db.startTransaction(false);
+ try {
+ introducerManager.makeIntroduction(txn, c1, c2, msg);
+ txn.setComplete();
+ } finally {
+ db.endTransaction(txn);
+ }
}
@Override
@@ -468,7 +470,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
}
if (LOG.isLoggable(WARNING)) {
LOG.warning(
- "No session state found for this message with session ID " +
+ "No session state found for message with session ID " +
Arrays.hashCode(sessionId));
}
throw new FormatException();
@@ -505,5 +507,4 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
db.deleteMessage(txn, messageId);
db.deleteMessageMetadata(txn, messageId);
}
-
}
diff --git a/briar-core/src/org/briarproject/introduction/IntroductionModule.java b/briar-core/src/org/briarproject/introduction/IntroductionModule.java
index 686a34eda..4fb0e493d 100644
--- a/briar-core/src/org/briarproject/introduction/IntroductionModule.java
+++ b/briar-core/src/org/briarproject/introduction/IntroductionModule.java
@@ -5,6 +5,7 @@ import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.introduction.IntroductionManager;
+import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.system.Clock;
import javax.inject.Inject;
@@ -41,15 +42,17 @@ public class IntroductionModule {
@Provides
@Singleton
IntroductionManager getIntroductionManager(
+ LifecycleManager lifecycleManager,
ContactManager contactManager,
MessageQueueManager messageQueueManager,
IntroductionManagerImpl introductionManager) {
+ lifecycleManager.registerClient(introductionManager);
contactManager.registerAddContactHook(introductionManager);
contactManager.registerRemoveContactHook(introductionManager);
- messageQueueManager
- .registerIncomingMessageHook(introductionManager.getClientId(),
- introductionManager);
+ messageQueueManager.registerIncomingMessageHook(
+ introductionManager.getClientId(),
+ introductionManager);
return introductionManager;
}
diff --git a/briar-core/src/org/briarproject/lifecycle/LifecycleManagerImpl.java b/briar-core/src/org/briarproject/lifecycle/LifecycleManagerImpl.java
index f153a3a37..bd2d31765 100644
--- a/briar-core/src/org/briarproject/lifecycle/LifecycleManagerImpl.java
+++ b/briar-core/src/org/briarproject/lifecycle/LifecycleManagerImpl.java
@@ -1,14 +1,16 @@
package org.briarproject.lifecycle;
+import org.briarproject.api.clients.Client;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
+import org.briarproject.api.db.Transaction;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.ShutdownEvent;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.lifecycle.Service;
import java.io.IOException;
-import java.util.Collection;
+import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
@@ -31,8 +33,9 @@ class LifecycleManagerImpl implements LifecycleManager {
private final DatabaseComponent db;
private final EventBus eventBus;
- private final Collection services;
- private final Collection executors;
+ private final List services;
+ private final List clients;
+ private final List executors;
private final Semaphore startStopSemaphore = new Semaphore(1);
private final CountDownLatch dbLatch = new CountDownLatch(1);
private final CountDownLatch startupLatch = new CountDownLatch(1);
@@ -43,15 +46,22 @@ class LifecycleManagerImpl implements LifecycleManager {
this.db = db;
this.eventBus = eventBus;
services = new CopyOnWriteArrayList();
+ clients = new CopyOnWriteArrayList();
executors = new CopyOnWriteArrayList();
}
- public void register(Service s) {
+ public void registerService(Service s) {
if (LOG.isLoggable(INFO))
LOG.info("Registering service " + s.getClass().getName());
services.add(s);
}
+ public void registerClient(Client c) {
+ if (LOG.isLoggable(INFO))
+ LOG.info("Registering client " + c.getClass().getName());
+ clients.add(c);
+ }
+
public void registerForShutdown(ExecutorService e) {
if (LOG.isLoggable(INFO))
LOG.info("Registering executor " + e.getClass().getName());
@@ -74,15 +84,28 @@ class LifecycleManagerImpl implements LifecycleManager {
else LOG.info("Creating database took " + duration + " ms");
}
dbLatch.countDown();
+ Transaction txn = db.startTransaction(false);
+ try {
+ for (Client c : clients) {
+ start = System.currentTimeMillis();
+ c.createLocalState(txn);
+ duration = System.currentTimeMillis() - start;
+ if (LOG.isLoggable(INFO)) {
+ LOG.info("Starting " + c.getClass().getName()
+ + " took " + duration + " ms");
+ }
+ }
+ txn.setComplete();
+ } finally {
+ db.endTransaction(txn);
+ }
for (Service s : services) {
start = System.currentTimeMillis();
boolean started = s.start();
duration = System.currentTimeMillis() - start;
if (!started) {
- if (LOG.isLoggable(WARNING)) {
- String name = s.getClass().getName();
- LOG.warning(name + " did not start");
- }
+ if (LOG.isLoggable(WARNING))
+ LOG.warning(s.getClass().getName() + " did not start");
return SERVICE_ERROR;
}
if (LOG.isLoggable(INFO)) {
diff --git a/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java b/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java
index e7e64552f..93a0cc979 100644
--- a/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java
+++ b/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java
@@ -1,6 +1,7 @@
package org.briarproject.messaging;
import org.briarproject.api.FormatException;
+import org.briarproject.api.clients.Client;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.PrivateGroupFactory;
import org.briarproject.api.contact.Contact;
@@ -28,7 +29,7 @@ import java.util.Map;
import javax.inject.Inject;
-class MessagingManagerImpl implements MessagingManager, AddContactHook,
+class MessagingManagerImpl implements MessagingManager, Client, AddContactHook,
RemoveContactHook {
static final ClientId CLIENT_ID = new ClientId(StringUtils.fromHexString(
@@ -47,11 +48,19 @@ class MessagingManagerImpl implements MessagingManager, AddContactHook,
this.privateGroupFactory = privateGroupFactory;
}
+ @Override
+ public void createLocalState(Transaction txn) throws DbException {
+ // Ensure we've set things up for any pre-existing contacts
+ for (Contact c : db.getContacts(txn)) addingContact(txn, c);
+ }
+
@Override
public void addingContact(Transaction txn, Contact c) throws DbException {
try {
// Create a group to share with the contact
Group g = getContactGroup(c);
+ // Return if we've already set things up for this contact
+ if (db.containsGroup(txn, g.getId())) return;
// Store the group and share it with the contact
db.addGroup(txn, g);
db.setVisibleToContact(txn, c.getId(), g.getId(), true);
diff --git a/briar-core/src/org/briarproject/messaging/MessagingModule.java b/briar-core/src/org/briarproject/messaging/MessagingModule.java
index b943a6921..8fec2d9b6 100644
--- a/briar-core/src/org/briarproject/messaging/MessagingModule.java
+++ b/briar-core/src/org/briarproject/messaging/MessagingModule.java
@@ -3,6 +3,7 @@ package org.briarproject.messaging;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.data.MetadataEncoder;
+import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.messaging.MessagingManager;
import org.briarproject.api.messaging.PrivateMessageFactory;
import org.briarproject.api.sync.ValidationManager;
@@ -43,8 +44,10 @@ public class MessagingModule {
@Provides
@Singleton
- MessagingManager getMessagingManager(ContactManager contactManager,
+ MessagingManager getMessagingManager(LifecycleManager lifecycleManager,
+ ContactManager contactManager,
MessagingManagerImpl messagingManager) {
+ lifecycleManager.registerClient(messagingManager);
contactManager.registerAddContactHook(messagingManager);
contactManager.registerRemoveContactHook(messagingManager);
return messagingManager;
diff --git a/briar-core/src/org/briarproject/plugins/PluginsModule.java b/briar-core/src/org/briarproject/plugins/PluginsModule.java
index d106d8920..412948665 100644
--- a/briar-core/src/org/briarproject/plugins/PluginsModule.java
+++ b/briar-core/src/org/briarproject/plugins/PluginsModule.java
@@ -64,7 +64,7 @@ public class PluginsModule {
@Singleton
PluginManager getPluginManager(LifecycleManager lifecycleManager,
PluginManagerImpl pluginManager) {
- lifecycleManager.register(pluginManager);
+ lifecycleManager.registerService(pluginManager);
return pluginManager;
}
}
diff --git a/briar-core/src/org/briarproject/properties/PropertiesModule.java b/briar-core/src/org/briarproject/properties/PropertiesModule.java
index e9f2fcf58..cea2c7504 100644
--- a/briar-core/src/org/briarproject/properties/PropertiesModule.java
+++ b/briar-core/src/org/briarproject/properties/PropertiesModule.java
@@ -3,6 +3,7 @@ package org.briarproject.properties;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.data.MetadataEncoder;
+import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.properties.TransportPropertyManager;
import org.briarproject.api.sync.ValidationManager;
import org.briarproject.api.system.Clock;
@@ -36,8 +37,10 @@ public class PropertiesModule {
@Provides @Singleton
TransportPropertyManager getTransportPropertyManager(
+ LifecycleManager lifecycleManager,
ContactManager contactManager,
TransportPropertyManagerImpl transportPropertyManager) {
+ lifecycleManager.registerClient(transportPropertyManager);
contactManager.registerAddContactHook(transportPropertyManager);
contactManager.registerRemoveContactHook(transportPropertyManager);
return transportPropertyManager;
diff --git a/briar-core/src/org/briarproject/properties/TransportPropertyManagerImpl.java b/briar-core/src/org/briarproject/properties/TransportPropertyManagerImpl.java
index 4b10c48ed..f393e3eaa 100644
--- a/briar-core/src/org/briarproject/properties/TransportPropertyManagerImpl.java
+++ b/briar-core/src/org/briarproject/properties/TransportPropertyManagerImpl.java
@@ -3,6 +3,7 @@ package org.briarproject.properties;
import org.briarproject.api.DeviceId;
import org.briarproject.api.FormatException;
import org.briarproject.api.TransportId;
+import org.briarproject.api.clients.Client;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.PrivateGroupFactory;
import org.briarproject.api.contact.Contact;
@@ -13,13 +14,11 @@ import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
-import org.briarproject.api.db.NoSuchGroupException;
import org.briarproject.api.db.Transaction;
import org.briarproject.api.properties.TransportProperties;
import org.briarproject.api.properties.TransportPropertyManager;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group;
-import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId;
@@ -34,14 +33,12 @@ import java.util.Map.Entry;
import javax.inject.Inject;
class TransportPropertyManagerImpl implements TransportPropertyManager,
- AddContactHook, RemoveContactHook {
+ Client, AddContactHook, RemoveContactHook {
static final ClientId CLIENT_ID = new ClientId(StringUtils.fromHexString(
"673ea091673561e28f70122f6a8ea8f4"
+ "97c3624b86fa07f785bb15f09fb87b4b"));
- private static final byte[] LOCAL_GROUP_DESCRIPTOR = new byte[0];
-
private final DatabaseComponent db;
private final ClientHelper clientHelper;
private final PrivateGroupFactory privateGroupFactory;
@@ -50,20 +47,28 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
@Inject
TransportPropertyManagerImpl(DatabaseComponent db,
- ClientHelper clientHelper, GroupFactory groupFactory,
- PrivateGroupFactory privateGroupFactory, Clock clock) {
+ ClientHelper clientHelper, PrivateGroupFactory privateGroupFactory,
+ Clock clock) {
this.db = db;
this.clientHelper = clientHelper;
this.privateGroupFactory = privateGroupFactory;
this.clock = clock;
- localGroup = groupFactory.createGroup(CLIENT_ID,
- LOCAL_GROUP_DESCRIPTOR);
+ localGroup = privateGroupFactory.createLocalGroup(CLIENT_ID);
+ }
+
+ @Override
+ public void createLocalState(Transaction txn) throws DbException {
+ db.addGroup(txn, localGroup);
+ // Ensure we've set things up for any pre-existing contacts
+ for (Contact c : db.getContacts(txn)) addingContact(txn, c);
}
@Override
public void addingContact(Transaction txn, Contact c) throws DbException {
// Create a group to share with the contact
Group g = getContactGroup(c);
+ // Return if we've already set things up for this contact
+ if (db.containsGroup(txn, g.getId())) return;
// Store the group and share it with the contact
db.addGroup(txn, g);
db.setVisibleToContact(txn, c.getId(), g.getId(), true);
@@ -126,9 +131,6 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
db.endTransaction(txn);
}
return p;
- } catch (NoSuchGroupException e) {
- // Local group doesn't exist - there are no local properties
- return null;
} catch (FormatException e) {
throw new DbException(e);
}
@@ -169,8 +171,6 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
try {
Transaction txn = db.startTransaction(false);
try {
- // Create the local group if necessary
- db.addGroup(txn, localGroup);
// Merge the new properties with any existing properties
TransportProperties merged;
boolean changed;
@@ -230,9 +230,6 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
local.put(e.getKey(), parseProperties(message));
}
return local;
- } catch (NoSuchGroupException e) {
- // Local group doesn't exist - there are no local properties
- return Collections.emptyMap();
} catch (FormatException e) {
throw new DbException(e);
}
diff --git a/briar-core/src/org/briarproject/sync/SyncModule.java b/briar-core/src/org/briarproject/sync/SyncModule.java
index 15d13ce66..2cbbac5d7 100644
--- a/briar-core/src/org/briarproject/sync/SyncModule.java
+++ b/briar-core/src/org/briarproject/sync/SyncModule.java
@@ -62,7 +62,7 @@ public class SyncModule {
@Singleton
ValidationManager getValidationManager(LifecycleManager lifecycleManager,
EventBus eventBus, ValidationManagerImpl validationManager) {
- lifecycleManager.register(validationManager);
+ lifecycleManager.registerService(validationManager);
eventBus.addListener(validationManager);
return validationManager;
}
diff --git a/briar-core/src/org/briarproject/transport/TransportModule.java b/briar-core/src/org/briarproject/transport/TransportModule.java
index d5819fbfc..5cc81e458 100644
--- a/briar-core/src/org/briarproject/transport/TransportModule.java
+++ b/briar-core/src/org/briarproject/transport/TransportModule.java
@@ -37,7 +37,7 @@ public class TransportModule {
@Singleton
KeyManager getKeyManager(LifecycleManager lifecycleManager,
EventBus eventBus, KeyManagerImpl keyManager) {
- lifecycleManager.register(keyManager);
+ lifecycleManager.registerService(keyManager);
eventBus.addListener(keyManager);
return keyManager;
}
diff --git a/briar-tests/src/org/briarproject/TestLifecycleModule.java b/briar-tests/src/org/briarproject/TestLifecycleModule.java
index fbf07ca0d..04137713c 100644
--- a/briar-tests/src/org/briarproject/TestLifecycleModule.java
+++ b/briar-tests/src/org/briarproject/TestLifecycleModule.java
@@ -1,5 +1,6 @@
package org.briarproject;
+import org.briarproject.api.clients.Client;
import org.briarproject.api.lifecycle.IoExecutor;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.lifecycle.Service;
@@ -20,8 +21,14 @@ public class TestLifecycleModule {
@Provides
LifecycleManager provideLifecycleManager() {
return new LifecycleManager() {
+
@Override
- public void register(Service s) {
+ public void registerService(Service s) {
+
+ }
+
+ @Override
+ public void registerClient(Client c) {
}
@@ -60,6 +67,7 @@ public class TestLifecycleModule {
@Provides
ShutdownManager provideShutdownManager() {
return new ShutdownManager() {
+
@Override
public int addShutdownHook(Runnable hook) {
return 0;
@@ -75,8 +83,7 @@ public class TestLifecycleModule {
@Provides
@IoExecutor
@Singleton
- Executor provideExecutor() {
+ Executor provideIoExecutor() {
return Executors.newCachedThreadPool();
}
-
}