attempt to incorporate fragments (WIP)

This commit is contained in:
ameba23
2021-03-02 09:47:13 +01:00
parent dcda13db64
commit 681b151c8b
7 changed files with 257 additions and 8 deletions

View File

@@ -1,4 +1,4 @@
package org.briarproject.briar.android.darkcrystal;
package org.briarproject.briar.android.socialbackup;
import android.content.Context;
import android.os.Bundle;
@@ -11,7 +11,7 @@ import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.backup.creation.CreateBackupController;
import org.briarproject.briar.android.socialbackup.creation.CreateBackupController;
import org.briarproject.briar.android.contact.BaseContactListAdapter;
import org.briarproject.briar.android.contactselection.BaseContactSelectorFragment;
import org.briarproject.briar.android.contactselection.ContactDisplayAdapter;
@@ -71,7 +71,7 @@ public class CustodianDisplayFragment extends BaseContactSelectorFragment<Select
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requireNonNull(getActivity()).setTitle(R.string.activity_name_distributed_backup);
requireActivity().setTitle(R.string.activity_name_distributed_backup);
}
@Override

View File

@@ -1,4 +1,4 @@
package org.briarproject.briar.android.darkcrystal;
package org.briarproject.briar.android.socialbackup;
import android.os.Bundle;
import android.view.MenuItem;
@@ -11,7 +11,7 @@ import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.backup.creation.CreateBackupController;
import org.briarproject.briar.android.socialbackup.creation.CreateBackupController;
import org.briarproject.briar.android.contactselection.BaseContactSelectorAdapter;
import org.briarproject.briar.android.contactselection.ContactSelectorController;
import org.briarproject.briar.android.contactselection.ContactSelectorFragment;
@@ -51,7 +51,7 @@ public class CustodianSelectorFragment extends ContactSelectorFragment {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requireNonNull(getActivity()).setTitle(R.string.title_select_custodians);
requireActivity().setTitle(R.string.title_select_custodians);
}
@Override

View File

@@ -1,4 +1,4 @@
package org.briarproject.briar.android.darkcrystal;
package org.briarproject.briar.android.socialbackup;
import android.os.Bundle;
import android.widget.Toast;

View File

@@ -36,7 +36,7 @@ public class ThresholdSelectorFragment extends BaseFragment {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requireNonNull(getActivity()).setTitle(R.string.title_define_threshold);
requireActivity().setTitle(R.string.title_define_threshold);
}
@Nullable

View File

@@ -0,0 +1,26 @@
package org.briarproject.briar.android.socialbackup.creation;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.briar.android.contactselection.ContactSelectorController;
import org.briarproject.briar.android.contactselection.SelectableContactItem;
import org.briarproject.briar.android.controller.handler.ResultExceptionHandler;
import java.util.Collection;
import androidx.annotation.Nullable;
@NotNullByDefault
public interface CreateBackupController
extends ContactSelectorController<SelectableContactItem> {
void createGroup(String name,
ResultExceptionHandler<GroupId, DbException> result);
void sendInvitation(GroupId g, Collection<ContactId> contacts,
@Nullable String text,
ResultExceptionHandler<Void, DbException> result);
}

View File

@@ -0,0 +1,205 @@
package org.briarproject.briar.android.socialbackup.creation;
import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.contact.ContactManager;
import org.briarproject.bramble.api.crypto.CryptoExecutor;
import org.briarproject.bramble.api.db.DatabaseExecutor;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.NoSuchContactException;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.briar.android.contactselection.ContactSelectorControllerImpl;
import org.briarproject.briar.android.controller.handler.ResultExceptionHandler;
import org.briarproject.briar.api.privategroup.GroupMessage;
import org.briarproject.briar.api.privategroup.GroupMessageFactory;
import org.briarproject.briar.api.privategroup.PrivateGroup;
import org.briarproject.briar.api.privategroup.PrivateGroupFactory;
import org.briarproject.briar.api.privategroup.PrivateGroupManager;
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationFactory;
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import androidx.annotation.Nullable;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@Immutable
@NotNullByDefault
/**
* Derived from {@link org.briarproject.briar.android.privategroup.invitation.GroupInvitationControllerImpl}
*/
class CreateBackupControllerImpl extends ContactSelectorControllerImpl
implements CreateBackupController {
private static final Logger LOG =
Logger.getLogger(
CreateBackupControllerImpl.class.getName());
private final Executor cryptoExecutor;
private final ContactManager contactManager;
private final IdentityManager identityManager;
private final PrivateGroupFactory groupFactory;
private final GroupMessageFactory groupMessageFactory;
private final PrivateGroupManager groupManager;
private final GroupInvitationFactory groupInvitationFactory;
private final GroupInvitationManager groupInvitationManager;
private final Clock clock;
@Inject
CreateBackupControllerImpl(@DatabaseExecutor Executor dbExecutor,
@CryptoExecutor Executor cryptoExecutor,
LifecycleManager lifecycleManager, ContactManager contactManager,
IdentityManager identityManager, PrivateGroupFactory groupFactory,
GroupMessageFactory groupMessageFactory,
PrivateGroupManager groupManager,
GroupInvitationFactory groupInvitationFactory,
GroupInvitationManager groupInvitationManager, Clock clock) {
super(dbExecutor, lifecycleManager, contactManager);
this.cryptoExecutor = cryptoExecutor;
this.contactManager = contactManager;
this.identityManager = identityManager;
this.groupFactory = groupFactory;
this.groupMessageFactory = groupMessageFactory;
this.groupManager = groupManager;
this.groupInvitationFactory = groupInvitationFactory;
this.groupInvitationManager = groupInvitationManager;
this.clock = clock;
}
@Override
public void createGroup(String name,
ResultExceptionHandler<GroupId, DbException> handler) {
runOnDbThread(() -> {
try {
LocalAuthor author = identityManager.getLocalAuthor();
createGroupAndMessages(author, name, handler);
} catch (DbException e) {
logException(LOG, WARNING, e);
handler.onException(e);
}
});
}
private void createGroupAndMessages(LocalAuthor author, String name,
ResultExceptionHandler<GroupId, DbException> handler) {
cryptoExecutor.execute(() -> {
LOG.info("Creating group...");
PrivateGroup group =
groupFactory.createPrivateGroup(name, author);
LOG.info("Creating new join announcement...");
GroupMessage joinMsg =
groupMessageFactory.createJoinMessage(group.getId(),
clock.currentTimeMillis(), author);
storeGroup(group, joinMsg, handler);
});
}
private void storeGroup(PrivateGroup group, GroupMessage joinMsg,
ResultExceptionHandler<GroupId, DbException> handler) {
runOnDbThread(() -> {
LOG.info("Adding group to database...");
try {
groupManager.addPrivateGroup(group, joinMsg, true);
handler.onResult(group.getId());
} catch (DbException e) {
logException(LOG, WARNING, e);
handler.onException(e);
}
});
}
@Override
protected boolean isDisabled(GroupId g, Contact c) {
return false;
}
@Override
public void sendInvitation(GroupId g, Collection<ContactId> contactIds,
@Nullable String text,
ResultExceptionHandler<Void, DbException> handler) {
runOnDbThread(() -> {
try {
LocalAuthor localAuthor = identityManager.getLocalAuthor();
List<Contact> contacts = new ArrayList<>();
for (ContactId c : contactIds) {
try {
contacts.add(contactManager.getContact(c));
} catch (NoSuchContactException e) {
// Continue
}
}
signInvitations(g, localAuthor, contacts, text, handler);
} catch (DbException e) {
logException(LOG, WARNING, e);
handler.onException(e);
}
});
}
private void signInvitations(GroupId g, LocalAuthor localAuthor,
Collection<Contact> contacts, @Nullable String text,
ResultExceptionHandler<Void, DbException> handler) {
cryptoExecutor.execute(() -> {
long timestamp = clock.currentTimeMillis();
List<InvitationContext> contexts = new ArrayList<>();
for (Contact c : contacts) {
byte[] signature = groupInvitationFactory.signInvitation(c, g,
timestamp, localAuthor.getPrivateKey());
contexts.add(new InvitationContext(c.getId(), timestamp,
signature));
}
sendInvitations(g, contexts, text, handler);
});
}
private void sendInvitations(GroupId g,
Collection<InvitationContext> contexts, @Nullable String text,
ResultExceptionHandler<Void, DbException> handler) {
runOnDbThread(() -> {
try {
for (InvitationContext context : contexts) {
try {
groupInvitationManager.sendInvitation(g,
context.contactId, text, context.timestamp,
context.signature);
} catch (NoSuchContactException e) {
// Continue
}
}
//noinspection ConstantConditions
handler.onResult(null);
} catch (DbException e) {
logException(LOG, WARNING, e);
handler.onException(e);
}
});
}
private static class InvitationContext {
private final ContactId contactId;
private final long timestamp;
private final byte[] signature;
private InvitationContext(ContactId contactId, long timestamp,
byte[] signature) {
this.contactId = contactId;
this.timestamp = timestamp;
this.signature = signature;
}
}
}

View File

@@ -0,0 +1,18 @@
package org.briarproject.briar.android.socialbackup.creation;
import org.briarproject.briar.android.activity.ActivityScope;
import dagger.Module;
import dagger.Provides;
@Module
public class CreateBackupModule {
@ActivityScope
@Provides
CreateBackupController provideCreateGroupController(
CreateBackupControllerImpl createBackupController) {
return createBackupController;
}
}