From b0a5a69b818d24fc5d9905495e95934e43f2ca10 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Wed, 26 Oct 2016 18:19:02 -0200 Subject: [PATCH 1/2] Remove group from database in PrivateGroupManager --- .../org/briarproject/privategroup/PrivateGroupManagerImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/briar-core/src/org/briarproject/privategroup/PrivateGroupManagerImpl.java b/briar-core/src/org/briarproject/privategroup/PrivateGroupManagerImpl.java index 7a623419e..a8a867de1 100644 --- a/briar-core/src/org/briarproject/privategroup/PrivateGroupManagerImpl.java +++ b/briar-core/src/org/briarproject/privategroup/PrivateGroupManagerImpl.java @@ -138,12 +138,13 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements @Override public void removePrivateGroup(GroupId g) throws DbException { - // TODO Transaction txn = db.startTransaction(false); try { for (PrivateGroupHook hook : hooks) { hook.removingGroup(txn, g); } + Group group = db.getGroup(txn, g); + db.removeGroup(txn, group); txn.setComplete(); } finally { db.endTransaction(txn); From 8dac2d1ca6f5a2ba54fabd2a8a111d5712c21495 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Wed, 26 Oct 2016 18:43:41 -0200 Subject: [PATCH 2/2] Implement UI for dissolving and leaving group --- briar-android/res/menu/group_actions.xml | 3 - briar-android/res/values/strings.xml | 5 ++ .../android/forum/ForumActivity.java | 8 +- .../conversation/GroupActivity.java | 85 ++++++++++++++++++- .../conversation/GroupController.java | 5 ++ .../conversation/GroupControllerImpl.java | 21 +++++ .../threaded/ThreadListControllerImpl.java | 10 +-- 7 files changed, 123 insertions(+), 14 deletions(-) diff --git a/briar-android/res/menu/group_actions.xml b/briar-android/res/menu/group_actions.xml index 8ebe58a1b..bf575e325 100644 --- a/briar-android/res/menu/group_actions.xml +++ b/briar-android/res/menu/group_actions.xml @@ -25,15 +25,12 @@ diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml index f69c03741..8802b1543 100644 --- a/briar-android/res/values/strings.xml +++ b/briar-android/res/values/strings.xml @@ -163,6 +163,8 @@ Member List Invite Members Leave Group + Confirm Leaving Group + Are you sure that you want to leave this group? Dissolve Group joined the group. @@ -180,6 +182,9 @@ You declined the group invitation from %s. %s accepted your group invitation. %s declined your group invitation. + Confirm Dissolving Group + Are you sure that you want to dissolve this group?\n\nAll other members will not be able to continue their conversation and might not receive the latest messages. + Dissolve You don\'t have any forums yet.\n\nWhy don\'t you create a new one yourself by tapping the + icon at the top?\n\nYou can also ask your contacts to share forums with you. diff --git a/briar-android/src/org/briarproject/android/forum/ForumActivity.java b/briar-android/src/org/briarproject/android/forum/ForumActivity.java index 36d552473..22c713889 100644 --- a/briar-android/src/org/briarproject/android/forum/ForumActivity.java +++ b/briar-android/src/org/briarproject/android/forum/ForumActivity.java @@ -149,11 +149,11 @@ public class ForumActivity extends OnClickListener okListener = new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - deleteNamedGroup(); + deleteForum(); } }; - AlertDialog.Builder builder = new AlertDialog.Builder( - ForumActivity.this, R.style.BriarDialogTheme); + AlertDialog.Builder builder = new AlertDialog.Builder(this, + R.style.BriarDialogTheme); builder.setTitle(getString(R.string.dialog_title_leave_forum)); builder.setMessage(getString(R.string.dialog_message_leave_forum)); builder.setNegativeButton(R.string.dialog_button_leave, okListener); @@ -161,7 +161,7 @@ public class ForumActivity extends builder.show(); } - private void deleteNamedGroup() { + private void deleteForum() { forumController.deleteNamedGroup( new UiResultExceptionHandler(this) { @Override diff --git a/briar-android/src/org/briarproject/android/privategroup/conversation/GroupActivity.java b/briar-android/src/org/briarproject/android/privategroup/conversation/GroupActivity.java index d17ed8d66..14000ec25 100644 --- a/briar-android/src/org/briarproject/android/privategroup/conversation/GroupActivity.java +++ b/briar-android/src/org/briarproject/android/privategroup/conversation/GroupActivity.java @@ -1,10 +1,13 @@ package org.briarproject.android.privategroup.conversation; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.os.Bundle; import android.support.annotation.LayoutRes; import android.support.annotation.StringRes; import android.support.v7.app.ActionBar; +import android.support.v7.app.AlertDialog; import android.support.v7.widget.LinearLayoutManager; import android.view.Menu; import android.view.MenuInflater; @@ -12,8 +15,10 @@ import android.view.MenuItem; import org.briarproject.R; import org.briarproject.android.ActivityComponent; +import org.briarproject.android.controller.handler.UiResultExceptionHandler; import org.briarproject.android.threaded.ThreadListActivity; import org.briarproject.android.threaded.ThreadListController; +import org.briarproject.api.db.DbException; import org.briarproject.api.privategroup.GroupMessageHeader; import org.briarproject.api.privategroup.PrivateGroup; @@ -22,11 +27,16 @@ import javax.inject.Inject; import static org.briarproject.api.privategroup.PrivateGroupConstants.MAX_GROUP_POST_BODY_LENGTH; public class GroupActivity extends - ThreadListActivity { + ThreadListActivity + implements OnClickListener { @Inject GroupController controller; + private boolean isCreator; + private MenuItem leaveMenuItem; + private MenuItem dissolveMenuItem; + @Override public void injectActivity(ActivityComponent component) { component.inject(this); @@ -58,6 +68,20 @@ public class GroupActivity extends actionBar.setSubtitle(getString(R.string.groups_created_by, group.getAuthor().getName())); } + controller.isCreator(group, + new UiResultExceptionHandler(this) { + @Override + public void onResultUi(Boolean isCreator) { + GroupActivity.this.isCreator = isCreator; + showMenuItems(); + } + + @Override + public void onExceptionUi(DbException exception) { + // TODO proper error handling + finish(); + } + }); } @Override @@ -78,6 +102,10 @@ public class GroupActivity extends MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.group_actions, menu); + leaveMenuItem = menu.findItem(R.id.action_group_leave); + dissolveMenuItem = menu.findItem(R.id.action_group_dissolve); + showMenuItems(); + return super.onCreateOptionsMenu(menu); } @@ -87,6 +115,12 @@ public class GroupActivity extends case R.id.action_group_compose_message: showTextInput(null); return true; + case R.id.action_group_leave: + showLeaveGroupDialog(); + return true; + case R.id.action_group_dissolve: + showDissolveGroupDialog(); + return true; default: return super.onOptionsItemSelected(item); } @@ -109,4 +143,53 @@ public class GroupActivity extends return R.string.groups_message_received; } + private void showMenuItems() { + if (leaveMenuItem == null || dissolveMenuItem == null) return; + if (isCreator) { + leaveMenuItem.setVisible(false); + dissolveMenuItem.setVisible(true); + } else { + leaveMenuItem.setVisible(true); + dissolveMenuItem.setVisible(false); + } + } + + private void showLeaveGroupDialog() { + AlertDialog.Builder builder = + new AlertDialog.Builder(this, R.style.BriarDialogTheme); + builder.setTitle(getString(R.string.groups_leave_dialog_title)); + builder.setMessage(getString(R.string.groups_leave_dialog_message)); + builder.setNegativeButton(R.string.dialog_button_leave, this); + builder.setPositiveButton(R.string.cancel, null); + builder.show(); + } + + private void showDissolveGroupDialog() { + AlertDialog.Builder builder = + new AlertDialog.Builder(this, R.style.BriarDialogTheme); + builder.setTitle(getString(R.string.groups_dissolve_dialog_title)); + builder.setMessage(getString(R.string.groups_dissolve_dialog_message)); + builder.setNegativeButton(R.string.groups_dissolve_button, this); + builder.setPositiveButton(R.string.cancel, null); + builder.show(); + } + + @Override + public void onClick(DialogInterface dialog, int which) { + controller.deleteNamedGroup( + new UiResultExceptionHandler(this) { + @Override + public void onResultUi(Void v) { + // The activity is going to be destroyed by the + // GroupRemovedEvent being fired + } + + @Override + public void onExceptionUi(DbException exception) { + // TODO proper error handling + finish(); + } + }); + } + } diff --git a/briar-android/src/org/briarproject/android/privategroup/conversation/GroupController.java b/briar-android/src/org/briarproject/android/privategroup/conversation/GroupController.java index 0292f2278..1a2fa951e 100644 --- a/briar-android/src/org/briarproject/android/privategroup/conversation/GroupController.java +++ b/briar-android/src/org/briarproject/android/privategroup/conversation/GroupController.java @@ -1,6 +1,8 @@ package org.briarproject.android.privategroup.conversation; +import org.briarproject.android.controller.handler.ResultExceptionHandler; import org.briarproject.android.threaded.ThreadListController; +import org.briarproject.api.db.DbException; import org.briarproject.api.privategroup.GroupMessageHeader; import org.briarproject.api.privategroup.PrivateGroup; @@ -8,4 +10,7 @@ public interface GroupController extends ThreadListController { + void isCreator(PrivateGroup group, + ResultExceptionHandler handler); + } diff --git a/briar-android/src/org/briarproject/android/privategroup/conversation/GroupControllerImpl.java b/briar-android/src/org/briarproject/android/privategroup/conversation/GroupControllerImpl.java index abbf10d42..df366c675 100644 --- a/briar-android/src/org/briarproject/android/privategroup/conversation/GroupControllerImpl.java +++ b/briar-android/src/org/briarproject/android/privategroup/conversation/GroupControllerImpl.java @@ -30,6 +30,7 @@ import java.util.logging.Logger; import javax.inject.Inject; import static java.lang.Math.max; + import static java.util.logging.Level.WARNING; public class GroupControllerImpl extends @@ -174,4 +175,24 @@ public class GroupControllerImpl extends return new GroupMessageItem(header, body); } + @Override + public void isCreator(final PrivateGroup group, + final ResultExceptionHandler handler) { + runOnDbThread(new Runnable() { + @Override + public void run() { + try { + LocalAuthor author = identityManager.getLocalAuthor(); + boolean isCreator = + author.getId().equals(group.getAuthor().getId()); + handler.onResult(isCreator); + } catch (DbException e) { + if (LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + handler.onException(e); + } + } + }); + } + } diff --git a/briar-android/src/org/briarproject/android/threaded/ThreadListControllerImpl.java b/briar-android/src/org/briarproject/android/threaded/ThreadListControllerImpl.java index 6ea72c892..018188a48 100644 --- a/briar-android/src/org/briarproject/android/threaded/ThreadListControllerImpl.java +++ b/briar-android/src/org/briarproject/android/threaded/ThreadListControllerImpl.java @@ -41,16 +41,14 @@ public abstract class ThreadListControllerImpl bodyCache = new ConcurrentHashMap<>(); - private volatile GroupId groupId; + protected final IdentityManager identityManager; + protected final AndroidNotificationManager notificationManager; + protected final Executor cryptoExecutor; + protected final Clock clock; protected volatile ThreadListListener listener; protected ThreadListControllerImpl(@DatabaseExecutor Executor dbExecutor,