Create ThreadListViewModels and move loading of named groups there

This commit is contained in:
Torsten Grote
2021-01-06 10:59:20 -03:00
parent 36a9174781
commit ab43dd4986
13 changed files with 387 additions and 142 deletions

View File

@@ -35,6 +35,7 @@ import org.briarproject.briar.android.forum.ForumModule;
import org.briarproject.briar.android.keyagreement.ContactExchangeModule;
import org.briarproject.briar.android.login.LoginModule;
import org.briarproject.briar.android.navdrawer.NavDrawerModule;
import org.briarproject.briar.android.privategroup.conversation.GroupConversationModule;
import org.briarproject.briar.android.settings.SettingsModule;
import org.briarproject.briar.android.privategroup.list.GroupListModule;
import org.briarproject.briar.android.reporting.DevReportModule;
@@ -81,6 +82,7 @@ import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD;
// below need to be within same scope as ViewModelProvider.Factory
ForumModule.BindsModule.class,
GroupListModule.class,
GroupConversationModule.BindsModule.class,
})
public class AppModule {

View File

@@ -21,6 +21,7 @@ import org.briarproject.briar.android.sharing.ShareForumActivity;
import org.briarproject.briar.android.threaded.ThreadItemAdapter;
import org.briarproject.briar.android.threaded.ThreadListActivity;
import org.briarproject.briar.android.threaded.ThreadListController;
import org.briarproject.briar.android.threaded.ThreadListViewModel;
import org.briarproject.briar.api.forum.Forum;
import javax.annotation.Nullable;
@@ -28,11 +29,13 @@ import javax.inject.Inject;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
import static android.widget.Toast.LENGTH_SHORT;
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_SHARE_FORUM;
import static org.briarproject.briar.android.util.UiUtils.observeOnce;
import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_POST_TEXT_LENGTH;
@MethodsNotNullByDefault
@@ -41,12 +44,18 @@ public class ForumActivity extends
ThreadListActivity<Forum, ForumPostItem, ThreadItemAdapter<ForumPostItem>>
implements ForumListener {
@Inject
ViewModelProvider.Factory viewModelFactory;
@Inject
ForumController forumController;
private ForumViewModel viewModel;
@Override
public void injectActivity(ActivityComponent component) {
component.inject(this);
viewModel = new ViewModelProvider(this, viewModelFactory)
.get(ForumViewModel.class);
}
@Override
@@ -54,6 +63,11 @@ public class ForumActivity extends
return forumController;
}
@Override
protected ThreadListViewModel<Forum, ForumPostItem> getViewModel() {
return viewModel;
}
@Override
public void onCreate(@Nullable Bundle state) {
super.onCreate(state);
@@ -62,8 +76,13 @@ public class ForumActivity extends
Intent i = getIntent();
String groupName = i.getStringExtra(GROUP_NAME);
if (groupName != null) setTitle(groupName);
else loadNamedGroup();
if (groupName != null) {
setTitle(groupName);
} else {
observeOnce(viewModel.loadForum(), this, forum ->
setTitle(forum.getName())
);
}
// Open member list on Toolbar click
if (toolbar != null) {
@@ -76,11 +95,6 @@ public class ForumActivity extends
}
}
@Override
protected void onNamedGroupLoaded(Forum forum) {
setTitle(forum.getName());
}
@Override
protected ThreadItemAdapter<ForumPostItem> createAdapter(
LinearLayoutManager layoutManager) {
@@ -88,7 +102,8 @@ public class ForumActivity extends
}
@Override
protected void onActivityResult(int request, int result, Intent data) {
protected void onActivityResult(int request, int result,
@Nullable Intent data) {
super.onActivityResult(request, result, data);
if (request == REQUEST_SHARE_FORUM && result == RESULT_OK) {
@@ -108,25 +123,24 @@ public class ForumActivity extends
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_forum_share:
Intent i2 = new Intent(this, ShareForumActivity.class);
i2.setFlags(FLAG_ACTIVITY_CLEAR_TOP);
i2.putExtra(GROUP_ID, groupId.getBytes());
startActivityForResult(i2, REQUEST_SHARE_FORUM);
return true;
case R.id.action_forum_sharing_status:
Intent i3 = new Intent(this, ForumSharingStatusActivity.class);
i3.setFlags(FLAG_ACTIVITY_CLEAR_TOP);
i3.putExtra(GROUP_ID, groupId.getBytes());
startActivity(i3);
return true;
case R.id.action_forum_delete:
showUnsubscribeDialog();
return true;
default:
return super.onOptionsItemSelected(item);
int itemId = item.getItemId();
if (itemId == R.id.action_forum_share) {
Intent i2 = new Intent(this, ShareForumActivity.class);
i2.setFlags(FLAG_ACTIVITY_CLEAR_TOP);
i2.putExtra(GROUP_ID, groupId.getBytes());
startActivityForResult(i2, REQUEST_SHARE_FORUM);
return true;
} else if (itemId == R.id.action_forum_sharing_status) {
Intent i3 = new Intent(this, ForumSharingStatusActivity.class);
i3.setFlags(FLAG_ACTIVITY_CLEAR_TOP);
i3.putExtra(GROUP_ID, groupId.getBytes());
startActivity(i3);
return true;
} else if (itemId == R.id.action_forum_delete) {
showUnsubscribeDialog();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override

View File

@@ -19,6 +19,11 @@ public class ForumModule {
@IntoMap
@ViewModelKey(ForumListViewModel.class)
ViewModel bindForumListViewModel(ForumListViewModel forumListViewModel);
@Binds
@IntoMap
@ViewModelKey(ForumViewModel.class)
ViewModel bindForumViewModel(ForumViewModel forumViewModel);
}
@ActivityScope

View File

@@ -0,0 +1,82 @@
package org.briarproject.briar.android.forum;
import android.app.Application;
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.TransactionManager;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.briar.android.threaded.ThreadListViewModel;
import org.briarproject.briar.api.android.AndroidNotificationManager;
import org.briarproject.briar.api.forum.Forum;
import org.briarproject.briar.api.forum.ForumManager;
import org.briarproject.briar.api.forum.ForumSharingManager;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
import javax.inject.Inject;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.LogUtils.logException;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
class ForumViewModel extends ThreadListViewModel<Forum, ForumPostItem> {
private static final Logger LOG = getLogger(ForumViewModel.class.getName());
private final ForumManager forumManager;
private final ForumSharingManager forumSharingManager;
@Inject
ForumViewModel(Application application,
@DatabaseExecutor Executor dbExecutor,
LifecycleManager lifecycleManager,
TransactionManager db,
AndroidExecutor androidExecutor,
IdentityManager identityManager,
AndroidNotificationManager notificationManager,
@CryptoExecutor Executor cryptoExecutor,
Clock clock,
EventBus eventBus,
ForumManager forumManager,
ForumSharingManager forumSharingManager) {
super(application, dbExecutor, lifecycleManager, db, androidExecutor,
identityManager, notificationManager, cryptoExecutor, clock,
eventBus);
this.forumManager = forumManager;
this.forumSharingManager = forumSharingManager;
}
@Override
public void eventOccurred(Event e) {
}
LiveData<Forum> loadForum() {
MutableLiveData<Forum> forum = new MutableLiveData<>();
runOnDbThread(() -> {
try {
Forum f = forumManager.getForum(groupId);
forum.postValue(f);
} catch (DbException e) {
logException(LOG, WARNING, e);
}
});
return forum;
}
}

View File

@@ -11,7 +11,6 @@ import android.view.MenuItem;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.briar.R;
@@ -24,6 +23,7 @@ import org.briarproject.briar.android.privategroup.memberlist.GroupMemberListAct
import org.briarproject.briar.android.privategroup.reveal.RevealContactsActivity;
import org.briarproject.briar.android.threaded.ThreadListActivity;
import org.briarproject.briar.android.threaded.ThreadListController;
import org.briarproject.briar.android.threaded.ThreadListViewModel;
import org.briarproject.briar.api.privategroup.PrivateGroup;
import org.briarproject.briar.api.privategroup.Visibility;
@@ -32,11 +32,13 @@ import javax.inject.Inject;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_GROUP_INVITE;
import static org.briarproject.briar.android.util.UiUtils.observeOnce;
import static org.briarproject.briar.api.privategroup.PrivateGroupConstants.MAX_GROUP_POST_TEXT_LENGTH;
@MethodsNotNullByDefault
@@ -45,9 +47,13 @@ public class GroupActivity extends
ThreadListActivity<PrivateGroup, GroupMessageItem, GroupMessageAdapter>
implements GroupListener, OnClickListener {
@Inject
ViewModelProvider.Factory viewModelFactory;
@Inject
GroupController controller;
private GroupViewModel viewModel;
@Nullable
private Boolean isCreator = null;
private boolean isDissolved = false;
@@ -57,6 +63,8 @@ public class GroupActivity extends
@Override
public void injectActivity(ActivityComponent component) {
component.inject(this);
viewModel = new ViewModelProvider(this, viewModelFactory)
.get(GroupViewModel.class);
}
@Override
@@ -64,6 +72,11 @@ public class GroupActivity extends
return controller;
}
@Override
protected ThreadListViewModel<PrivateGroup, GroupMessageItem> getViewModel() {
return viewModel;
}
@Override
public void onCreate(@Nullable Bundle state) {
super.onCreate(state);
@@ -73,7 +86,14 @@ public class GroupActivity extends
Intent i = getIntent();
String groupName = i.getStringExtra(GROUP_NAME);
if (groupName != null) setTitle(groupName);
loadNamedGroup();
observeOnce(viewModel.getPrivateGroup(), this, privateGroup ->
setTitle(privateGroup.getName())
);
observeOnce(viewModel.isCreator(), this, isCreator -> {
this.isCreator = isCreator; // TODO remove field
adapter.setPerspective(isCreator);
showMenuItems();
});
// Open member list on Toolbar click
if (toolbar != null) {
@@ -111,25 +131,6 @@ public class GroupActivity extends
});
}
@Override
protected void onNamedGroupLoaded(PrivateGroup group) {
setTitle(group.getName());
controller.loadLocalAuthor(
new UiResultExceptionHandler<LocalAuthor, DbException>(this) {
@Override
public void onResultUi(LocalAuthor author) {
isCreator = group.getCreator().equals(author);
adapter.setPerspective(isCreator);
showMenuItems();
}
@Override
public void onExceptionUi(DbException exception) {
handleException(exception);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
@@ -155,42 +156,44 @@ public class GroupActivity extends
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_group_member_list:
Intent i1 = new Intent(this, GroupMemberListActivity.class);
i1.putExtra(GROUP_ID, groupId.getBytes());
startActivity(i1);
return true;
case R.id.action_group_reveal:
if (isCreator == null || isCreator)
throw new IllegalStateException();
Intent i2 = new Intent(this, RevealContactsActivity.class);
i2.putExtra(GROUP_ID, groupId.getBytes());
startActivity(i2);
return true;
case R.id.action_group_invite:
if (isCreator == null || !isCreator)
throw new IllegalStateException();
Intent i3 = new Intent(this, GroupInviteActivity.class);
i3.putExtra(GROUP_ID, groupId.getBytes());
startActivityForResult(i3, REQUEST_GROUP_INVITE);
return true;
case R.id.action_group_leave:
if (isCreator == null || isCreator)
throw new IllegalStateException();
showLeaveGroupDialog();
return true;
case R.id.action_group_dissolve:
if (isCreator == null || !isCreator)
throw new IllegalStateException();
showDissolveGroupDialog();
default:
return super.onOptionsItemSelected(item);
int itemId = item.getItemId();
if (itemId == R.id.action_group_member_list) {
Intent i1 = new Intent(this, GroupMemberListActivity.class);
i1.putExtra(GROUP_ID, groupId.getBytes());
startActivity(i1);
return true;
} else if (itemId == R.id.action_group_reveal) {
if (isCreator == null || isCreator)
throw new IllegalStateException();
Intent i2 = new Intent(this, RevealContactsActivity.class);
i2.putExtra(GROUP_ID, groupId.getBytes());
startActivity(i2);
return true;
} else if (itemId == R.id.action_group_invite) {
if (isCreator == null || !isCreator)
throw new IllegalStateException();
Intent i3 = new Intent(this, GroupInviteActivity.class);
i3.putExtra(GROUP_ID, groupId.getBytes());
startActivityForResult(i3, REQUEST_GROUP_INVITE);
return true;
} else if (itemId == R.id.action_group_leave) {
if (isCreator == null || isCreator)
throw new IllegalStateException();
showLeaveGroupDialog();
return true;
} else if (itemId == R.id.action_group_dissolve) {
if (isCreator == null || !isCreator)
throw new IllegalStateException();
showDissolveGroupDialog();
return super.onOptionsItemSelected(item);
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onActivityResult(int request, int result, Intent data) {
protected void onActivityResult(int request, int result,
@Nullable Intent data) {
if (request == REQUEST_GROUP_INVITE && result == RESULT_OK) {
displaySnackbar(R.string.groups_invitation_sent);
} else super.onActivityResult(request, result, data);

View File

@@ -3,7 +3,6 @@ package org.briarproject.briar.android.privategroup.conversation;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.briar.android.controller.handler.ResultExceptionHandler;
import org.briarproject.briar.android.threaded.ThreadListController;
import org.briarproject.briar.api.privategroup.PrivateGroup;
@@ -14,9 +13,6 @@ import androidx.annotation.UiThread;
public interface GroupController
extends ThreadListController<PrivateGroup, GroupMessageItem> {
void loadLocalAuthor(
ResultExceptionHandler<LocalAuthor, DbException> handler);
void isDissolved(
ResultExceptionHandler<Boolean, DbException> handler);

View File

@@ -210,20 +210,6 @@ class GroupControllerImpl extends
return new GroupMessageItem(header, text);
}
@Override
public void loadLocalAuthor(
ResultExceptionHandler<LocalAuthor, DbException> handler) {
runOnDbThread(() -> {
try {
LocalAuthor author = identityManager.getLocalAuthor();
handler.onResult(author);
} catch (DbException e) {
logException(LOG, WARNING, e);
handler.onException(e);
}
});
}
@Override
public void isDissolved(
ResultExceptionHandler<Boolean, DbException> handler) {

View File

@@ -2,13 +2,25 @@ package org.briarproject.briar.android.privategroup.conversation;
import org.briarproject.briar.android.activity.ActivityScope;
import org.briarproject.briar.android.activity.BaseActivity;
import org.briarproject.briar.android.viewmodel.ViewModelKey;
import androidx.lifecycle.ViewModel;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoMap;
@Module
public class GroupConversationModule {
@Module
public interface BindsModule {
@Binds
@IntoMap
@ViewModelKey(GroupViewModel.class)
ViewModel bindGroupViewModel(GroupViewModel groupViewModel);
}
@ActivityScope
@Provides
GroupController provideGroupController(BaseActivity activity,

View File

@@ -0,0 +1,102 @@
package org.briarproject.briar.android.privategroup.conversation;
import android.app.Application;
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.TransactionManager;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.briar.android.threaded.ThreadListViewModel;
import org.briarproject.briar.api.android.AndroidNotificationManager;
import org.briarproject.briar.api.privategroup.GroupMessageFactory;
import org.briarproject.briar.api.privategroup.PrivateGroup;
import org.briarproject.briar.api.privategroup.PrivateGroupManager;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
import javax.inject.Inject;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.LogUtils.logException;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
class GroupViewModel
extends ThreadListViewModel<PrivateGroup, GroupMessageItem> {
private static final Logger LOG = getLogger(GroupViewModel.class.getName());
private final PrivateGroupManager privateGroupManager;
private final GroupMessageFactory groupMessageFactory;
MutableLiveData<PrivateGroup> privateGroup = new MutableLiveData<>();
MutableLiveData<Boolean> isCreator = new MutableLiveData<>();
@Inject
GroupViewModel(Application application,
@DatabaseExecutor Executor dbExecutor,
LifecycleManager lifecycleManager,
TransactionManager db,
AndroidExecutor androidExecutor,
EventBus eventBus,
IdentityManager identityManager,
AndroidNotificationManager notificationManager,
@CryptoExecutor Executor cryptoExecutor,
Clock clock,
PrivateGroupManager privateGroupManager,
GroupMessageFactory groupMessageFactory) {
super(application, dbExecutor, lifecycleManager, db, androidExecutor,
identityManager, notificationManager, cryptoExecutor, clock,
eventBus);
this.privateGroupManager = privateGroupManager;
this.groupMessageFactory = groupMessageFactory;
}
@Override
public void eventOccurred(Event e) {
}
@Override
public void setGroupId(GroupId groupId) {
super.setGroupId(groupId);
loadPrivateGroup(groupId);
}
private void loadPrivateGroup(GroupId groupId) {
runOnDbThread(() -> {
try {
PrivateGroup g = privateGroupManager.getPrivateGroup(groupId);
privateGroup.postValue(g);
Author author = identityManager.getLocalAuthor();
isCreator.postValue(g.getCreator().equals(author));
} catch (DbException e) {
logException(LOG, WARNING, e);
}
});
}
LiveData<PrivateGroup> getPrivateGroup() {
return privateGroup;
}
LiveData<Boolean> isCreator() {
return isCreator;
}
}

View File

@@ -39,11 +39,11 @@ import javax.inject.Inject;
import androidx.annotation.CallSuper;
import androidx.annotation.StringRes;
import androidx.annotation.UiThread;
import androidx.appcompat.app.ActionBar;
import androidx.recyclerview.widget.LinearLayoutManager;
import static androidx.recyclerview.widget.RecyclerView.NO_POSITION;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
@MethodsNotNullByDefault
@@ -56,7 +56,7 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
protected static final String KEY_REPLY_ID = "replyId";
private static final Logger LOG =
Logger.getLogger(ThreadListActivity.class.getName());
getLogger(ThreadListActivity.class.getName());
protected A adapter;
private ThreadScrollListener<I> scrollListener;
@@ -72,6 +72,8 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
protected abstract ThreadListController<G, I> getController();
protected abstract ThreadListViewModel<G, I> getViewModel();
@Inject
protected SharingController sharingController;
@@ -87,6 +89,7 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
if (b == null) throw new IllegalStateException("No GroupId in intent.");
groupId = new GroupId(b);
getController().setGroupId(groupId);
getViewModel().setGroupId(groupId);
textInput = findViewById(R.id.text_input_container);
sendController = new TextSendController(textInput, this, false);
@@ -142,24 +145,6 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
protected abstract A createAdapter(LinearLayoutManager layoutManager);
protected void loadNamedGroup() {
getController().loadNamedGroup(
new UiResultExceptionHandler<G, DbException>(this) {
@Override
public void onResultUi(G groupItem) {
onNamedGroupLoaded(groupItem);
}
@Override
public void onExceptionUi(DbException exception) {
handleException(exception);
}
});
}
@UiThread
protected abstract void onNamedGroupLoaded(G groupItem);
protected void loadItems() {
int revision = adapter.getRevision();
getController().loadItems(
@@ -256,13 +241,11 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
supportFinishAfterTransition();
return true;
default:
return super.onOptionsItemSelected(item);
if (item.getItemId() == android.R.id.home) {
supportFinishAfterTransition();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override

View File

@@ -22,8 +22,6 @@ public interface ThreadListController<G extends NamedGroup, I extends ThreadItem
void setGroupId(GroupId groupId);
void loadNamedGroup(ResultExceptionHandler<G, DbException> handler);
void loadSharingContacts(
ResultExceptionHandler<Collection<ContactId>, DbException> handler);

View File

@@ -130,23 +130,6 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
}
}
@Override
public void loadNamedGroup(
ResultExceptionHandler<G, DbException> handler) {
checkGroupId();
runOnDbThread(() -> {
try {
long start = now();
G groupItem = loadNamedGroup();
logDuration(LOG, "Loading group", start);
handler.onResult(groupItem);
} catch (DbException e) {
logException(LOG, WARNING, e);
handler.onException(e);
}
});
}
@DatabaseExecutor
protected abstract G loadNamedGroup() throws DbException;

View File

@@ -0,0 +1,79 @@
package org.briarproject.briar.android.threaded;
import android.app.Application;
import org.briarproject.bramble.api.crypto.CryptoExecutor;
import org.briarproject.bramble.api.db.DatabaseExecutor;
import org.briarproject.bramble.api.db.TransactionManager;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.event.EventListener;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.briar.android.viewmodel.DbViewModel;
import org.briarproject.briar.api.android.AndroidNotificationManager;
import org.briarproject.briar.api.client.NamedGroup;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
import androidx.annotation.CallSuper;
import static java.util.logging.Logger.getLogger;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public abstract class ThreadListViewModel<G extends NamedGroup, I extends ThreadItem>
extends DbViewModel implements EventListener {
private static final Logger LOG =
getLogger(ThreadListViewModel.class.getName());
protected final IdentityManager identityManager;
protected final AndroidNotificationManager notificationManager;
protected final Executor cryptoExecutor;
protected final Clock clock;
private final EventBus eventBus;
protected volatile GroupId groupId;
public ThreadListViewModel(Application application,
@DatabaseExecutor Executor dbExecutor,
LifecycleManager lifecycleManager,
TransactionManager db,
AndroidExecutor androidExecutor,
IdentityManager identityManager,
AndroidNotificationManager notificationManager,
@CryptoExecutor Executor cryptoExecutor,
Clock clock,
EventBus eventBus) {
super(application, dbExecutor, lifecycleManager, db, androidExecutor);
this.identityManager = identityManager;
this.notificationManager = notificationManager;
this.cryptoExecutor = cryptoExecutor;
this.clock = clock;
this.eventBus = eventBus;
this.eventBus.addListener(this);
}
@Override
protected void onCleared() {
super.onCleared();
eventBus.removeListener(this);
}
/**
* Needs to be called right after initialization,
* before calling other methods.
*/
@CallSuper
public void setGroupId(GroupId groupId) {
this.groupId = groupId;
}
}