added a cache to the IdentityManager, changed its signature, modified when and where the author is stored

made the author creation single-threaded again in the LifecycleManager, removed redundant code
This commit is contained in:
Ernir Erlingsson
2016-10-13 11:01:25 +02:00
parent 47d6fc526f
commit eaa393a7ed
45 changed files with 299 additions and 552 deletions

View File

@@ -12,7 +12,6 @@ import org.briarproject.api.blogs.BlogPostHeader;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.contact.ContactManager; import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.KeyPair;
import org.briarproject.api.crypto.SecretKey; import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.db.DbException; import org.briarproject.api.db.DbException;
import org.briarproject.api.event.Event; import org.briarproject.api.event.Event;
@@ -455,6 +454,7 @@ public class BlogManagerTest extends BriarIntegrationTest {
@Test @Test
public void testCommentOnOwnComment() throws Exception { public void testCommentOnOwnComment() throws Exception {
startLifecycles(); startLifecycles();
defaultInit(); defaultInit();
@@ -526,26 +526,15 @@ public class BlogManagerTest extends BriarIntegrationTest {
} }
private void defaultInit() throws DbException { private void defaultInit() throws DbException {
addDefaultIdentities(); getDefaultIdentities();
addDefaultContacts(); addDefaultContacts();
listenToEvents(); listenToEvents();
} }
private void addDefaultIdentities() throws DbException { private void getDefaultIdentities() throws DbException {
KeyPair keyPair0 = crypto.generateSignatureKeyPair(); author0 = identityManager0.getLocalAuthor();
byte[] publicKey0 = keyPair0.getPublic().getEncoded(); author1 = identityManager1.getLocalAuthor();
byte[] privateKey0 = keyPair0.getPrivate().getEncoded();
author0 = authorFactory
.createLocalAuthor(AUTHOR1, publicKey0, privateKey0);
identityManager0.addLocalAuthor(author0);
blog0 = blogFactory.createBlog(author0); blog0 = blogFactory.createBlog(author0);
KeyPair keyPair1 = crypto.generateSignatureKeyPair();
byte[] publicKey1 = keyPair1.getPublic().getEncoded();
byte[] privateKey1 = keyPair1.getPrivate().getEncoded();
author1 = authorFactory
.createLocalAuthor(AUTHOR2, publicKey1, privateKey1);
identityManager1.addLocalAuthor(author1);
blog1 = blogFactory.createBlog(author1); blog1 = blogFactory.createBlog(author1);
} }
@@ -603,8 +592,8 @@ public class BlogManagerTest extends BriarIntegrationTest {
// Start the lifecycle manager and wait for it to finish // Start the lifecycle manager and wait for it to finish
lifecycleManager0 = t0.getLifecycleManager(); lifecycleManager0 = t0.getLifecycleManager();
lifecycleManager1 = t1.getLifecycleManager(); lifecycleManager1 = t1.getLifecycleManager();
lifecycleManager0.startServices(); lifecycleManager0.startServices(AUTHOR1);
lifecycleManager1.startServices(); lifecycleManager1.startServices(AUTHOR2);
lifecycleManager0.waitForStartup(); lifecycleManager0.waitForStartup();
lifecycleManager1.waitForStartup(); lifecycleManager1.waitForStartup();
} }

View File

@@ -13,7 +13,6 @@ import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.contact.ContactManager; import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.KeyPair;
import org.briarproject.api.crypto.SecretKey; import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.db.DbException; import org.briarproject.api.db.DbException;
import org.briarproject.api.event.BlogInvitationReceivedEvent; import org.briarproject.api.event.BlogInvitationReceivedEvent;
@@ -617,9 +616,9 @@ public class BlogSharingIntegrationTest extends BriarIntegrationTest {
lifecycleManager0 = t0.getLifecycleManager(); lifecycleManager0 = t0.getLifecycleManager();
lifecycleManager1 = t1.getLifecycleManager(); lifecycleManager1 = t1.getLifecycleManager();
lifecycleManager2 = t2.getLifecycleManager(); lifecycleManager2 = t2.getLifecycleManager();
lifecycleManager0.startServices(); lifecycleManager0.startServices(SHARER);
lifecycleManager1.startServices(); lifecycleManager1.startServices(INVITEE);
lifecycleManager2.startServices(); lifecycleManager2.startServices(CONTACT2);
lifecycleManager0.waitForStartup(); lifecycleManager0.waitForStartup();
lifecycleManager1.waitForStartup(); lifecycleManager1.waitForStartup();
lifecycleManager2.waitForStartup(); lifecycleManager2.waitForStartup();
@@ -636,30 +635,16 @@ public class BlogSharingIntegrationTest extends BriarIntegrationTest {
} }
private void defaultInit(boolean accept) throws DbException { private void defaultInit(boolean accept) throws DbException {
addDefaultIdentities(); getDefaultIdentities();
addDefaultContacts(); addDefaultContacts();
getPersonalBlogOfSharer(); getPersonalBlogOfSharer();
listenToEvents(accept); listenToEvents(accept);
} }
private void addDefaultIdentities() throws DbException { private void getDefaultIdentities() throws DbException {
KeyPair keyPair = cryptoComponent.generateSignatureKeyPair(); author0 = identityManager0.getLocalAuthor();
author0 = authorFactory.createLocalAuthor(SHARER, author1 = identityManager1.getLocalAuthor();
keyPair.getPublic().getEncoded(), author2 = identityManager2.getLocalAuthor();
keyPair.getPrivate().getEncoded());
identityManager0.addLocalAuthor(author0);
keyPair = cryptoComponent.generateSignatureKeyPair();
author1 = authorFactory.createLocalAuthor(INVITEE,
keyPair.getPublic().getEncoded(),
keyPair.getPrivate().getEncoded());
identityManager1.addLocalAuthor(author1);
keyPair = cryptoComponent.generateSignatureKeyPair();
author2 = authorFactory.createLocalAuthor(CONTACT2,
keyPair.getPublic().getEncoded(),
keyPair.getPrivate().getEncoded());
identityManager2.addLocalAuthor(author2);
} }
private void addDefaultContacts() throws DbException { private void addDefaultContacts() throws DbException {

View File

@@ -140,7 +140,7 @@ public class ForumManagerTest extends BriarIntegrationTest {
@Test @Test
public void testForumPost() throws Exception { public void testForumPost() throws Exception {
startLifecycles(); startLifecycles();
addDefaultIdentities(); getDefaultIdentities();
Forum forum = forumManager0.addForum("TestForum"); Forum forum = forumManager0.addForum("TestForum");
assertEquals(1, forumManager0.getForums().size()); assertEquals(1, forumManager0.getForums().size());
final long ms1 = clock.currentTimeMillis() - 1000L; final long ms1 = clock.currentTimeMillis() - 1000L;
@@ -362,26 +362,15 @@ public class ForumManagerTest extends BriarIntegrationTest {
} }
private void defaultInit() throws DbException { private void defaultInit() throws DbException {
addDefaultIdentities(); getDefaultIdentities();
addDefaultContacts(); addDefaultContacts();
addForum(); addForum();
listenToEvents(); listenToEvents();
} }
private void addDefaultIdentities() throws DbException { private void getDefaultIdentities() throws DbException {
KeyPair keyPair0 = crypto.generateSignatureKeyPair(); author0 = identityManager0.getLocalAuthor();
byte[] publicKey0 = keyPair0.getPublic().getEncoded(); author1 = identityManager1.getLocalAuthor();
byte[] privateKey0 = keyPair0.getPrivate().getEncoded();
author0 = authorFactory
.createLocalAuthor(SHARER, publicKey0, privateKey0);
identityManager0.addLocalAuthor(author0);
KeyPair keyPair1 = crypto.generateSignatureKeyPair();
byte[] publicKey1 = keyPair1.getPublic().getEncoded();
byte[] privateKey1 = keyPair1.getPrivate().getEncoded();
author1 = authorFactory
.createLocalAuthor(INVITEE, publicKey1, privateKey1);
identityManager1.addLocalAuthor(author1);
} }
private void addDefaultContacts() throws DbException { private void addDefaultContacts() throws DbException {
@@ -442,8 +431,8 @@ public class ForumManagerTest extends BriarIntegrationTest {
// Start the lifecycle manager and wait for it to finish // Start the lifecycle manager and wait for it to finish
lifecycleManager0 = t0.getLifecycleManager(); lifecycleManager0 = t0.getLifecycleManager();
lifecycleManager1 = t1.getLifecycleManager(); lifecycleManager1 = t1.getLifecycleManager();
lifecycleManager0.startServices(); lifecycleManager0.startServices(SHARER);
lifecycleManager1.startServices(); lifecycleManager1.startServices(INVITEE);
lifecycleManager0.waitForStartup(); lifecycleManager0.waitForStartup();
lifecycleManager1.waitForStartup(); lifecycleManager1.waitForStartup();
} }

View File

@@ -10,7 +10,6 @@ import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.contact.ContactManager; import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.KeyPair;
import org.briarproject.api.crypto.SecretKey; import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.data.BdfList; import org.briarproject.api.data.BdfList;
import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DatabaseComponent;
@@ -729,7 +728,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
startLifecycles(); startLifecycles();
try { try {
// initialize // initialize
addDefaultIdentities(); getDefaultIdentities();
addDefaultContacts(); addDefaultContacts();
addForumForSharer(); addForumForSharer();
@@ -1017,9 +1016,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
lifecycleManager0 = t0.getLifecycleManager(); lifecycleManager0 = t0.getLifecycleManager();
lifecycleManager1 = t1.getLifecycleManager(); lifecycleManager1 = t1.getLifecycleManager();
lifecycleManager2 = t2.getLifecycleManager(); lifecycleManager2 = t2.getLifecycleManager();
lifecycleManager0.startServices(); lifecycleManager0.startServices(SHARER);
lifecycleManager1.startServices(); lifecycleManager1.startServices(INVITEE);
lifecycleManager2.startServices(); lifecycleManager2.startServices(SHARER2);
lifecycleManager0.waitForStartup(); lifecycleManager0.waitForStartup();
lifecycleManager1.waitForStartup(); lifecycleManager1.waitForStartup();
lifecycleManager2.waitForStartup(); lifecycleManager2.waitForStartup();
@@ -1036,30 +1035,16 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
} }
private void defaultInit(boolean accept) throws DbException { private void defaultInit(boolean accept) throws DbException {
addDefaultIdentities(); getDefaultIdentities();
addDefaultContacts(); addDefaultContacts();
addForumForSharer(); addForumForSharer();
listenToEvents(accept); listenToEvents(accept);
} }
private void addDefaultIdentities() throws DbException { private void getDefaultIdentities() throws DbException {
KeyPair keyPair = cryptoComponent.generateSignatureKeyPair(); author0 = identityManager0.getLocalAuthor();
author0 = authorFactory.createLocalAuthor(SHARER, author1 = identityManager1.getLocalAuthor();
keyPair.getPublic().getEncoded(), author2 = identityManager2.getLocalAuthor();
keyPair.getPrivate().getEncoded());
identityManager0.addLocalAuthor(author0);
keyPair = cryptoComponent.generateSignatureKeyPair();
author1 = authorFactory.createLocalAuthor(INVITEE,
keyPair.getPublic().getEncoded(),
keyPair.getPrivate().getEncoded());
identityManager1.addLocalAuthor(author1);
keyPair = cryptoComponent.generateSignatureKeyPair();
author2 = authorFactory.createLocalAuthor(SHARER2,
keyPair.getPublic().getEncoded(),
keyPair.getPrivate().getEncoded());
identityManager2.addLocalAuthor(author2);
} }
private void addDefaultContacts() throws DbException { private void addDefaultContacts() throws DbException {

View File

@@ -416,7 +416,7 @@ public class PrivateGroupManagerTest extends BriarIntegrationTest {
byte[] privateKey0 = keyPair0.getPrivate().getEncoded(); byte[] privateKey0 = keyPair0.getPrivate().getEncoded();
author0 = authorFactory author0 = authorFactory
.createLocalAuthor(AUTHOR1, publicKey0, privateKey0); .createLocalAuthor(AUTHOR1, publicKey0, privateKey0);
identityManager0.addLocalAuthor(author0); identityManager0.registerLocalAuthor(author0);
privateGroup0 = privateGroup0 =
privateGroupFactory.createPrivateGroup("Testgroup", author0); privateGroupFactory.createPrivateGroup("Testgroup", author0);
groupId0 = privateGroup0.getId(); groupId0 = privateGroup0.getId();
@@ -426,7 +426,7 @@ public class PrivateGroupManagerTest extends BriarIntegrationTest {
byte[] privateKey1 = keyPair1.getPrivate().getEncoded(); byte[] privateKey1 = keyPair1.getPrivate().getEncoded();
author1 = authorFactory author1 = authorFactory
.createLocalAuthor(AUTHOR2, publicKey1, privateKey1); .createLocalAuthor(AUTHOR2, publicKey1, privateKey1);
identityManager1.addLocalAuthor(author1); identityManager1.registerLocalAuthor(author1);
} }
private void addDefaultContacts() throws DbException { private void addDefaultContacts() throws DbException {
@@ -531,8 +531,8 @@ public class PrivateGroupManagerTest extends BriarIntegrationTest {
// Start the lifecycle manager and wait for it to finish // Start the lifecycle manager and wait for it to finish
lifecycleManager0 = t0.getLifecycleManager(); lifecycleManager0 = t0.getLifecycleManager();
lifecycleManager1 = t1.getLifecycleManager(); lifecycleManager1 = t1.getLifecycleManager();
lifecycleManager0.startServices(); lifecycleManager0.startServices(AUTHOR1);
lifecycleManager1.startServices(); lifecycleManager1.startServices(AUTHOR2);
lifecycleManager0.waitForStartup(); lifecycleManager0.waitForStartup();
lifecycleManager1.waitForStartup(); lifecycleManager1.waitForStartup();
} }

View File

@@ -43,6 +43,9 @@ import static org.junit.Assert.assertTrue;
public class SimplexMessagingIntegrationTest extends BriarTestCase { public class SimplexMessagingIntegrationTest extends BriarTestCase {
private final static String ALICE = "Alice";
private final static String BOB = "Bob";
private final File testDir = TestUtils.getTestDirectory(); private final File testDir = TestUtils.getTestDirectory();
private final File aliceDir = new File(testDir, "alice"); private final File aliceDir = new File(testDir, "alice");
private final File bobDir = new File(testDir, "bob"); private final File bobDir = new File(testDir, "bob");
@@ -69,6 +72,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
read(write()); read(write());
} }
private byte[] write() throws Exception { private byte[] write() throws Exception {
// Instantiate Alice's services // Instantiate Alice's services
LifecycleManager lifecycleManager = alice.getLifecycleManager(); LifecycleManager lifecycleManager = alice.getLifecycleManager();
@@ -83,17 +87,17 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
SyncSessionFactory syncSessionFactory = alice.getSyncSessionFactory(); SyncSessionFactory syncSessionFactory = alice.getSyncSessionFactory();
// Start the lifecycle manager // Start the lifecycle manager
lifecycleManager.startServices(); lifecycleManager.startServices(null);
lifecycleManager.waitForStartup(); lifecycleManager.waitForStartup();
// Add an identity for Alice // Add an identity for Alice
LocalAuthor aliceAuthor = new LocalAuthor(aliceId, "Alice", LocalAuthor aliceAuthor = new LocalAuthor(aliceId, "Alice",
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp); new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp);
identityManager.addLocalAuthor(aliceAuthor); identityManager.registerLocalAuthor(aliceAuthor);
// Add Bob as a contact // Add Bob as a contact
Author bobAuthor = new Author(bobId, "Bob", Author bobAuthor = new Author(bobId, BOB,
new byte[MAX_PUBLIC_KEY_LENGTH]); new byte[MAX_PUBLIC_KEY_LENGTH]);
ContactId contactId = contactManager.addContact(bobAuthor, aliceId, ContactId contactId = contactManager.addContact(bobAuthor,
master, timestamp, true, true, true); aliceAuthor.getId(), master, timestamp, true, true, true);
// Send Bob a message // Send Bob a message
GroupId groupId = messagingManager.getConversationId(contactId); GroupId groupId = messagingManager.getConversationId(contactId);
@@ -136,18 +140,17 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
bob.getMessagingManager(); bob.getMessagingManager();
// Start the lifecyle manager // Start the lifecyle manager
lifecycleManager.startServices(); lifecycleManager.startServices(null);
lifecycleManager.waitForStartup(); lifecycleManager.waitForStartup();
// Add an identity for Bob // Add an identity for Bob
LocalAuthor bobAuthor = new LocalAuthor(bobId, "Bob", LocalAuthor bobAuthor = new LocalAuthor(bobId, BOB,
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp); new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp);
identityManager.addLocalAuthor(bobAuthor); identityManager.registerLocalAuthor(bobAuthor);
// Add Alice as a contact // Add Alice as a contact
Author aliceAuthor = new Author(aliceId, "Alice", Author aliceAuthor = new Author(aliceId, ALICE,
new byte[MAX_PUBLIC_KEY_LENGTH]); new byte[MAX_PUBLIC_KEY_LENGTH]);
ContactId contactId = contactManager.addContact(aliceAuthor, bobId, ContactId contactId = contactManager.addContact(aliceAuthor,
master, timestamp, false, true, true); bobAuthor.getId(), master, timestamp, false, true, true);
// Set up an event listener // Set up an event listener
MessageListener listener = new MessageListener(); MessageListener listener = new MessageListener();
bob.getEventBus().addListener(listener); bob.getEventBus().addListener(listener);

View File

@@ -188,7 +188,7 @@ public class IntroductionIntegrationTest extends BriarIntegrationTest {
public void testIntroductionSession() throws Exception { public void testIntroductionSession() throws Exception {
startLifecycles(); startLifecycles();
try { try {
addDefaultIdentities(); getDefaultIdentities();
addDefaultContacts(); addDefaultContacts();
addListeners(true, true); addListeners(true, true);
addTransportProperties(); addTransportProperties();
@@ -282,7 +282,7 @@ public class IntroductionIntegrationTest extends BriarIntegrationTest {
public void testIntroductionSessionFirstDecline() throws Exception { public void testIntroductionSessionFirstDecline() throws Exception {
startLifecycles(); startLifecycles();
try { try {
addDefaultIdentities(); getDefaultIdentities();
addDefaultContacts(); addDefaultContacts();
addListeners(false, true); addListeners(false, true);
addTransportProperties(); addTransportProperties();
@@ -349,7 +349,7 @@ public class IntroductionIntegrationTest extends BriarIntegrationTest {
public void testIntroductionSessionSecondDecline() throws Exception { public void testIntroductionSessionSecondDecline() throws Exception {
startLifecycles(); startLifecycles();
try { try {
addDefaultIdentities(); getDefaultIdentities();
addDefaultContacts(); addDefaultContacts();
addListeners(true, false); addListeners(true, false);
addTransportProperties(); addTransportProperties();
@@ -411,7 +411,7 @@ public class IntroductionIntegrationTest extends BriarIntegrationTest {
public void testIntroductionSessionDelayedFirstDecline() throws Exception { public void testIntroductionSessionDelayedFirstDecline() throws Exception {
startLifecycles(); startLifecycles();
try { try {
addDefaultIdentities(); getDefaultIdentities();
addDefaultContacts(); addDefaultContacts();
addListeners(false, false); addListeners(false, false);
addTransportProperties(); addTransportProperties();
@@ -464,7 +464,7 @@ public class IntroductionIntegrationTest extends BriarIntegrationTest {
public void testResponseAndAckInOneSession() throws Exception { public void testResponseAndAckInOneSession() throws Exception {
startLifecycles(); startLifecycles();
addDefaultIdentities(); getDefaultIdentities();
addDefaultContacts(); addDefaultContacts();
addListeners(true, true); addListeners(true, true);
addTransportProperties(); addTransportProperties();
@@ -512,7 +512,7 @@ public class IntroductionIntegrationTest extends BriarIntegrationTest {
public void testIntroductionToSameContact() throws Exception { public void testIntroductionToSameContact() throws Exception {
startLifecycles(); startLifecycles();
try { try {
addDefaultIdentities(); getDefaultIdentities();
addDefaultContacts(); addDefaultContacts();
addListeners(true, false); addListeners(true, false);
addTransportProperties(); addTransportProperties();
@@ -541,19 +541,12 @@ public class IntroductionIntegrationTest extends BriarIntegrationTest {
public void testIntroductionToIdentitiesOfSameContact() throws Exception { public void testIntroductionToIdentitiesOfSameContact() throws Exception {
startLifecycles(); startLifecycles();
try { try {
// Add Identities // Get Identities
author0 = authorFactory.createLocalAuthor(INTRODUCER, getDefaultIdentities();
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
TestUtils.getRandomBytes(123));
identityManager0.addLocalAuthor(author0);
author1 = authorFactory.createLocalAuthor(INTRODUCEE1,
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
TestUtils.getRandomBytes(123));
identityManager1.addLocalAuthor(author1);
author2 = authorFactory.createLocalAuthor(INTRODUCEE2, author2 = authorFactory.createLocalAuthor(INTRODUCEE2,
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH), TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
TestUtils.getRandomBytes(123)); TestUtils.getRandomBytes(123));
identityManager1.addLocalAuthor(author2); identityManager1.registerLocalAuthor(author2);
// Add introducees' authors as contacts // Add introducees' authors as contacts
contactId1 = contactManager0.addContact(author1, contactId1 = contactManager0.addContact(author1,
@@ -651,7 +644,7 @@ public class IntroductionIntegrationTest extends BriarIntegrationTest {
public void testSessionIdReuse() throws Exception { public void testSessionIdReuse() throws Exception {
startLifecycles(); startLifecycles();
try { try {
addDefaultIdentities(); getDefaultIdentities();
addDefaultContacts(); addDefaultContacts();
addListeners(true, true); addListeners(true, true);
addTransportProperties(); addTransportProperties();
@@ -719,7 +712,7 @@ public class IntroductionIntegrationTest extends BriarIntegrationTest {
public void testIntroducerRemovedCleanup() throws Exception { public void testIntroducerRemovedCleanup() throws Exception {
startLifecycles(); startLifecycles();
try { try {
addDefaultIdentities(); getDefaultIdentities();
addDefaultContacts(); addDefaultContacts();
addListeners(true, true); addListeners(true, true);
addTransportProperties(); addTransportProperties();
@@ -776,7 +769,7 @@ public class IntroductionIntegrationTest extends BriarIntegrationTest {
public void testIntroduceesRemovedCleanup() throws Exception { public void testIntroduceesRemovedCleanup() throws Exception {
startLifecycles(); startLifecycles();
try { try {
addDefaultIdentities(); getDefaultIdentities();
addDefaultContacts(); addDefaultContacts();
addListeners(true, true); addListeners(true, true);
addTransportProperties(); addTransportProperties();
@@ -847,7 +840,7 @@ public class IntroductionIntegrationTest extends BriarIntegrationTest {
throws Exception { throws Exception {
startLifecycles(); startLifecycles();
try { try {
addDefaultIdentities(); getDefaultIdentities();
addDefaultContacts(); addDefaultContacts();
addListeners(true, true); addListeners(true, true);
addTransportProperties(); addTransportProperties();
@@ -1091,9 +1084,9 @@ public class IntroductionIntegrationTest extends BriarIntegrationTest {
lifecycleManager0 = t0.getLifecycleManager(); lifecycleManager0 = t0.getLifecycleManager();
lifecycleManager1 = t1.getLifecycleManager(); lifecycleManager1 = t1.getLifecycleManager();
lifecycleManager2 = t2.getLifecycleManager(); lifecycleManager2 = t2.getLifecycleManager();
lifecycleManager0.startServices(); lifecycleManager0.startServices(INTRODUCER);
lifecycleManager1.startServices(); lifecycleManager1.startServices(INTRODUCEE1);
lifecycleManager2.startServices(); lifecycleManager2.startServices(INTRODUCEE2);
lifecycleManager0.waitForStartup(); lifecycleManager0.waitForStartup();
lifecycleManager1.waitForStartup(); lifecycleManager1.waitForStartup();
lifecycleManager2.waitForStartup(); lifecycleManager2.waitForStartup();
@@ -1138,25 +1131,11 @@ public class IntroductionIntegrationTest extends BriarIntegrationTest {
t2.getEventBus().addListener(listener2); t2.getEventBus().addListener(listener2);
} }
private void addDefaultIdentities() throws DbException { private void getDefaultIdentities() throws DbException {
KeyPair keyPair0 = crypto.generateSignatureKeyPair(); author0 = identityManager0.getLocalAuthor();
byte[] publicKey0 = keyPair0.getPublic().getEncoded(); author1 = identityManager1.getLocalAuthor();
byte[] privateKey0 = keyPair0.getPrivate().getEncoded(); author2 = identityManager2.getLocalAuthor();
author0 = authorFactory
.createLocalAuthor(INTRODUCER, publicKey0, privateKey0);
identityManager0.addLocalAuthor(author0);
KeyPair keyPair1 = crypto.generateSignatureKeyPair();
byte[] publicKey1 = keyPair1.getPublic().getEncoded();
byte[] privateKey1 = keyPair1.getPrivate().getEncoded();
author1 = authorFactory
.createLocalAuthor(INTRODUCEE1, publicKey1, privateKey1);
identityManager1.addLocalAuthor(author1);
KeyPair keyPair2 = crypto.generateSignatureKeyPair();
byte[] publicKey2 = keyPair2.getPublic().getEncoded();
byte[] privateKey2 = keyPair2.getPrivate().getEncoded();
author2 = authorFactory
.createLocalAuthor(INTRODUCEE2, publicKey2, privateKey2);
identityManager2.addLocalAuthor(author2);
} }
private void addDefaultContacts() throws DbException { private void addDefaultContacts() throws DbException {

View File

@@ -77,6 +77,7 @@ public class AppModule {
return new DatabaseConfig() { return new DatabaseConfig() {
private volatile SecretKey key = null; private volatile SecretKey key = null;
private volatile String nickName;
@Override @Override
public boolean databaseExists() { public boolean databaseExists() {
@@ -95,6 +96,16 @@ public class AppModule {
this.key = key; this.key = key;
} }
@Override
public void setAuthorNick(String nickName) {
this.nickName = nickName;
}
@Override
public String getAuthorNick() {
return nickName;
}
@Override @Override
public SecretKey getEncryptionKey() { public SecretKey getEncryptionKey() {
return key; return key;

View File

@@ -22,8 +22,6 @@ import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
@SuppressLint("Registered") @SuppressLint("Registered")
public abstract class BriarActivity extends BaseActivity { public abstract class BriarActivity extends BaseActivity {
public static final String KEY_LOCAL_AUTHOR_HANDLE =
"briar.LOCAL_AUTHOR_HANDLE";
public static final String KEY_STARTUP_FAILED = "briar.STARTUP_FAILED"; public static final String KEY_STARTUP_FAILED = "briar.STARTUP_FAILED";
public static final String GROUP_ID = "briar.GROUP_ID"; public static final String GROUP_ID = "briar.GROUP_ID";
public static final String GROUP_NAME = "briar.GROUP_NAME"; public static final String GROUP_NAME = "briar.GROUP_NAME";

View File

@@ -45,11 +45,13 @@ public class BriarService extends Service {
private final AtomicBoolean created = new AtomicBoolean(false); private final AtomicBoolean created = new AtomicBoolean(false);
private final Binder binder = new BriarBinder(); private final Binder binder = new BriarBinder();
@Inject protected DatabaseConfig databaseConfig; @Inject
protected DatabaseConfig databaseConfig;
// Fields that are accessed from background threads must be volatile // Fields that are accessed from background threads must be volatile
@Inject protected volatile LifecycleManager lifecycleManager; @Inject
@Inject protected volatile AndroidExecutor androidExecutor; protected volatile LifecycleManager lifecycleManager;
@Inject
protected volatile AndroidExecutor androidExecutor;
private volatile boolean started = false; private volatile boolean started = false;
@Override @Override
@@ -91,7 +93,8 @@ public class BriarService extends Service {
new Thread() { new Thread() {
@Override @Override
public void run() { public void run() {
StartResult result = lifecycleManager.startServices(); StartResult result = lifecycleManager
.startServices(databaseConfig.getAuthorNick());
if (result == SUCCESS) { if (result == SUCCESS) {
started = true; started = true;
} else if (result == ALREADY_RUNNING) { } else if (result == ALREADY_RUNNING) {
@@ -169,24 +172,32 @@ public class BriarService extends Service {
// FIXME: Work out what to do about it // FIXME: Work out what to do about it
} }
/** Waits for all services to start before returning. */ /**
* Waits for all services to start before returning.
*/
public void waitForStartup() throws InterruptedException { public void waitForStartup() throws InterruptedException {
lifecycleManager.waitForStartup(); lifecycleManager.waitForStartup();
} }
/** Waits for all services to stop before returning. */ /**
* Waits for all services to stop before returning.
*/
public void waitForShutdown() throws InterruptedException { public void waitForShutdown() throws InterruptedException {
lifecycleManager.waitForShutdown(); lifecycleManager.waitForShutdown();
} }
/** Starts the shutdown process. */ /**
* Starts the shutdown process.
*/
public void shutdown() { public void shutdown() {
stopSelf(); // This will call onDestroy() stopSelf(); // This will call onDestroy()
} }
public class BriarBinder extends Binder { public class BriarBinder extends Binder {
/** Returns the bound service. */ /**
* Returns the bound service.
*/
public BriarService getService() { public BriarService getService() {
return BriarService.this; return BriarService.this;
} }
@@ -205,9 +216,12 @@ public class BriarService extends Service {
} }
@Override @Override
public void onServiceDisconnected(ComponentName name) {} public void onServiceDisconnected(ComponentName name) {
}
/** Waits for the service to connect and returns its binder. */ /**
* Waits for the service to connect and returns its binder.
*/
public IBinder waitForBinder() throws InterruptedException { public IBinder waitForBinder() throws InterruptedException {
binderLatch.await(); binderLatch.await();
return binder; return binder;

View File

@@ -25,12 +25,10 @@ import org.briarproject.android.blogs.FeedFragment;
import org.briarproject.android.contact.ContactListFragment; import org.briarproject.android.contact.ContactListFragment;
import org.briarproject.android.controller.NavDrawerController; import org.briarproject.android.controller.NavDrawerController;
import org.briarproject.android.controller.TransportStateListener; import org.briarproject.android.controller.TransportStateListener;
import org.briarproject.android.controller.handler.UiResultHandler;
import org.briarproject.android.forum.ForumListFragment; import org.briarproject.android.forum.ForumListFragment;
import org.briarproject.android.fragment.BaseFragment.BaseFragmentListener; import org.briarproject.android.fragment.BaseFragment.BaseFragmentListener;
import org.briarproject.android.privategroup.list.GroupListFragment; import org.briarproject.android.privategroup.list.GroupListFragment;
import org.briarproject.api.TransportId; import org.briarproject.api.TransportId;
import org.briarproject.api.identity.LocalAuthor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -72,7 +70,6 @@ public class NavDrawerActivity extends BriarFragmentActivity implements
protected void onNewIntent(Intent intent) { protected void onNewIntent(Intent intent) {
super.onNewIntent(intent); super.onNewIntent(intent);
exitIfStartupFailed(intent); exitIfStartupFailed(intent);
checkAuthorHandle(intent);
// FIXME why was the stack cleared here? // FIXME why was the stack cleared here?
// This prevents state from being restored properly // This prevents state from being restored properly
// clearBackStack(); // clearBackStack();
@@ -115,7 +112,6 @@ public class NavDrawerActivity extends BriarFragmentActivity implements
R.string.nav_drawer_close_description); R.string.nav_drawer_close_description);
drawerLayout.addDrawerListener(drawerToggle); drawerLayout.addDrawerListener(drawerToggle);
navigation.setNavigationItemSelectedListener(this); navigation.setNavigationItemSelectedListener(this);
checkAuthorHandle(getIntent());
initializeTransports(getLayoutInflater()); initializeTransports(getLayoutInflater());
transportsView.setAdapter(transportsAdapter); transportsView.setAdapter(transportsAdapter);
@@ -146,18 +142,6 @@ public class NavDrawerActivity extends BriarFragmentActivity implements
updateTransports(); updateTransports();
} }
private void checkAuthorHandle(Intent intent) {
long handle = intent.getLongExtra(KEY_LOCAL_AUTHOR_HANDLE, -1);
if (handle != -1) {
LocalAuthor a = controller.removeAuthorHandle(handle);
// The activity was launched from the setup wizard
if (a != null) {
showLoadingScreen(true, R.string.progress_title_please_wait);
storeLocalAuthor(a);
}
}
}
private void exitIfStartupFailed(Intent intent) { private void exitIfStartupFailed(Intent intent) {
if (intent.getBooleanExtra(KEY_STARTUP_FAILED, false)) { if (intent.getBooleanExtra(KEY_STARTUP_FAILED, false)) {
finish(); finish();
@@ -166,15 +150,6 @@ public class NavDrawerActivity extends BriarFragmentActivity implements
} }
} }
private void storeLocalAuthor(LocalAuthor a) {
controller.storeLocalAuthor(a, new UiResultHandler<Void>(this) {
@Override
public void onResultUi(Void result) {
hideLoadingScreen();
}
});
}
private void loadFragment(int fragmentId) { private void loadFragment(int fragmentId) {
// TODO re-use fragments from the manager when possible // TODO re-use fragments from the manager when possible
switch (fragmentId) { switch (fragmentId) {

View File

@@ -2,7 +2,6 @@ package org.briarproject.android;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull;
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;
@@ -135,18 +134,18 @@ public class SetupActivity extends BaseActivity implements OnClickListener,
progress.setVisibility(VISIBLE); progress.setVisibility(VISIBLE);
String nickname = nicknameEntry.getText().toString(); String nickname = nicknameEntry.getText().toString();
String password = passwordEntry.getText().toString(); String password = passwordEntry.getText().toString();
setupController.createIdentity(nickname, password,
new UiResultHandler<Long>(this) { setupController.storeAuthorInfo(password, nickname,
new UiResultHandler<Void>(this) {
@Override @Override
public void onResultUi(@NonNull Long result) { public void onResultUi(Void result) {
showMain(result); showMain();
} }
}); });
} }
private void showMain(final long handle) { private void showMain() {
Intent i = new Intent(this, NavDrawerActivity.class); Intent i = new Intent(this, NavDrawerActivity.class);
i.putExtra(BriarActivity.KEY_LOCAL_AUTHOR_HANDLE, handle);
i.setFlags(FLAG_ACTIVITY_NEW_TASK); i.setFlags(FLAG_ACTIVITY_NEW_TASK);
startActivity(i); startActivity(i);
finish(); finish();

View File

@@ -27,7 +27,6 @@ import org.briarproject.api.sync.GroupId;
import org.briarproject.util.StringUtils; import org.briarproject.util.StringUtils;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.util.Collection;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.inject.Inject; import javax.inject.Inject;
@@ -147,9 +146,7 @@ public class WriteBlogPostActivity extends BriarActivity
public void run() { public void run() {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
try { try {
Collection<LocalAuthor> authors = LocalAuthor author = identityManager.getLocalAuthor();
identityManager.getLocalAuthors();
LocalAuthor author = authors.iterator().next();
BlogPost p = blogPostFactory BlogPost p = blogPostFactory
.createBlogPost(groupId, now, null, author, body); .createBlogPost(groupId, now, null, author, body);
blogManager.addLocalPost(p); blogManager.addLocalPost(p);

View File

@@ -6,7 +6,7 @@ public interface ConfigController {
String getEncryptedDatabaseKey(); String getEncryptedDatabaseKey();
void setEncryptedDatabaseKey(String hex); void storeEncryptedDatabaseKey(String hex);
void deleteAccount(Context ctx); void deleteAccount(Context ctx);

View File

@@ -29,7 +29,7 @@ public class ConfigControllerImpl implements ConfigController {
} }
@Override @Override
public void setEncryptedDatabaseKey(String hex) { public void storeEncryptedDatabaseKey(String hex) {
SharedPreferences.Editor editor = briarPrefs.edit(); SharedPreferences.Editor editor = briarPrefs.edit();
editor.putString(PREF_DB_KEY, hex); editor.putString(PREF_DB_KEY, hex);
editor.apply(); editor.apply();

View File

@@ -1,15 +1,9 @@
package org.briarproject.android.controller; package org.briarproject.android.controller;
import org.briarproject.android.controller.handler.ResultHandler;
import org.briarproject.api.TransportId; import org.briarproject.api.TransportId;
import org.briarproject.api.identity.LocalAuthor;
public interface NavDrawerController extends ActivityLifecycleController { public interface NavDrawerController extends ActivityLifecycleController {
boolean isTransportRunning(TransportId transportId); boolean isTransportRunning(TransportId transportId);
void storeLocalAuthor(LocalAuthor author,
ResultHandler<Void> resultHandler);
LocalAuthor removeAuthorHandle(long handle);
} }

View File

@@ -2,18 +2,14 @@ package org.briarproject.android.controller;
import android.app.Activity; import android.app.Activity;
import org.briarproject.android.api.ReferenceManager;
import org.briarproject.android.controller.handler.ResultHandler;
import org.briarproject.api.TransportId; import org.briarproject.api.TransportId;
import org.briarproject.api.db.DatabaseExecutor; import org.briarproject.api.db.DatabaseExecutor;
import org.briarproject.api.db.DbException;
import org.briarproject.api.event.Event; import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventBus; import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.EventListener; import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.TransportDisabledEvent; import org.briarproject.api.event.TransportDisabledEvent;
import org.briarproject.api.event.TransportEnabledEvent; import org.briarproject.api.event.TransportEnabledEvent;
import org.briarproject.api.identity.IdentityManager; import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.lifecycle.LifecycleManager; import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.plugins.Plugin; import org.briarproject.api.plugins.Plugin;
import org.briarproject.api.plugins.PluginManager; import org.briarproject.api.plugins.PluginManager;
@@ -24,7 +20,6 @@ import java.util.logging.Logger;
import javax.inject.Inject; import javax.inject.Inject;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
public class NavDrawerControllerImpl extends DbControllerImpl public class NavDrawerControllerImpl extends DbControllerImpl
implements NavDrawerController, EventListener { implements NavDrawerController, EventListener {
@@ -32,7 +27,6 @@ public class NavDrawerControllerImpl extends DbControllerImpl
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(NavDrawerControllerImpl.class.getName()); Logger.getLogger(NavDrawerControllerImpl.class.getName());
private final ReferenceManager referenceManager;
private final PluginManager pluginManager; private final PluginManager pluginManager;
private final EventBus eventBus; private final EventBus eventBus;
private final IdentityManager identityManager; private final IdentityManager identityManager;
@@ -42,10 +36,9 @@ public class NavDrawerControllerImpl extends DbControllerImpl
@Inject @Inject
NavDrawerControllerImpl(@DatabaseExecutor Executor dbExecutor, NavDrawerControllerImpl(@DatabaseExecutor Executor dbExecutor,
LifecycleManager lifecycleManager, LifecycleManager lifecycleManager,
ReferenceManager referenceManager, PluginManager pluginManager, PluginManager pluginManager, EventBus eventBus,
EventBus eventBus, IdentityManager identityManager) { IdentityManager identityManager) {
super(dbExecutor, lifecycleManager); super(dbExecutor, lifecycleManager);
this.referenceManager = referenceManager;
this.pluginManager = pluginManager; this.pluginManager = pluginManager;
this.eventBus = eventBus; this.eventBus = eventBus;
this.identityManager = identityManager; this.identityManager = identityManager;
@@ -101,33 +94,8 @@ public class NavDrawerControllerImpl extends DbControllerImpl
@Override @Override
public boolean isTransportRunning(TransportId transportId) { public boolean isTransportRunning(TransportId transportId) {
Plugin plugin = pluginManager.getPlugin(transportId); Plugin plugin = pluginManager.getPlugin(transportId);
return plugin != null && plugin.isRunning(); return plugin != null && plugin.isRunning();
} }
@Override
public void storeLocalAuthor(final LocalAuthor author,
final ResultHandler<Void> resultHandler) {
runOnDbThread(new Runnable() {
@Override
public void run() {
try {
long now = System.currentTimeMillis();
identityManager.addLocalAuthor(author);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Storing author took " + duration + " ms");
resultHandler.onResult(null);
} catch (final DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
}
});
}
@Override
public LocalAuthor removeAuthorHandle(long handle) {
return referenceManager.removeReference(handle, LocalAuthor.class);
}
} }

View File

@@ -65,7 +65,7 @@ public class PasswordControllerImpl extends ConfigControllerImpl
} else { } else {
String hex = String hex =
encryptDatabaseKey(new SecretKey(key), newPassword); encryptDatabaseKey(new SecretKey(key), newPassword);
setEncryptedDatabaseKey(hex); storeEncryptedDatabaseKey(hex);
resultHandler.onResult(true); resultHandler.onResult(true);
} }
} }

View File

@@ -6,6 +6,7 @@ public interface SetupController {
float estimatePasswordStrength(String password); float estimatePasswordStrength(String password);
void createIdentity(String nickname, String password, void storeAuthorInfo(String password, String nickName,
ResultHandler<Long> resultHandler); ResultHandler<Void> resultHandler);
} }

View File

@@ -2,24 +2,18 @@ package org.briarproject.android.controller;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import org.briarproject.android.api.ReferenceManager;
import org.briarproject.android.controller.handler.ResultHandler; import org.briarproject.android.controller.handler.ResultHandler;
import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.CryptoExecutor; import org.briarproject.api.crypto.CryptoExecutor;
import org.briarproject.api.crypto.KeyPair;
import org.briarproject.api.crypto.PasswordStrengthEstimator; import org.briarproject.api.crypto.PasswordStrengthEstimator;
import org.briarproject.api.crypto.SecretKey; import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.db.DatabaseConfig; import org.briarproject.api.db.DatabaseConfig;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.identity.LocalAuthor;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.inject.Inject; import javax.inject.Inject;
import static java.util.logging.Level.INFO;
public class SetupControllerImpl extends PasswordControllerImpl public class SetupControllerImpl extends PasswordControllerImpl
implements SetupController { implements SetupController {
@@ -27,33 +21,14 @@ public class SetupControllerImpl extends PasswordControllerImpl
Logger.getLogger(SetupControllerImpl.class.getName()); Logger.getLogger(SetupControllerImpl.class.getName());
private final PasswordStrengthEstimator strengthEstimator; private final PasswordStrengthEstimator strengthEstimator;
private final AuthorFactory authorFactory;
private final ReferenceManager referenceManager;
@Inject @Inject
SetupControllerImpl(SharedPreferences briarPrefs, SetupControllerImpl(SharedPreferences briarPrefs,
DatabaseConfig databaseConfig, DatabaseConfig databaseConfig,
@CryptoExecutor Executor cryptoExecutor, CryptoComponent crypto, @CryptoExecutor Executor cryptoExecutor, CryptoComponent crypto,
PasswordStrengthEstimator strengthEstimator, PasswordStrengthEstimator strengthEstimator) {
AuthorFactory authorFactory, ReferenceManager referenceManager) {
super(briarPrefs, databaseConfig, cryptoExecutor, crypto); super(briarPrefs, databaseConfig, cryptoExecutor, crypto);
this.strengthEstimator = strengthEstimator; this.strengthEstimator = strengthEstimator;
this.authorFactory = authorFactory;
this.referenceManager = referenceManager;
}
private LocalAuthor createLocalAuthor(String nickname) {
long now = System.currentTimeMillis();
KeyPair keyPair = crypto.generateSignatureKeyPair();
byte[] publicKey = keyPair.getPublic().getEncoded();
byte[] privateKey = keyPair.getPrivate().getEncoded();
LocalAuthor localAuthor = authorFactory.createLocalAuthor(nickname,
publicKey, privateKey);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Identity creation took " + duration + " ms");
return localAuthor;
} }
@Override @Override
@@ -62,20 +37,19 @@ public class SetupControllerImpl extends PasswordControllerImpl
} }
@Override @Override
public void createIdentity(final String nickname, final String password, public void storeAuthorInfo(final String password, final String nickName,
final ResultHandler<Long> resultHandler) { final ResultHandler<Void> resultHandler) {
cryptoExecutor.execute(new Runnable() { cryptoExecutor.execute(new Runnable() {
@Override @Override
public void run() { public void run() {
SecretKey key = crypto.generateSecretKey(); SecretKey key = crypto.generateSecretKey();
databaseConfig.setEncryptionKey(key); databaseConfig.setEncryptionKey(key);
String hex = encryptDatabaseKey(key, password); String hex = encryptDatabaseKey(key, password);
setEncryptedDatabaseKey(hex); storeEncryptedDatabaseKey(hex);
LocalAuthor localAuthor = createLocalAuthor(nickname); databaseConfig.setAuthorNick(nickName);
long handle = referenceManager.putReference(localAuthor, resultHandler.onResult(null);
LocalAuthor.class);
resultHandler.onResult(handle);
} }
}); });
} }
} }

View File

@@ -254,8 +254,7 @@ public class AddContactActivity extends BriarActivity
// change UI to show a progress indicator // change UI to show a progress indicator
setView(new InvitationCodeView(this, true)); setView(new InvitationCodeView(this, true));
task = invitationTaskFactory.createTask(localAuthorId, task = invitationTaskFactory.createTask(localInvitationCode, code);
localInvitationCode, code);
taskHandle = referenceManager.putReference(task, InvitationTask.class); taskHandle = referenceManager.putReference(task, InvitationTask.class);
task.addListener(AddContactActivity.this); task.addListener(AddContactActivity.this);
// Add a second listener so we can remove the first in onDestroy(), // Add a second listener so we can remove the first in onDestroy(),

View File

@@ -114,7 +114,6 @@ public class ChangePasswordActivityTest {
@Test @Test
public void testChangePasswordUI() { public void testChangePasswordUI() {
PasswordController mockedPasswordController = this.passwordController; PasswordController mockedPasswordController = this.passwordController;
SetupController mockedSetupController = this.setupController; SetupController mockedSetupController = this.setupController;
changePasswordActivity.setPasswordController(mockedPasswordController); changePasswordActivity.setPasswordController(mockedPasswordController);
@@ -135,7 +134,7 @@ public class ChangePasswordActivityTest {
verify(mockedPasswordController, times(1)) verify(mockedPasswordController, times(1))
.changePassword(eq(curPass), eq(safePass), .changePassword(eq(curPass), eq(safePass),
resultCaptor.capture()); resultCaptor.capture());
// execute the callback // execute the callbacks
resultCaptor.getValue().onResult(true); resultCaptor.getValue().onResult(true);
assertEquals(changePasswordActivity.isFinishing(), true); assertEquals(changePasswordActivity.isFinishing(), true);
} }
@@ -147,12 +146,14 @@ public class ChangePasswordActivityTest {
SetupController setupController = SetupController setupController =
changePasswordActivity.getSetupController(); changePasswordActivity.getSetupController();
// mock a resulthandler // mock a resulthandler
ResultHandler<Long> resultHandler = ResultHandler<Void> resultHandler =
(ResultHandler<Long>) mock(ResultHandler.class); (ResultHandler<Void>) mock(ResultHandler.class);
setupController.createIdentity("nick", "some.old.pass", resultHandler); setupController
.storeAuthorInfo("nick", "some.old.pass", resultHandler);
// blocking verification call with timeout that waits until the mocked // blocking verification call with timeout that waits until the mocked
// result gets called with handle 0L, the expected value // result gets called with handle 0L, the expected value
verify(resultHandler, timeout(2000).times(1)).onResult(0L); verify(resultHandler, timeout(2000).times(1))
.onResult(null);
SharedPreferences prefs = SharedPreferences prefs =
changePasswordActivity changePasswordActivity
.getSharedPreferences("db", Context.MODE_PRIVATE); .getSharedPreferences("db", Context.MODE_PRIVATE);

View File

@@ -63,7 +63,7 @@ public class SetupActivityTest {
@Mock @Mock
private SetupController setupController; private SetupController setupController;
@Captor @Captor
private ArgumentCaptor<ResultHandler<Long>> resultCaptor; private ArgumentCaptor<ResultHandler<Void>> authorCaptor;
@Before @Before
public void setUp() { public void setUp() {
@@ -114,7 +114,6 @@ public class SetupActivityTest {
@Test @Test
public void testCreateAccountUI() { public void testCreateAccountUI() {
SetupController mockedController = this.setupController; SetupController mockedController = this.setupController;
setupActivity.setController(mockedController); setupActivity.setController(mockedController);
// Mock strong password strength answer // Mock strong password strength answer
@@ -131,9 +130,10 @@ public class SetupActivityTest {
// Verify that the controller's method was called with the correct // Verify that the controller's method was called with the correct
// params and get the callback // params and get the callback
verify(mockedController, times(1)) verify(mockedController, times(1))
.createIdentity(eq(nick), eq(safePass), resultCaptor.capture()); .storeAuthorInfo(eq(safePass), eq(nick),
authorCaptor.capture());
authorCaptor.getValue().onResult(null);
// execute the callback // execute the callback
resultCaptor.getValue().onResult(1L);
assertEquals(setupActivity.isFinishing(), true); assertEquals(setupActivity.isFinishing(), true);
// Confirm that the correct Activity has been started // Confirm that the correct Activity has been started
ShadowActivity shadowActivity = shadowOf(setupActivity); ShadowActivity shadowActivity = shadowOf(setupActivity);
@@ -158,13 +158,13 @@ public class SetupActivityTest {
public void testAccountCreation() { public void testAccountCreation() {
SetupController controller = setupActivity.getController(); SetupController controller = setupActivity.getController();
// mock a resulthandler // mock a resulthandler
ResultHandler<Long> resultHandler = ResultHandler<Void> resultHandler =
(ResultHandler<Long>) mock(ResultHandler.class); (ResultHandler<Void>) mock(ResultHandler.class);
controller controller
.createIdentity("nick", "some.strong.pass", resultHandler); .storeAuthorInfo("nick", "some.strong.pass", resultHandler);
// blocking verification call with timeout that waits until the mocked // blocking verification call with timeout that waits until the mocked
// result gets called with handle 0L, the expected value // result gets called with handle 0L, the expected value
verify(resultHandler, timeout(2000).times(1)).onResult(0L); verify(resultHandler, timeout(2000).times(1)).onResult(null);
SharedPreferences prefs = SharedPreferences prefs =
setupActivity.getSharedPreferences("db", Context.MODE_PRIVATE); setupActivity.getSharedPreferences("db", Context.MODE_PRIVATE);
// Confirm database key // Confirm database key

View File

@@ -1,9 +1,9 @@
package org.briarproject.api.db; package org.briarproject.api.db;
import java.io.File;
import org.briarproject.api.crypto.SecretKey; import org.briarproject.api.crypto.SecretKey;
import java.io.File;
public interface DatabaseConfig { public interface DatabaseConfig {
boolean databaseExists(); boolean databaseExists();
@@ -14,5 +14,9 @@ public interface DatabaseConfig {
SecretKey getEncryptionKey(); SecretKey getEncryptionKey();
void setAuthorNick(String nickName);
String getAuthorNick();
long getMaxSize(); long getMaxSize();
} }

View File

@@ -4,49 +4,23 @@ import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction; import org.briarproject.api.db.Transaction;
import org.briarproject.api.identity.Author.Status; import org.briarproject.api.identity.Author.Status;
import java.util.Collection;
public interface IdentityManager { public interface IdentityManager {
/** Registers a hook to be called whenever a local pseudonym is added. */ /** Stores the local pseudonym. */
void registerAddIdentityHook(AddIdentityHook hook); void registerLocalAuthor(LocalAuthor a) throws DbException;
/** Registers a hook to be called whenever a local pseudonym is removed. */ /** Returns the cached main local identity, non-blocking, or loads it from
void registerRemoveIdentityHook(RemoveIdentityHook hook); * the db, blocking*/
/** Stores a local pseudonym. */
void addLocalAuthor(LocalAuthor a) throws DbException;
/** Returns the local pseudonym with the given ID. */
LocalAuthor getLocalAuthor(AuthorId a) throws DbException;
/** Returns the local pseudonym with the given ID. */
LocalAuthor getLocalAuthor(Transaction txn, AuthorId a) throws DbException;
/** Returns the main local identity. */
LocalAuthor getLocalAuthor() throws DbException; LocalAuthor getLocalAuthor() throws DbException;
/** Returns the main local identity within the given Transaction. */ /** Returns the cached main local identity, non-blocking, or loads it from
* the db, blocking, within the given Transaction. */
LocalAuthor getLocalAuthor(Transaction txn) throws DbException; LocalAuthor getLocalAuthor(Transaction txn) throws DbException;
/** Returns all local pseudonyms. */
Collection<LocalAuthor> getLocalAuthors() throws DbException;
/** Removes a local pseudonym and all associated state. */
void removeLocalAuthor(AuthorId a) throws DbException;
/** Returns the trust-level status of the author */ /** Returns the trust-level status of the author */
Status getAuthorStatus(AuthorId a) throws DbException; Status getAuthorStatus(AuthorId a) throws DbException;
/** Returns the trust-level status of the author */ /** Returns the trust-level status of the author */
Status getAuthorStatus(Transaction txn, AuthorId a) throws DbException; Status getAuthorStatus(Transaction txn, AuthorId a) throws DbException;
interface AddIdentityHook {
void addingIdentity(Transaction txn, LocalAuthor a) throws DbException;
}
interface RemoveIdentityHook {
void removingIdentity(Transaction txn, LocalAuthor a)
throws DbException;
}
} }

View File

@@ -1,11 +1,8 @@
package org.briarproject.api.invitation; package org.briarproject.api.invitation;
import org.briarproject.api.identity.AuthorId;
/** Creates tasks for exchanging invitations with remote peers. */ /** Creates tasks for exchanging invitations with remote peers. */
public interface InvitationTaskFactory { public interface InvitationTaskFactory {
/** Creates a task using the given pseudonym and invitation codes. */ /** Creates a task using the local author and invitation codes. */
InvitationTask createTask(AuthorId localAuthorId, int localCode, InvitationTask createTask(int localCode, int remoteCode);
int remoteCode);
} }

View File

@@ -4,6 +4,8 @@ import org.briarproject.api.clients.Client;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import javax.annotation.Nullable;
/** /**
* Manages the lifecycle of the app, starting {@link * Manages the lifecycle of the app, starting {@link
* org.briarproject.api.clients.Client Clients}, starting and stopping {@link * org.briarproject.api.clients.Client Clients}, starting and stopping {@link
@@ -14,7 +16,7 @@ import java.util.concurrent.ExecutorService;
public interface LifecycleManager { public interface LifecycleManager {
/** /**
* The result of calling {@link LifecycleManager#startServices()}. * The result of calling {@link LifecycleManager#startServices(String)}.
*/ */
enum StartResult { enum StartResult {
ALREADY_RUNNING, DB_ERROR, SERVICE_ERROR, SUCCESS ALREADY_RUNNING, DB_ERROR, SERVICE_ERROR, SUCCESS
@@ -39,11 +41,11 @@ public interface LifecycleManager {
/** /**
* Opens the {@link org.briarproject.api.db.DatabaseComponent * Opens the {@link org.briarproject.api.db.DatabaseComponent
* DatabaseComponent} and starts any registered {@link * DatabaseComponent}, creates a local author with the provided nick, and
* org.briarproject.api.clients.Client Clients} and {@link Service * starts any registered {@link org.briarproject.api.clients.Client Clients}
* Services}. * and {@link Service Services}.
*/ */
StartResult startServices(); StartResult startServices(@Nullable String authorNick);
/** /**
* Stops any registered {@link Service Services}, shuts down any * Stops any registered {@link Service Services}, shuts down any

View File

@@ -26,8 +26,6 @@ import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.Author.Status; import org.briarproject.api.identity.Author.Status;
import org.briarproject.api.identity.AuthorId; import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.IdentityManager; import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.IdentityManager.AddIdentityHook;
import org.briarproject.api.identity.IdentityManager.RemoveIdentityHook;
import org.briarproject.api.identity.LocalAuthor; import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.sync.ClientId; import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group; import org.briarproject.api.sync.Group;
@@ -75,8 +73,7 @@ import static org.briarproject.api.contact.ContactManager.RemoveContactHook;
import static org.briarproject.blogs.BlogPostValidator.authorToBdfDictionary; import static org.briarproject.blogs.BlogPostValidator.authorToBdfDictionary;
class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager, class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
AddContactHook, RemoveContactHook, Client, AddContactHook, RemoveContactHook, Client {
AddIdentityHook, RemoveIdentityHook {
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(BlogManagerImpl.class.getName()); Logger.getLogger(BlogManagerImpl.class.getName());
@@ -151,25 +148,6 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
} }
} }
@Override
public void addingIdentity(Transaction txn, LocalAuthor a)
throws DbException {
// add a personal blog for the new identity
LOG.info("New Personal Blog Added.");
Blog b = blogFactory.createBlog(a);
db.addGroup(txn, b.getGroup());
}
@Override
public void removingIdentity(Transaction txn, LocalAuthor a)
throws DbException {
// remove the personal blog of that identity
Blog b = blogFactory.createBlog(a);
db.removeGroup(txn, b.getGroup());
}
@Override @Override
protected boolean incomingMessage(Transaction txn, Message m, BdfList list, protected boolean incomingMessage(Transaction txn, Message m, BdfList list,
BdfDictionary meta) throws DbException, FormatException { BdfDictionary meta) throws DbException, FormatException {

View File

@@ -7,7 +7,6 @@ import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.contact.ContactManager; import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.data.MetadataEncoder; import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.identity.AuthorFactory; import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.lifecycle.LifecycleManager; import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.sync.GroupFactory; import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.sync.MessageFactory; import org.briarproject.api.sync.MessageFactory;
@@ -36,14 +35,11 @@ public class BlogsModule {
@Singleton @Singleton
BlogManager provideBlogManager(BlogManagerImpl blogManager, BlogManager provideBlogManager(BlogManagerImpl blogManager,
LifecycleManager lifecycleManager, ContactManager contactManager, LifecycleManager lifecycleManager, ContactManager contactManager,
IdentityManager identityManager,
ValidationManager validationManager) { ValidationManager validationManager) {
lifecycleManager.registerClient(blogManager); lifecycleManager.registerClient(blogManager);
contactManager.registerAddContactHook(blogManager); contactManager.registerAddContactHook(blogManager);
contactManager.registerRemoveContactHook(blogManager); contactManager.registerRemoveContactHook(blogManager);
identityManager.registerAddIdentityHook(blogManager);
identityManager.registerRemoveIdentityHook(blogManager);
validationManager.registerIncomingMessageHook(CLIENT_ID, blogManager); validationManager.registerIncomingMessageHook(CLIENT_ID, blogManager);
return blogManager; return blogManager;
} }

View File

@@ -9,8 +9,6 @@ import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction; import org.briarproject.api.db.Transaction;
import org.briarproject.api.identity.Author; import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorId; import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.IdentityManager.RemoveIdentityHook;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.transport.KeyManager; import org.briarproject.api.transport.KeyManager;
import java.util.ArrayList; import java.util.ArrayList;
@@ -21,7 +19,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
import javax.inject.Inject; import javax.inject.Inject;
class ContactManagerImpl implements ContactManager, RemoveIdentityHook { class ContactManagerImpl implements ContactManager {
private final DatabaseComponent db; private final DatabaseComponent db;
private final KeyManager keyManager; private final KeyManager keyManager;
@@ -148,11 +146,4 @@ class ContactManagerImpl implements ContactManager, RemoveIdentityHook {
db.removeContact(txn, c); db.removeContact(txn, c);
} }
@Override
public void removingIdentity(Transaction txn, LocalAuthor a)
throws DbException {
// Remove any contacts of the local pseudonym that's being removed
for (ContactId c : db.getContacts(txn, a.getId()))
removeContact(txn, c);
}
} }

View File

@@ -2,17 +2,6 @@ package org.briarproject.contact;
import org.briarproject.api.contact.ContactExchangeTask; import org.briarproject.api.contact.ContactExchangeTask;
import org.briarproject.api.contact.ContactManager; import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.data.BdfReaderFactory;
import org.briarproject.api.data.BdfWriterFactory;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.plugins.ConnectionManager;
import org.briarproject.api.properties.TransportPropertyManager;
import org.briarproject.api.system.Clock;
import org.briarproject.api.transport.StreamReaderFactory;
import org.briarproject.api.transport.StreamWriterFactory;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
@@ -30,9 +19,7 @@ public class ContactModule {
@Provides @Provides
@Singleton @Singleton
ContactManager getContactManager(IdentityManager identityManager, ContactManager getContactManager(ContactManagerImpl contactManager) {
ContactManagerImpl contactManager) {
identityManager.registerRemoveIdentityHook(contactManager);
return contactManager; return contactManager;
} }

View File

@@ -9,7 +9,6 @@ import com.rometools.rome.io.XmlReader;
import org.briarproject.api.FormatException; import org.briarproject.api.FormatException;
import org.briarproject.api.TransportId; import org.briarproject.api.TransportId;
import org.briarproject.api.blogs.Blog;
import org.briarproject.api.blogs.BlogManager; import org.briarproject.api.blogs.BlogManager;
import org.briarproject.api.blogs.BlogPost; import org.briarproject.api.blogs.BlogPost;
import org.briarproject.api.blogs.BlogPostFactory; import org.briarproject.api.blogs.BlogPostFactory;
@@ -27,7 +26,6 @@ import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.TransportEnabledEvent; import org.briarproject.api.event.TransportEnabledEvent;
import org.briarproject.api.feed.Feed; import org.briarproject.api.feed.Feed;
import org.briarproject.api.feed.FeedManager; import org.briarproject.api.feed.FeedManager;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.IdentityManager; import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor; import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.lifecycle.IoExecutor; import org.briarproject.api.lifecycle.IoExecutor;
@@ -459,9 +457,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
String body = getPostBody(b.toString()); String body = getPostBody(b.toString());
try { try {
// create and store post // create and store post
Blog blog = blogManager.getBlog(txn, groupId); LocalAuthor author = identityManager.getLocalAuthor(txn);
AuthorId authorId = blog.getAuthor().getId();
LocalAuthor author = identityManager.getLocalAuthor(txn, authorId);
BlogPost post = blogPostFactory BlogPost post = blogPostFactory
.createBlogPost(groupId, time, null, author, body); .createBlogPost(groupId, time, null, author, body);
blogManager.addLocalPost(txn, post); blogManager.addLocalPost(txn, post);

View File

@@ -10,8 +10,7 @@ import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor; import org.briarproject.api.identity.LocalAuthor;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.logging.Logger;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.inject.Inject; import javax.inject.Inject;
@@ -22,104 +21,62 @@ import static org.briarproject.api.identity.Author.Status.VERIFIED;
class IdentityManagerImpl implements IdentityManager { class IdentityManagerImpl implements IdentityManager {
private final DatabaseComponent db; private final DatabaseComponent db;
private final List<AddIdentityHook> addHooks;
private final List<RemoveIdentityHook> removeHooks; private static final Logger LOG =
Logger.getLogger(IdentityManagerImpl.class.getName());
// Make sure that this variable is immutable
private volatile LocalAuthor cachedAuthor;
@Inject @Inject
IdentityManagerImpl(DatabaseComponent db) { IdentityManagerImpl(DatabaseComponent db) {
this.db = db; this.db = db;
addHooks = new CopyOnWriteArrayList<AddIdentityHook>();
removeHooks = new CopyOnWriteArrayList<RemoveIdentityHook>();
} }
@Override @Override
public void registerAddIdentityHook(AddIdentityHook hook) { public void registerLocalAuthor(LocalAuthor localAuthor) throws DbException {
addHooks.add(hook);
}
@Override
public void registerRemoveIdentityHook(RemoveIdentityHook hook) {
removeHooks.add(hook);
}
@Override
public void addLocalAuthor(LocalAuthor localAuthor) throws DbException {
Transaction txn = db.startTransaction(false); Transaction txn = db.startTransaction(false);
try { try {
db.addLocalAuthor(txn, localAuthor); db.addLocalAuthor(txn, localAuthor);
for (AddIdentityHook hook : addHooks)
hook.addingIdentity(txn, localAuthor);
txn.setComplete(); txn.setComplete();
cachedAuthor = localAuthor;
LOG.info("Local Author created");
} finally { } finally {
db.endTransaction(txn); db.endTransaction(txn);
} }
} }
@Override
public LocalAuthor getLocalAuthor(AuthorId a) throws DbException {
LocalAuthor author;
Transaction txn = db.startTransaction(true);
try {
author = getLocalAuthor(txn, a);
txn.setComplete();
} finally {
db.endTransaction(txn);
}
return author;
}
@Override
public LocalAuthor getLocalAuthor(Transaction txn, AuthorId a)
throws DbException {
return db.getLocalAuthor(txn, a);
}
@Override @Override
public LocalAuthor getLocalAuthor() throws DbException { public LocalAuthor getLocalAuthor() throws DbException {
return getLocalAuthors().iterator().next(); if (cachedAuthor == null) {
Transaction txn = db.startTransaction(true);
try {
cachedAuthor = loadLocalAuthor(txn);
LOG.info("Author loaded from db");
txn.setComplete();
} finally {
db.endTransaction(txn);
}
}
return cachedAuthor;
} }
@Override @Override
public LocalAuthor getLocalAuthor(Transaction txn) throws DbException { public LocalAuthor getLocalAuthor(Transaction txn) throws DbException {
return getLocalAuthors(txn).iterator().next(); if (cachedAuthor == null) {
} cachedAuthor = loadLocalAuthor(txn);
@Override
public Collection<LocalAuthor> getLocalAuthors() throws DbException {
Collection<LocalAuthor> authors;
Transaction txn = db.startTransaction(true);
try {
authors = getLocalAuthors(txn);
txn.setComplete();
} finally {
db.endTransaction(txn);
} }
return authors; return cachedAuthor;
} }
private Collection<LocalAuthor> getLocalAuthors(Transaction txn) private LocalAuthor loadLocalAuthor(Transaction txn) throws DbException{
throws DbException { return db.getLocalAuthors(txn).iterator().next();
return db.getLocalAuthors(txn);
}
@Override
public void removeLocalAuthor(AuthorId a) throws DbException {
Transaction txn = db.startTransaction(false);
try {
LocalAuthor localAuthor = db.getLocalAuthor(txn, a);
for (RemoveIdentityHook hook : removeHooks)
hook.removingIdentity(txn, localAuthor);
db.removeLocalAuthor(txn, a);
txn.setComplete();
} finally {
db.endTransaction(txn);
}
} }
@Override @Override
public Status getAuthorStatus(AuthorId authorId) throws DbException { public Status getAuthorStatus(AuthorId authorId) throws DbException {
Transaction txn = db.startTransaction(false); Transaction txn = db.startTransaction(true);
try { try {
return getAuthorStatus(txn, authorId); return getAuthorStatus(txn, authorId);
} finally { } finally {
@@ -131,10 +88,8 @@ class IdentityManagerImpl implements IdentityManager {
public Status getAuthorStatus(Transaction txn, AuthorId authorId) public Status getAuthorStatus(Transaction txn, AuthorId authorId)
throws DbException { throws DbException {
// Compare to the IDs of the user's identities // Compare to the IDs of the user's identity
for (LocalAuthor a : db.getLocalAuthors(txn)) { if (getLocalAuthor(txn).getId().equals(authorId)) return OURSELVES;
if (a.getId().equals(authorId)) return OURSELVES;
}
Collection<Contact> contacts = db.getContactsByAuthorId(txn, authorId); Collection<Contact> contacts = db.getContactsByAuthorId(txn, authorId);
if (contacts.isEmpty()) return UNKNOWN; if (contacts.isEmpty()) return UNKNOWN;

View File

@@ -31,7 +31,7 @@ public class IdentityModule {
@Provides @Provides
@Singleton @Singleton
IdentityManager provideIdendityModule(DatabaseComponent db) { IdentityManager provideIdentityModule(DatabaseComponent db) {
return new IdentityManagerImpl(db); return new IdentityManagerImpl(db);
} }

View File

@@ -305,10 +305,8 @@ class IntroduceeManager {
boolean alice = comp < 0; boolean alice = comp < 0;
// get our local author // get our local author
AuthorId localAuthorId =
new AuthorId(localState.getRaw(LOCAL_AUTHOR_ID));
LocalAuthor author = LocalAuthor author =
identityManager.getLocalAuthor(txn, localAuthorId); identityManager.getLocalAuthor(txn);
SecretKey secretKey; SecretKey secretKey;
byte[] privateKeyBytes = localState.getRaw(OUR_PRIVATE_KEY); byte[] privateKeyBytes = localState.getRaw(OUR_PRIVATE_KEY);
@@ -336,7 +334,7 @@ class IntroduceeManager {
.createAuthor(localState.getString(NAME), .createAuthor(localState.getString(NAME),
localState.getRaw(PUBLIC_KEY)); localState.getRaw(PUBLIC_KEY));
ContactId contactId = contactManager ContactId contactId = contactManager
.addContact(txn, remoteAuthor, localAuthorId, secretKey, .addContact(txn, remoteAuthor, author.getId(), secretKey,
timestamp, alice, false, false); timestamp, alice, false, false);
// Update local state with ContactId, so we know what to activate // Update local state with ContactId, so we know what to activate

View File

@@ -2,26 +2,19 @@ package org.briarproject.invitation;
import org.briarproject.api.contact.ContactExchangeListener; import org.briarproject.api.contact.ContactExchangeListener;
import org.briarproject.api.contact.ContactExchangeTask; import org.briarproject.api.contact.ContactExchangeTask;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.PseudoRandom; import org.briarproject.api.crypto.PseudoRandom;
import org.briarproject.api.data.BdfReaderFactory; import org.briarproject.api.data.BdfReaderFactory;
import org.briarproject.api.data.BdfWriterFactory; import org.briarproject.api.data.BdfWriterFactory;
import org.briarproject.api.db.DbException; import org.briarproject.api.db.DbException;
import org.briarproject.api.identity.Author; import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.IdentityManager; import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor; import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.invitation.InvitationListener; import org.briarproject.api.invitation.InvitationListener;
import org.briarproject.api.invitation.InvitationState; import org.briarproject.api.invitation.InvitationState;
import org.briarproject.api.invitation.InvitationTask; import org.briarproject.api.invitation.InvitationTask;
import org.briarproject.api.plugins.ConnectionManager;
import org.briarproject.api.plugins.PluginManager; import org.briarproject.api.plugins.PluginManager;
import org.briarproject.api.plugins.duplex.DuplexPlugin; import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.system.Clock;
import org.briarproject.api.transport.StreamReaderFactory;
import org.briarproject.api.transport.StreamWriterFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@@ -51,7 +44,6 @@ class ConnectorGroup extends Thread implements InvitationTask,
private final ContactExchangeTask contactExchangeTask; private final ContactExchangeTask contactExchangeTask;
private final IdentityManager identityManager; private final IdentityManager identityManager;
private final PluginManager pluginManager; private final PluginManager pluginManager;
private final AuthorId localAuthorId;
private final int localInvitationCode, remoteInvitationCode; private final int localInvitationCode, remoteInvitationCode;
private final Collection<InvitationListener> listeners; private final Collection<InvitationListener> listeners;
private final AtomicBoolean connected; private final AtomicBoolean connected;
@@ -66,11 +58,9 @@ class ConnectorGroup extends Thread implements InvitationTask,
private String remoteName = null; private String remoteName = null;
ConnectorGroup(CryptoComponent crypto, BdfReaderFactory bdfReaderFactory, ConnectorGroup(CryptoComponent crypto, BdfReaderFactory bdfReaderFactory,
BdfWriterFactory bdfWriterFactory, BdfWriterFactory bdfWriterFactory, ContactExchangeTask contactExchangeTask,
ContactExchangeTask contactExchangeTask,
IdentityManager identityManager, PluginManager pluginManager, IdentityManager identityManager, PluginManager pluginManager,
AuthorId localAuthorId, int localInvitationCode, int localInvitationCode, int remoteInvitationCode) {
int remoteInvitationCode) {
super("ConnectorGroup"); super("ConnectorGroup");
this.crypto = crypto; this.crypto = crypto;
this.bdfReaderFactory = bdfReaderFactory; this.bdfReaderFactory = bdfReaderFactory;
@@ -78,7 +68,6 @@ class ConnectorGroup extends Thread implements InvitationTask,
this.contactExchangeTask = contactExchangeTask; this.contactExchangeTask = contactExchangeTask;
this.identityManager = identityManager; this.identityManager = identityManager;
this.pluginManager = pluginManager; this.pluginManager = pluginManager;
this.localAuthorId = localAuthorId;
this.localInvitationCode = localInvitationCode; this.localInvitationCode = localInvitationCode;
this.remoteInvitationCode = remoteInvitationCode; this.remoteInvitationCode = remoteInvitationCode;
listeners = new CopyOnWriteArrayList<InvitationListener>(); listeners = new CopyOnWriteArrayList<InvitationListener>();
@@ -113,7 +102,7 @@ class ConnectorGroup extends Thread implements InvitationTask,
LocalAuthor localAuthor; LocalAuthor localAuthor;
// Load the local pseudonym // Load the local pseudonym
try { try {
localAuthor = identityManager.getLocalAuthor(localAuthorId); localAuthor = identityManager.getLocalAuthor();
} catch (DbException e) { } catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
lock.lock(); lock.lock();

View File

@@ -4,7 +4,6 @@ import org.briarproject.api.contact.ContactExchangeTask;
import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.data.BdfReaderFactory; import org.briarproject.api.data.BdfReaderFactory;
import org.briarproject.api.data.BdfWriterFactory; import org.briarproject.api.data.BdfWriterFactory;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.IdentityManager; import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.invitation.InvitationTask; import org.briarproject.api.invitation.InvitationTask;
import org.briarproject.api.invitation.InvitationTaskFactory; import org.briarproject.api.invitation.InvitationTaskFactory;
@@ -35,10 +34,9 @@ class InvitationTaskFactoryImpl implements InvitationTaskFactory {
this.pluginManager = pluginManager; this.pluginManager = pluginManager;
} }
public InvitationTask createTask(AuthorId localAuthorId, int localCode, public InvitationTask createTask(int localCode, int remoteCode) {
int remoteCode) {
return new ConnectorGroup(crypto, bdfReaderFactory, bdfWriterFactory, return new ConnectorGroup(crypto, bdfReaderFactory, bdfWriterFactory,
contactExchangeTask, identityManager, pluginManager, contactExchangeTask, identityManager, pluginManager,
localAuthorId, localCode, remoteCode); localCode, remoteCode);
} }
} }

View File

@@ -1,11 +1,16 @@
package org.briarproject.lifecycle; package org.briarproject.lifecycle;
import org.briarproject.api.clients.Client; import org.briarproject.api.clients.Client;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.KeyPair;
import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException; import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction; import org.briarproject.api.db.Transaction;
import org.briarproject.api.event.EventBus; import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.ShutdownEvent; import org.briarproject.api.event.ShutdownEvent;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.lifecycle.LifecycleManager; import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.lifecycle.Service; import org.briarproject.api.lifecycle.Service;
import org.briarproject.api.lifecycle.ServiceException; import org.briarproject.api.lifecycle.ServiceException;
@@ -17,6 +22,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Semaphore; import java.util.concurrent.Semaphore;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
@@ -36,15 +42,23 @@ class LifecycleManagerImpl implements LifecycleManager {
private final List<Service> services; private final List<Service> services;
private final List<Client> clients; private final List<Client> clients;
private final List<ExecutorService> executors; private final List<ExecutorService> executors;
private final CryptoComponent crypto;
private final AuthorFactory authorFactory;
private final IdentityManager identityManager;
private final Semaphore startStopSemaphore = new Semaphore(1); private final Semaphore startStopSemaphore = new Semaphore(1);
private final CountDownLatch dbLatch = new CountDownLatch(1); private final CountDownLatch dbLatch = new CountDownLatch(1);
private final CountDownLatch startupLatch = new CountDownLatch(1); private final CountDownLatch startupLatch = new CountDownLatch(1);
private final CountDownLatch shutdownLatch = new CountDownLatch(1); private final CountDownLatch shutdownLatch = new CountDownLatch(1);
@Inject @Inject
LifecycleManagerImpl(DatabaseComponent db, EventBus eventBus) { LifecycleManagerImpl(DatabaseComponent db, EventBus eventBus,
CryptoComponent crypto, AuthorFactory authorFactory,
IdentityManager identityManager) {
this.db = db; this.db = db;
this.eventBus = eventBus; this.eventBus = eventBus;
this.crypto = crypto;
this.authorFactory = authorFactory;
this.identityManager = identityManager;
services = new CopyOnWriteArrayList<Service>(); services = new CopyOnWriteArrayList<Service>();
clients = new CopyOnWriteArrayList<Client>(); clients = new CopyOnWriteArrayList<Client>();
executors = new CopyOnWriteArrayList<ExecutorService>(); executors = new CopyOnWriteArrayList<ExecutorService>();
@@ -70,8 +84,30 @@ class LifecycleManagerImpl implements LifecycleManager {
executors.add(e); executors.add(e);
} }
private LocalAuthor createLocalAuthor(final String nickname) {
long now = System.currentTimeMillis();
KeyPair keyPair = crypto.generateSignatureKeyPair();
byte[] publicKey = keyPair.getPublic().getEncoded();
byte[] privateKey = keyPair.getPrivate().getEncoded();
LocalAuthor localAuthor = authorFactory
.createLocalAuthor(nickname, publicKey, privateKey);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Identity creation took " + duration + " ms");
return localAuthor;
}
private void registerLocalAuthor(LocalAuthor author) throws DbException {
long now = System.currentTimeMillis();
identityManager.registerLocalAuthor(author);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Author registration took " + duration +
" ms");
}
@Override @Override
public StartResult startServices() { public StartResult startServices(@Nullable String authorNick) {
if (!startStopSemaphore.tryAcquire()) { if (!startStopSemaphore.tryAcquire()) {
LOG.info("Already starting or stopping"); LOG.info("Already starting or stopping");
return ALREADY_RUNNING; return ALREADY_RUNNING;
@@ -79,6 +115,7 @@ class LifecycleManagerImpl implements LifecycleManager {
try { try {
LOG.info("Starting services"); LOG.info("Starting services");
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
boolean reopened = db.open(); boolean reopened = db.open();
long duration = System.currentTimeMillis() - start; long duration = System.currentTimeMillis() - start;
if (LOG.isLoggable(INFO)) { if (LOG.isLoggable(INFO)) {
@@ -86,6 +123,11 @@ class LifecycleManagerImpl implements LifecycleManager {
LOG.info("Reopening database took " + duration + " ms"); LOG.info("Reopening database took " + duration + " ms");
else LOG.info("Creating database took " + duration + " ms"); else LOG.info("Creating database took " + duration + " ms");
} }
if (authorNick != null) {
registerLocalAuthor(createLocalAuthor(authorNick));
}
dbLatch.countDown(); dbLatch.countDown();
Transaction txn = db.startTransaction(false); Transaction txn = db.startTransaction(false);
try { try {
@@ -181,4 +223,5 @@ class LifecycleManagerImpl implements LifecycleManager {
public void waitForShutdown() throws InterruptedException { public void waitForShutdown() throws InterruptedException {
shutdownLatch.await(); shutdownLatch.await();
} }
} }

View File

@@ -1,7 +1,10 @@
package org.briarproject.lifecycle; package org.briarproject.lifecycle;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.event.EventBus; import org.briarproject.api.event.EventBus;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.lifecycle.IoExecutor; import org.briarproject.api.lifecycle.IoExecutor;
import org.briarproject.api.lifecycle.LifecycleManager; import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.lifecycle.ShutdownManager; import org.briarproject.api.lifecycle.ShutdownManager;
@@ -26,7 +29,8 @@ public class LifecycleModule {
public static class EagerSingletons { public static class EagerSingletons {
@Inject @Inject
@IoExecutor Executor executor; @IoExecutor
Executor executor;
} }
private final ExecutorService ioExecutor; private final ExecutorService ioExecutor;
@@ -51,8 +55,10 @@ public class LifecycleModule {
@Provides @Provides
@Singleton @Singleton
LifecycleManager provideLifecycleManager(DatabaseComponent db, LifecycleManager provideLifecycleManager(DatabaseComponent db,
EventBus eventBus) { EventBus eventBus, CryptoComponent crypto,
return new LifecycleManagerImpl(db, eventBus); AuthorFactory authorFactory, IdentityManager identityManager) {
return new LifecycleManagerImpl(db, eventBus, crypto, authorFactory,
identityManager);
} }
@Provides @Provides

View File

@@ -38,6 +38,16 @@ public class TestDatabaseConfig implements DatabaseConfig {
return key; return key;
} }
@Override
public void setAuthorNick(String nickName) {
}
@Override
public String getAuthorNick() {
return null;
}
@Override @Override
public long getMaxSize() { public long getMaxSize() {
return maxSize; return maxSize;

View File

@@ -38,7 +38,7 @@ public class TestLifecycleModule {
} }
@Override @Override
public StartResult startServices() { public StartResult startServices(String authorNick) {
return StartResult.SUCCESS; return StartResult.SUCCESS;
} }

View File

@@ -93,7 +93,6 @@ public class BlogManagerImplTest extends BriarTestCase {
@Test @Test
public void testCreateLocalState() throws DbException { public void testCreateLocalState() throws DbException {
final Transaction txn = new Transaction(null, false); final Transaction txn = new Transaction(null, false);
final LocalAuthor localAuthor = (LocalAuthor) blog1.getAuthor();
final ContactId contactId = new ContactId(0); final ContactId contactId = new ContactId(0);
final Collection<ContactId> contactIds = final Collection<ContactId> contactIds =
@@ -105,7 +104,7 @@ public class BlogManagerImplTest extends BriarTestCase {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(identityManager).getLocalAuthor(txn); oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor)); will(returnValue(blog1.getAuthor()));
oneOf(blogFactory).createBlog(blog1.getAuthor()); oneOf(blogFactory).createBlog(blog1.getAuthor());
will(returnValue(blog1)); will(returnValue(blog1));
oneOf(db).containsGroup(txn, blog1.getId()); oneOf(db).containsGroup(txn, blog1.getId());
@@ -151,42 +150,6 @@ public class BlogManagerImplTest extends BriarTestCase {
context.assertIsSatisfied(); context.assertIsSatisfied();
} }
@Test
public void testAddingIdentity() throws DbException {
final Transaction txn = new Transaction(null, false);
Author a = blog1.getAuthor();
final LocalAuthor localAuthor =
new LocalAuthor(a.getId(), a.getName(), a.getPublicKey(),
a.getPublicKey(), 0);
context.checking(new Expectations() {{
oneOf(blogFactory).createBlog(localAuthor);
will(returnValue(blog1));
oneOf(db).addGroup(txn, blog1.getGroup());
}});
blogManager.addingIdentity(txn, localAuthor);
context.assertIsSatisfied();
}
@Test
public void testRemovingIdentity() throws DbException {
final Transaction txn = new Transaction(null, false);
Author a = blog1.getAuthor();
final LocalAuthor localAuthor =
new LocalAuthor(a.getId(), a.getName(), a.getPublicKey(),
a.getPublicKey(), 0);
context.checking(new Expectations() {{
oneOf(blogFactory).createBlog(localAuthor);
will(returnValue(blog1));
oneOf(db).removeGroup(txn, blog1.getGroup());
}});
blogManager.removingIdentity(txn, localAuthor);
context.assertIsSatisfied();
}
@Test @Test
public void testIncomingMessage() throws DbException, FormatException { public void testIncomingMessage() throws DbException, FormatException {
final Transaction txn = new Transaction(null, false); final Transaction txn = new Transaction(null, false);

View File

@@ -136,7 +136,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
// startTransaction() // startTransaction()
oneOf(database).startTransaction(); oneOf(database).startTransaction();
will(returnValue(txn)); will(returnValue(txn));
// addLocalAuthor() // registerLocalAuthor()
oneOf(database).containsLocalAuthor(txn, localAuthorId); oneOf(database).containsLocalAuthor(txn, localAuthorId);
will(returnValue(false)); will(returnValue(false));
oneOf(database).addLocalAuthor(txn, localAuthor); oneOf(database).addLocalAuthor(txn, localAuthor);
@@ -813,7 +813,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
// startTransaction() // startTransaction()
oneOf(database).startTransaction(); oneOf(database).startTransaction();
will(returnValue(txn)); will(returnValue(txn));
// addLocalAuthor() // registerLocalAuthor()
oneOf(database).containsLocalAuthor(txn, localAuthorId); oneOf(database).containsLocalAuthor(txn, localAuthorId);
will(returnValue(false)); will(returnValue(false));
oneOf(database).addLocalAuthor(txn, localAuthor); oneOf(database).addLocalAuthor(txn, localAuthor);

View File

@@ -46,7 +46,7 @@ public class IdentityManagerImplTest extends BriarTestCase {
@Test @Test
public void testGetAuthorStatus() throws DbException { public void testGetAuthorStatus() throws DbException {
AuthorId authorId = new AuthorId(TestUtils.getRandomId()); final AuthorId authorId = new AuthorId(TestUtils.getRandomId());
final Collection<LocalAuthor> localAuthors = new ArrayList<>(); final Collection<LocalAuthor> localAuthors = new ArrayList<>();
LocalAuthor localAuthor = LocalAuthor localAuthor =
new LocalAuthor(new AuthorId(TestUtils.getRandomId()), new LocalAuthor(new AuthorId(TestUtils.getRandomId()),
@@ -54,9 +54,17 @@ public class IdentityManagerImplTest extends BriarTestCase {
TestUtils.getRandomBytes(42), TestUtils.getRandomBytes(42),
TestUtils.getRandomBytes(42), 0); TestUtils.getRandomBytes(42), 0);
localAuthors.add(localAuthor); localAuthors.add(localAuthor);
Collection<Contact> contacts = new ArrayList<>(); final Collection<Contact> contacts = new ArrayList<>();
checkAuthorStatusContext(localAuthors, authorId, contacts); context.checking(new Expectations() {{
oneOf(db).startTransaction(true);
will(returnValue(txn));
oneOf(db).getLocalAuthors(txn);
will(returnValue(localAuthors));
oneOf(db).getContactsByAuthorId(txn, authorId);
will(returnValue(contacts));
oneOf(db).endTransaction(txn);
}});
assertEquals(UNKNOWN, identityManager.getAuthorStatus(authorId)); assertEquals(UNKNOWN, identityManager.getAuthorStatus(authorId));
// add one unverified contact // add one unverified contact
@@ -67,7 +75,7 @@ public class IdentityManagerImplTest extends BriarTestCase {
false, true); false, true);
contacts.add(contact); contacts.add(contact);
checkAuthorStatusContext(localAuthors, authorId, contacts); checkAuthorStatusContext(authorId, contacts);
assertEquals(UNVERIFIED, identityManager.getAuthorStatus(authorId)); assertEquals(UNVERIFIED, identityManager.getAuthorStatus(authorId));
// add one verified contact // add one verified contact
@@ -76,37 +84,28 @@ public class IdentityManagerImplTest extends BriarTestCase {
true, true); true, true);
contacts.add(contact2); contacts.add(contact2);
checkAuthorStatusContext(localAuthors, authorId, contacts); checkAuthorStatusContext(authorId, contacts);
assertEquals(VERIFIED, identityManager.getAuthorStatus(authorId)); assertEquals(VERIFIED, identityManager.getAuthorStatus(authorId));
// add ourselves to the local authors
LocalAuthor localAuthor2 =
new LocalAuthor(authorId,
TestUtils.getRandomString(8),
TestUtils.getRandomBytes(42),
TestUtils.getRandomBytes(42), 0);
localAuthors.add(localAuthor2);
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(db).startTransaction(false); oneOf(db).startTransaction(true);
will(returnValue(txn)); will(returnValue(txn));
oneOf(db).getLocalAuthors(txn); never(db).getLocalAuthors(txn);
will(returnValue(localAuthors)); never(db).getContactsByAuthorId(txn, authorId);
oneOf(db).endTransaction(txn); oneOf(db).endTransaction(txn);
}}); }});
assertEquals(OURSELVES, identityManager.getAuthorStatus(authorId)); assertEquals(OURSELVES,
identityManager.getAuthorStatus(localAuthor.getId()));
context.assertIsSatisfied(); context.assertIsSatisfied();
} }
private void checkAuthorStatusContext( private void checkAuthorStatusContext(final AuthorId authorId,
final Collection<LocalAuthor> localAuthors, final AuthorId authorId,
final Collection<Contact> contacts) throws DbException { final Collection<Contact> contacts) throws DbException {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(db).startTransaction(false); oneOf(db).startTransaction(true);
will(returnValue(txn)); will(returnValue(txn));
oneOf(db).getLocalAuthors(txn); never(db).getLocalAuthors(txn);
will(returnValue(localAuthors));
oneOf(db).getContactsByAuthorId(txn, authorId); oneOf(db).getContactsByAuthorId(txn, authorId);
will(returnValue(contacts)); will(returnValue(contacts));
oneOf(db).endTransaction(txn); oneOf(db).endTransaction(txn);

View File

@@ -14,7 +14,7 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:2.2.1' classpath 'com.android.tools.build:gradle:2.2.2'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
classpath 'de.undercouch:gradle-download-task:2.1.0' classpath 'de.undercouch:gradle-download-task:2.1.0'
classpath files('briar-core/libs/gradle-witness.jar') classpath files('briar-core/libs/gradle-witness.jar')