diff --git a/briar-api/src/main/java/org/briarproject/briar/api/socialbackup/recovery/RestoreAccount.java b/briar-api/src/main/java/org/briarproject/briar/api/socialbackup/recovery/RestoreAccount.java index 45e2e983f..db56ad81d 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/socialbackup/recovery/RestoreAccount.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/socialbackup/recovery/RestoreAccount.java @@ -9,6 +9,7 @@ import java.security.GeneralSecurityException; public interface RestoreAccount { + int getNumberOfShards(); boolean addReturnShardPayload(ReturnShardPayload toAdd); @@ -19,5 +20,5 @@ public interface RestoreAccount { SocialBackup getSocialBackup(); - void addContactsToDb() throws InterruptedException, DbException; + void addContactsToDb() throws DbException; } diff --git a/briar-core/src/main/java/org/briarproject/briar/socialbackup/recovery/RestoreAccountImpl.java b/briar-core/src/main/java/org/briarproject/briar/socialbackup/recovery/RestoreAccountImpl.java index 25f0d351f..5b05e5d1e 100644 --- a/briar-core/src/main/java/org/briarproject/briar/socialbackup/recovery/RestoreAccountImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/socialbackup/recovery/RestoreAccountImpl.java @@ -2,9 +2,12 @@ package org.briarproject.briar.socialbackup.recovery; import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.contact.Contact; +import org.briarproject.bramble.api.contact.ContactManager; import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; +import org.briarproject.bramble.api.identity.AuthorId; +import org.briarproject.bramble.api.lifecycle.IoExecutor; import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.briar.api.socialbackup.BackupPayload; import org.briarproject.briar.api.socialbackup.ContactData; @@ -17,26 +20,39 @@ import org.briarproject.briar.socialbackup.BackupPayloadDecoder; import java.security.GeneralSecurityException; import java.util.ArrayList; +import java.util.concurrent.Executor; +import java.util.logging.Logger; import javax.inject.Inject; +import static java.util.logging.Logger.getLogger; + public class RestoreAccountImpl implements RestoreAccount { - private ArrayList recoveredShards = new ArrayList<>(); + private final ArrayList recoveredShards = new ArrayList<>(); private final DarkCrystal darkCrystal; + private final Executor ioExecutor; private final DatabaseComponent db; + private final ContactManager contactManager; private final LifecycleManager lifecycleManager; private SecretKey secretKey; private final BackupPayloadDecoder backupPayloadDecoder; private SocialBackup socialBackup; + private static final Logger LOG = + getLogger(RestoreAccountImpl.class.getName()); + @Inject RestoreAccountImpl(DarkCrystal darkCrystal, BackupPayloadDecoder backupPayloadDecoder, DatabaseComponent db, + @IoExecutor Executor ioExecutor, + ContactManager contactManager, LifecycleManager lifecycleManager) { this.darkCrystal = darkCrystal; this.backupPayloadDecoder = backupPayloadDecoder; this.db = db; + this.ioExecutor = ioExecutor; this.lifecycleManager = lifecycleManager; + this.contactManager = contactManager; } public int getNumberOfShards() { @@ -57,7 +73,7 @@ public class RestoreAccountImpl implements RestoreAccount { } public boolean canRecover() { - ArrayList shards = new ArrayList(); + ArrayList shards = new ArrayList<>(); for (ReturnShardPayload returnShardPayload : recoveredShards) { // TODO check shards all have same secret id shards.add(returnShardPayload.getShard()); @@ -91,16 +107,30 @@ public class RestoreAccountImpl implements RestoreAccount { return socialBackup; } - public void addContactsToDb() throws InterruptedException, DbException { + public void addContactsToDb() throws DbException { if (socialBackup == null) throw new DbException(); - // TODO maybe waitForDatabase should be in another thread - lifecycleManager.waitForDatabase(); - db.transaction(false, txn -> { - for (ContactData contactData : socialBackup.getContacts()) { - Contact c = contactData.getContact(); - db.addContact(txn, c.getAuthor(), c.getLocalAuthorId(), - c.getHandshakePublicKey(), c.isVerified()); + AuthorId localAuthorId = socialBackup.getIdentity().getId(); + + ioExecutor.execute(() -> { + try { + lifecycleManager.waitForDatabase(); + } catch (InterruptedException e) { + LOG.warning("Interrupted when waiting for database"); } + try { + db.transaction(false, txn -> { + for (ContactData contactData : socialBackup.getContacts()) { + Contact c = contactData.getContact(); + LOG.info("Adding contact " + c.getAuthor().getName() + " " + c.getAlias()); + contactManager.addContact(txn, c.getAuthor(), localAuthorId, + c.getHandshakePublicKey(), c.isVerified()); + } + }); + } catch (DbException e) { + LOG.warning("Error adding contacts to database"); + LOG.warning(e.getMessage()); + } + LOG.info("Added all contacts"); }); } }