diff --git a/briar-android-tests/src/test/java/org/briarproject/BlogSharingIntegrationTestComponent.java b/briar-android-tests/src/test/java/org/briarproject/BlogSharingIntegrationTestComponent.java index e0a7ada60e1cfede6ca822e31135517d30531b04..5515094fb97cb88a6519fbe1757d864149c347b0 100644 --- a/briar-android-tests/src/test/java/org/briarproject/BlogSharingIntegrationTestComponent.java +++ b/briar-android-tests/src/test/java/org/briarproject/BlogSharingIntegrationTestComponent.java @@ -17,6 +17,7 @@ import org.briarproject.event.EventModule; import org.briarproject.forum.ForumModule; import org.briarproject.identity.IdentityModule; import org.briarproject.lifecycle.LifecycleModule; +import org.briarproject.messaging.MessagingModule; import org.briarproject.properties.PropertiesModule; import org.briarproject.sharing.SharingModule; import org.briarproject.sync.SyncModule; @@ -46,7 +47,8 @@ import dagger.Component; SharingModule.class, SyncModule.class, SystemModule.class, - TransportModule.class + TransportModule.class, + MessagingModule.class }) interface BlogSharingIntegrationTestComponent { diff --git a/briar-android-tests/src/test/java/org/briarproject/ForumManagerTestComponent.java b/briar-android-tests/src/test/java/org/briarproject/ForumManagerTestComponent.java index 74c771488f832a608ebf66ee610a0e5fd6e1ddc2..fee35a0088438d7d5d04547f210002e58c3de28f 100644 --- a/briar-android-tests/src/test/java/org/briarproject/ForumManagerTestComponent.java +++ b/briar-android-tests/src/test/java/org/briarproject/ForumManagerTestComponent.java @@ -17,6 +17,7 @@ import org.briarproject.event.EventModule; import org.briarproject.forum.ForumModule; import org.briarproject.identity.IdentityModule; import org.briarproject.lifecycle.LifecycleModule; +import org.briarproject.messaging.MessagingModule; import org.briarproject.properties.PropertiesModule; import org.briarproject.sharing.SharingModule; import org.briarproject.sync.SyncModule; @@ -46,7 +47,8 @@ import dagger.Component; SharingModule.class, SyncModule.class, SystemModule.class, - TransportModule.class + TransportModule.class, + MessagingModule.class }) interface ForumManagerTestComponent { diff --git a/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTestComponent.java b/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTestComponent.java index 10dacd7c8041ea2a6ccd03987ccaaf4ad59a2fad..88b058807ce19031ffa8f311ffb8c42c2cd55708 100644 --- a/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTestComponent.java +++ b/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTestComponent.java @@ -21,6 +21,7 @@ import org.briarproject.event.EventModule; import org.briarproject.forum.ForumModule; import org.briarproject.identity.IdentityModule; import org.briarproject.lifecycle.LifecycleModule; +import org.briarproject.messaging.MessagingModule; import org.briarproject.properties.PropertiesModule; import org.briarproject.sharing.SharingModule; import org.briarproject.sync.SyncModule; @@ -50,7 +51,8 @@ import dagger.Component; SharingModule.class, SyncModule.class, SystemModule.class, - TransportModule.class + TransportModule.class, + MessagingModule.class }) interface ForumSharingIntegrationTestComponent { diff --git a/briar-android-tests/src/test/java/org/briarproject/introduction/IntroductionIntegrationTestComponent.java b/briar-android-tests/src/test/java/org/briarproject/introduction/IntroductionIntegrationTestComponent.java index c1f7077a497fa2d7c51269cda0ec504e15a75ebe..617fa1cee530f83f0125018fdda60e0ac80c71fe 100644 --- a/briar-android-tests/src/test/java/org/briarproject/introduction/IntroductionIntegrationTestComponent.java +++ b/briar-android-tests/src/test/java/org/briarproject/introduction/IntroductionIntegrationTestComponent.java @@ -20,6 +20,7 @@ import org.briarproject.db.DatabaseModule; import org.briarproject.event.EventModule; import org.briarproject.identity.IdentityModule; import org.briarproject.lifecycle.LifecycleModule; +import org.briarproject.messaging.MessagingModule; import org.briarproject.properties.PropertiesModule; import org.briarproject.sync.SyncModule; import org.briarproject.system.SystemModule; @@ -46,7 +47,8 @@ import dagger.Component; SyncModule.class, SystemModule.class, DataModule.class, - PropertiesModule.class + PropertiesModule.class, + MessagingModule.class }) public interface IntroductionIntegrationTestComponent { diff --git a/briar-api/src/org/briarproject/api/messaging/ConversationManager.java b/briar-api/src/org/briarproject/api/messaging/ConversationManager.java new file mode 100644 index 0000000000000000000000000000000000000000..5695af95b22ce30dd96bb5ea9c71eb2013d3f865 --- /dev/null +++ b/briar-api/src/org/briarproject/api/messaging/ConversationManager.java @@ -0,0 +1,28 @@ +package org.briarproject.api.messaging; + +import org.briarproject.api.clients.MessageTracker.GroupCount; +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.db.DbException; +import org.briarproject.api.db.Transaction; +import org.briarproject.api.sync.GroupId; + +public interface ConversationManager { + + /** + * Clients that present messages in a private conversation need to + * register themselves here. + */ + void registerConversationClient(ConversationClient client); + + /** Get the main group ID that represents this conversation */ + GroupId getConversationId(ContactId contactId) throws DbException; + + /** Get the unified group count for all private conversation messages. */ + GroupCount getGroupCount(ContactId contactId) throws DbException; + + interface ConversationClient { + GroupCount getGroupCount(Transaction txn, ContactId contactId) + throws DbException; + } + +} diff --git a/briar-core/src/org/briarproject/clients/BdfIncomingMessageHook.java b/briar-core/src/org/briarproject/clients/BdfIncomingMessageHook.java index c81293ab04e0324de5f5443aa2d636f4ce616a70..73d57f11be798c5136b2413404e4602f9340dbec 100644 --- a/briar-core/src/org/briarproject/clients/BdfIncomingMessageHook.java +++ b/briar-core/src/org/briarproject/clients/BdfIncomingMessageHook.java @@ -103,7 +103,7 @@ public abstract class BdfIncomingMessageHook implements IncomingMessageHook, return count; } - private GroupCount getGroupCount(Transaction txn, GroupId g) + protected GroupCount getGroupCount(Transaction txn, GroupId g) throws DbException { GroupCount count; try { diff --git a/briar-core/src/org/briarproject/clients/ConversationClient.java b/briar-core/src/org/briarproject/clients/ConversationClient.java new file mode 100644 index 0000000000000000000000000000000000000000..ba906d084f6078021f7819332400a3ff780aadc5 --- /dev/null +++ b/briar-core/src/org/briarproject/clients/ConversationClient.java @@ -0,0 +1,34 @@ +package org.briarproject.clients; + +import org.briarproject.api.clients.ClientHelper; +import org.briarproject.api.contact.Contact; +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.data.MetadataParser; +import org.briarproject.api.db.DatabaseComponent; +import org.briarproject.api.db.DbException; +import org.briarproject.api.db.Transaction; +import org.briarproject.api.messaging.ConversationManager; +import org.briarproject.api.sync.Group; +import org.briarproject.api.sync.GroupId; + +public abstract class ConversationClient extends BdfIncomingMessageHook + implements ConversationManager.ConversationClient { + + protected ConversationClient(DatabaseComponent db, + ClientHelper clientHelper, MetadataParser metadataParser) { + super(db, clientHelper, metadataParser); + } + + // TODO overwrite super methods to store GroupCount data in a single group + + protected abstract Group getContactGroup(Contact contact); + + @Override + public GroupCount getGroupCount(Transaction txn, ContactId contactId) + throws DbException { + Contact contact = db.getContact(txn, contactId); + GroupId groupId = getContactGroup(contact).getId(); + return getGroupCount(txn, groupId); + } + +} diff --git a/briar-core/src/org/briarproject/introduction/IntroductionManagerImpl.java b/briar-core/src/org/briarproject/introduction/IntroductionManagerImpl.java index e44472f8c711ace3ab60dc7099c803c4d8d352f9..31e671ca578bf5ac04f587e28e1087205c7d3e9b 100644 --- a/briar-core/src/org/briarproject/introduction/IntroductionManagerImpl.java +++ b/briar-core/src/org/briarproject/introduction/IntroductionManagerImpl.java @@ -29,7 +29,7 @@ import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.Message; import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageStatus; -import org.briarproject.clients.BdfIncomingMessageHook; +import org.briarproject.clients.ConversationClient; import org.briarproject.util.StringUtils; import java.io.IOException; @@ -76,7 +76,7 @@ import static org.briarproject.api.introduction.IntroductionConstants.TYPE_REQUE import static org.briarproject.api.introduction.IntroductionConstants.TYPE_RESPONSE; import static org.briarproject.clients.BdfConstants.MSG_KEY_READ; -class IntroductionManagerImpl extends BdfIncomingMessageHook +class IntroductionManagerImpl extends ConversationClient implements IntroductionManager, Client, AddContactHook, RemoveContactHook { @@ -119,7 +119,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook public void addingContact(Transaction txn, Contact c) throws DbException { try { // Create an introduction group for sending introduction messages - Group g = introductionGroupFactory.createIntroductionGroup(c); + 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 @@ -196,7 +196,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook // remove the group (all messages will be removed with it) // this contact won't get our abort message, but the other will - db.removeGroup(txn, introductionGroupFactory.createIntroductionGroup(c)); + db.removeGroup(txn, getContactGroup(c)); } /** @@ -288,6 +288,11 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook return false; } + @Override + protected Group getContactGroup(Contact contact) { + return introductionGroupFactory.createIntroductionGroup(contact); + } + @Override public void makeIntroduction(Contact c1, Contact c2, String msg, final long timestamp) @@ -296,8 +301,8 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook Transaction txn = db.startTransaction(false); try { introducerManager.makeIntroduction(txn, c1, c2, msg, timestamp); - Group g1 = introductionGroupFactory.createIntroductionGroup(c1); - Group g2 = introductionGroupFactory.createIntroductionGroup(c2); + Group g1 = getContactGroup(c1); + Group g2 = getContactGroup(c2); trackMessage(txn, g1.getId(), timestamp, true); trackMessage(txn, g2.getId(), timestamp, true); txn.setComplete(); @@ -314,7 +319,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook Transaction txn = db.startTransaction(false); try { Contact c = db.getContact(txn, contactId); - Group g = introductionGroupFactory.createIntroductionGroup(c); + Group g = getContactGroup(c); BdfDictionary state = getSessionState(txn, g.getId(), sessionId.getBytes()); @@ -334,7 +339,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook Transaction txn = db.startTransaction(false); try { Contact c = db.getContact(txn, contactId); - Group g = introductionGroupFactory.createIntroductionGroup(c); + Group g = getContactGroup(c); BdfDictionary state = getSessionState(txn, g.getId(), sessionId.getBytes()); @@ -358,9 +363,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook Transaction txn = db.startTransaction(true); try { // get messages and their status - GroupId g = introductionGroupFactory - .createIntroductionGroup(db.getContact(txn, contactId)) - .getId(); + GroupId g = getContactGroup(db.getContact(txn, contactId)).getId(); metadata = clientHelper.getMessageMetadataAsDictionary(txn, g); statuses = db.getMessageStatus(txn, contactId, g); diff --git a/briar-core/src/org/briarproject/introduction/IntroductionModule.java b/briar-core/src/org/briarproject/introduction/IntroductionModule.java index 4ea0ac6c3b5a9251d6b41db231f01f02cc3409fe..989100ff8b2266f5435def18051b36bdb111dfdc 100644 --- a/briar-core/src/org/briarproject/introduction/IntroductionModule.java +++ b/briar-core/src/org/briarproject/introduction/IntroductionModule.java @@ -6,6 +6,7 @@ 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.messaging.ConversationManager; import org.briarproject.api.system.Clock; import javax.inject.Inject; @@ -47,6 +48,7 @@ public class IntroductionModule { LifecycleManager lifecycleManager, ContactManager contactManager, MessageQueueManager messageQueueManager, + ConversationManager conversationManager, IntroductionManagerImpl introductionManager) { lifecycleManager.registerClient(introductionManager); @@ -55,6 +57,7 @@ public class IntroductionModule { messageQueueManager.registerIncomingMessageHook( introductionManager.getClientId(), introductionManager); + conversationManager.registerConversationClient(introductionManager); return introductionManager; } diff --git a/briar-core/src/org/briarproject/messaging/ConversationManagerImpl.java b/briar-core/src/org/briarproject/messaging/ConversationManagerImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..877e51f8d3540b8c5616fa7fee3e22b09a89cb0c --- /dev/null +++ b/briar-core/src/org/briarproject/messaging/ConversationManagerImpl.java @@ -0,0 +1,76 @@ +package org.briarproject.messaging; + +import org.briarproject.api.clients.ContactGroupFactory; +import org.briarproject.api.clients.MessageTracker.GroupCount; +import org.briarproject.api.contact.Contact; +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.db.DatabaseComponent; +import org.briarproject.api.db.DbException; +import org.briarproject.api.db.Transaction; +import org.briarproject.api.messaging.ConversationManager; +import org.briarproject.api.sync.Group; +import org.briarproject.api.sync.GroupId; + +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; + +import javax.inject.Inject; + +class ConversationManagerImpl implements ConversationManager { + + private final DatabaseComponent db; + private final ContactGroupFactory contactGroupFactory; + private final Set<ConversationClient> clients; + + @Inject + ConversationManagerImpl(DatabaseComponent db, + ContactGroupFactory contactGroupFactory) { + this.db = db; + this.contactGroupFactory = contactGroupFactory; + clients = new CopyOnWriteArraySet<ConversationClient>(); + } + + @Override + public void registerConversationClient(ConversationClient client) { + clients.add(client); + } + + @Override + public GroupId getConversationId(ContactId contactId) throws DbException { + // TODO we should probably transition this to its own group + // and/or work with the ContactId in the UI instead + Contact contact; + Transaction txn = db.startTransaction(true); + try { + contact = db.getContact(txn, contactId); + txn.setComplete(); + } finally { + db.endTransaction(txn); + } + Group group = contactGroupFactory + .createContactGroup(MessagingManagerImpl.CLIENT_ID, contact); + return group.getId(); + } + + @Override + public GroupCount getGroupCount(ContactId contactId) + throws DbException { + + long msgCount = 0, unreadCount = 0, latestTime = 0; + Transaction txn = db.startTransaction(true); + try { + for (ConversationClient client : clients) { + GroupCount count = client.getGroupCount(txn, contactId); + msgCount += count.getMsgCount(); + unreadCount += count.getUnreadCount(); + if (count.getLatestMsgTime() > latestTime) + latestTime = count.getLatestMsgTime(); + } + txn.setComplete(); + } finally { + db.endTransaction(txn); + } + return new GroupCount(msgCount, unreadCount, latestTime); + } + +} diff --git a/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java b/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java index 9e2918d0fa8143ccd3d0c00407ca02596c446672..3bb3c743a9c0b452f0ee01273d3fac4b301bd961 100644 --- a/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java +++ b/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java @@ -24,7 +24,7 @@ import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.Message; import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageStatus; -import org.briarproject.clients.BdfIncomingMessageHook; +import org.briarproject.clients.ConversationClient; import org.briarproject.util.StringUtils; import java.util.ArrayList; @@ -35,7 +35,7 @@ import javax.inject.Inject; import static org.briarproject.clients.BdfConstants.MSG_KEY_READ; -class MessagingManagerImpl extends BdfIncomingMessageHook +class MessagingManagerImpl extends ConversationClient implements MessagingManager, Client, AddContactHook, RemoveContactHook { static final ClientId CLIENT_ID = new ClientId(StringUtils.fromHexString( @@ -77,7 +77,8 @@ class MessagingManagerImpl extends BdfIncomingMessageHook } } - private Group getContactGroup(Contact c) { + @Override + protected Group getContactGroup(Contact c) { return contactGroupFactory.createContactGroup(CLIENT_ID, c); } @@ -203,4 +204,14 @@ class MessagingManagerImpl extends BdfIncomingMessageHook } } + @Override + public GroupCount getGroupCount(Transaction txn, ContactId contactId) + throws DbException { + + Contact contact = db.getContact(txn, contactId); + GroupId groupId = getContactGroup(contact).getId(); + + return getGroupCount(txn, groupId); + } + } diff --git a/briar-core/src/org/briarproject/messaging/MessagingModule.java b/briar-core/src/org/briarproject/messaging/MessagingModule.java index d22782cf42b7f19d87c954721a3c0524759e160b..243042dbc49c857e88a3cc158110d9d8d19601cb 100644 --- a/briar-core/src/org/briarproject/messaging/MessagingModule.java +++ b/briar-core/src/org/briarproject/messaging/MessagingModule.java @@ -4,6 +4,7 @@ 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.ConversationManager; import org.briarproject.api.messaging.MessagingManager; import org.briarproject.api.messaging.PrivateMessageFactory; import org.briarproject.api.sync.ValidationManager; @@ -22,6 +23,7 @@ public class MessagingModule { public static class EagerSingletons { @Inject MessagingManager messagingManager; + @Inject ConversationManager conversationManager; @Inject PrivateMessageValidator privateMessageValidator; } @@ -46,12 +48,22 @@ public class MessagingModule { @Singleton MessagingManager getMessagingManager(LifecycleManager lifecycleManager, ContactManager contactManager, ValidationManager validationManager, + ConversationManager conversationManager, MessagingManagerImpl messagingManager) { lifecycleManager.registerClient(messagingManager); contactManager.registerAddContactHook(messagingManager); contactManager.registerRemoveContactHook(messagingManager); validationManager .registerIncomingMessageHook(CLIENT_ID, messagingManager); + conversationManager.registerConversationClient(messagingManager); return messagingManager; } + + @Provides + @Singleton + ConversationManager getConversationManager( + ConversationManagerImpl conversationManager) { + return conversationManager; + } + } diff --git a/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java b/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java index a8d6fde681741176f7c04d4ffdd0fd18aec3ce56..2e12a46a7b889753e1caeb4900da6a26e96025b1 100644 --- a/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java +++ b/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java @@ -4,8 +4,8 @@ import org.briarproject.api.Bytes; 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.ContactGroupFactory; +import org.briarproject.api.clients.MessageQueueManager; import org.briarproject.api.clients.SessionId; import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.ContactId; @@ -36,7 +36,7 @@ import org.briarproject.api.sync.Message; import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageStatus; import org.briarproject.api.system.Clock; -import org.briarproject.clients.BdfIncomingMessageHook; +import org.briarproject.clients.ConversationClient; import org.briarproject.util.StringUtils; import java.io.IOException; @@ -86,7 +86,7 @@ import static org.briarproject.clients.BdfConstants.MSG_KEY_READ; import static org.briarproject.sharing.InviteeSessionState.State.AWAIT_LOCAL_RESPONSE; abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS extends InviteeSessionState, SS extends SharerSessionState, IR extends InvitationReceivedEvent, IRR extends InvitationResponseReceivedEvent> - extends BdfIncomingMessageHook + extends ConversationClient implements SharingManager<S>, Client, AddContactHook, RemoveContactHook { @@ -565,6 +565,16 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS } } + @Override + public GroupCount getGroupCount(Transaction txn, ContactId contactId) + throws DbException { + + Contact contact = db.getContact(txn, contactId); + GroupId groupId = getContactGroup(contact).getId(); + + return getGroupCount(txn, groupId); + } + void removingShareable(Transaction txn, S f) throws DbException { try { for (Contact c : db.getContacts(txn)) { @@ -922,7 +932,8 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS .sendMessage(txn, group, m.getTime(), body, meta); } - private Group getContactGroup(Contact c) { + @Override + protected Group getContactGroup(Contact c) { return contactGroupFactory.createContactGroup(getClientId(), c); } diff --git a/briar-core/src/org/briarproject/sharing/SharingModule.java b/briar-core/src/org/briarproject/sharing/SharingModule.java index a098fa1e143a5843fe097e456c3b622836616800..da616a43d7b20c7f3e520a3e3c5c2e91ca218020 100644 --- a/briar-core/src/org/briarproject/sharing/SharingModule.java +++ b/briar-core/src/org/briarproject/sharing/SharingModule.java @@ -9,6 +9,7 @@ import org.briarproject.api.data.MetadataEncoder; import org.briarproject.api.forum.ForumManager; import org.briarproject.api.forum.ForumSharingManager; import org.briarproject.api.lifecycle.LifecycleManager; +import org.briarproject.api.messaging.ConversationManager; import org.briarproject.api.system.Clock; import javax.inject.Inject; @@ -52,6 +53,7 @@ public class SharingModule { LifecycleManager lifecycleManager, ContactManager contactManager, MessageQueueManager messageQueueManager, + ConversationManager conversationManager, BlogManager blogManager, BlogSharingManagerImpl blogSharingManager) { @@ -60,6 +62,7 @@ public class SharingModule { contactManager.registerRemoveContactHook(blogSharingManager); messageQueueManager.registerIncomingMessageHook( BlogSharingManagerImpl.CLIENT_ID, blogSharingManager); + conversationManager.registerConversationClient(blogSharingManager); blogManager.registerRemoveBlogHook(blogSharingManager); return blogSharingManager; @@ -86,6 +89,7 @@ public class SharingModule { LifecycleManager lifecycleManager, ContactManager contactManager, MessageQueueManager messageQueueManager, + ConversationManager conversationManager, ForumManager forumManager, ForumSharingManagerImpl forumSharingManager) { @@ -94,6 +98,7 @@ public class SharingModule { contactManager.registerRemoveContactHook(forumSharingManager); messageQueueManager.registerIncomingMessageHook( ForumSharingManagerImpl.CLIENT_ID, forumSharingManager); + conversationManager.registerConversationClient(forumSharingManager); forumManager.registerRemoveForumHook(forumSharingManager); return forumSharingManager;