From abfff10f6bdb057265799d7f632d0682502a47fb Mon Sep 17 00:00:00 2001
From: akwizgran <akwizgran@users.sourceforge.net>
Date: Mon, 17 Mar 2014 14:49:11 +0000
Subject: [PATCH] Contacts a forum is already shared with should be selected.
 Dev task #79

---
 .../android/contact/SelectContactsDialog.java | 30 ++++--
 .../groups/ConfigureGroupActivity.java        | 40 ++++----
 .../android/groups/CreateGroupActivity.java   | 98 +++++++++----------
 .../identity/CreateIdentityActivity.java      | 23 ++---
 4 files changed, 101 insertions(+), 90 deletions(-)

diff --git a/briar-android/src/org/briarproject/android/contact/SelectContactsDialog.java b/briar-android/src/org/briarproject/android/contact/SelectContactsDialog.java
index c717c7732b..24ed0a8a64 100644
--- a/briar-android/src/org/briarproject/android/contact/SelectContactsDialog.java
+++ b/briar-android/src/org/briarproject/android/contact/SelectContactsDialog.java
@@ -1,7 +1,9 @@
 package org.briarproject.android.contact;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 import org.briarproject.R;
@@ -17,27 +19,35 @@ import android.support.v4.app.DialogFragment;
 public class SelectContactsDialog extends DialogFragment
 implements DialogInterface.OnMultiChoiceClickListener {
 
-	private final Set<ContactId> selected = new HashSet<ContactId>();
-
 	private Listener listener = null;
-	private Contact[] contacts = null;
+	private List<Contact> contacts = null;
+	private Set<ContactId> selected = null;
 
 	public void setListener(Listener listener) {
 		this.listener = listener;
 	}
 
 	public void setContacts(Collection<Contact> contacts) {
-		this.contacts = contacts.toArray(new Contact[contacts.size()]);
+		this.contacts = new ArrayList<Contact>(contacts);
+	}
+
+	public void setSelected(Collection<ContactId> selected) {
+		this.selected = new HashSet<ContactId>(selected);
 	}
 
 	@Override
 	public Dialog onCreateDialog(Bundle state) {
 		if(listener == null || contacts == null) return null;
 		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-		String[] names = new String[contacts.length];
-		for(int i = 0; i < contacts.length; i++)
-			names[i] = contacts[i].getAuthor().getName();
-		builder.setMultiChoiceItems(names, new boolean[contacts.length], this);
+		int size = contacts.size();
+		String[] names = new String[size];
+		boolean[] checked = new boolean[size];
+		for(int i = 0; i < size; i++) {
+			Contact c = contacts.get(i);
+			names[i] = c.getAuthor().getName();
+			checked[i] = selected.contains(c.getId());
+		}
+		builder.setMultiChoiceItems(names, checked, this);
 		builder.setPositiveButton(R.string.done_button,
 				new DialogInterface.OnClickListener() {
 			public void onClick(DialogInterface dialog, int id) {
@@ -54,8 +64,8 @@ implements DialogInterface.OnMultiChoiceClickListener {
 	}
 
 	public void onClick(DialogInterface dialog, int which, boolean isChecked) {
-		if(isChecked) selected.add(contacts[which].getId());
-		else selected.remove(contacts[which].getId());
+		if(isChecked) selected.add(contacts.get(which).getId());
+		else selected.remove(contacts.get(which).getId());
 	}
 
 	public interface Listener {
diff --git a/briar-android/src/org/briarproject/android/groups/ConfigureGroupActivity.java b/briar-android/src/org/briarproject/android/groups/ConfigureGroupActivity.java
index 711bef6b49..c77fac632f 100644
--- a/briar-android/src/org/briarproject/android/groups/ConfigureGroupActivity.java
+++ b/briar-android/src/org/briarproject/android/groups/ConfigureGroupActivity.java
@@ -47,7 +47,6 @@ SelectContactsDialog.Listener {
 	private static final Logger LOG =
 			Logger.getLogger(ConfigureGroupActivity.class.getName());
 
-	private boolean subscribed = false;
 	private CheckBox subscribeCheckBox = null;
 	private RadioGroup radioGroup = null;
 	private RadioButton visibleToAll = null, visibleToSome = null;
@@ -58,8 +57,11 @@ SelectContactsDialog.Listener {
 
 	// Fields that are accessed from background threads must be volatile
 	@Inject private volatile DatabaseComponent db;
+	private volatile GroupId groupId = null;
 	private volatile Group group = null;
-	private volatile Collection<ContactId> selected = Collections.emptyList();
+	private volatile boolean subscribed = false;
+	private volatile Collection<Contact> contacts = null;
+	private volatile Collection<ContactId> selected = null;
 
 	@Override
 	public void onCreate(Bundle state) {
@@ -68,13 +70,13 @@ SelectContactsDialog.Listener {
 		Intent i = getIntent();
 		byte[] b = i.getByteArrayExtra("briar.GROUP_ID");
 		if(b == null) throw new IllegalStateException();
-		GroupId id = new GroupId(b);
+		groupId = new GroupId(b);
 		String name = i.getStringExtra("briar.GROUP_NAME");
 		if(name == null) throw new IllegalStateException();
 		setTitle(name);
 		b = i.getByteArrayExtra("briar.GROUP_SALT");
 		if(b == null) throw new IllegalStateException();
-		group = new Group(id, name, b);
+		group = new Group(groupId, name, b);
 		subscribed = i.getBooleanExtra("briar.SUBSCRIBED", false);
 		boolean all = i.getBooleanExtra("briar.VISIBLE_TO_ALL", false);
 
@@ -145,18 +147,16 @@ SelectContactsDialog.Listener {
 			visibleToAll.setEnabled(subscribe);
 			visibleToSome.setEnabled(subscribe);
 		} else if(view == visibleToSome) {
-			loadContacts();
+			if(contacts == null) loadContacts();
+			else displayContacts();
 		} else if(view == doneButton) {
 			boolean subscribe = subscribeCheckBox.isChecked();
 			boolean all = visibleToAll.isChecked();
-			Collection<ContactId> visible =
-					Collections.unmodifiableCollection(selected);
 			// Replace the button with a progress bar
 			doneButton.setVisibility(GONE);
 			progress.setVisibility(VISIBLE);
 			// Update the blog in a background thread
-			if(subscribe || subscribed)
-				updateGroup(subscribe, subscribed, all, visible);
+			if(subscribe || subscribed) updateGroup(subscribe, all);
 		}
 	}
 
@@ -165,11 +165,12 @@ SelectContactsDialog.Listener {
 			public void run() {
 				try {
 					long now = System.currentTimeMillis();
-					Collection<Contact> contacts = db.getContacts();
+					contacts = db.getContacts();
+					selected = db.getVisibility(groupId);
 					long duration = System.currentTimeMillis() - now;
 					if(LOG.isLoggable(INFO))
 						LOG.info("Load took " + duration + " ms");
-					displayContacts(contacts);
+					displayContacts();
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
@@ -178,7 +179,7 @@ SelectContactsDialog.Listener {
 		});
 	}
 
-	private void displayContacts(final Collection<Contact> contacts) {
+	private void displayContacts() {
 		runOnUiThread(new Runnable() {
 			public void run() {
 				FragmentManager fm = getSupportFragmentManager();
@@ -186,24 +187,23 @@ SelectContactsDialog.Listener {
 					noContactsDialog.show(fm, "NoContactsDialog");
 				} else {
 					selectContactsDialog.setContacts(contacts);
+					selectContactsDialog.setSelected(selected);
 					selectContactsDialog.show(fm, "SelectContactsDialog");
 				}
 			}
 		});
 	}
 
-	private void updateGroup(final boolean subscribe,
-			final boolean wasSubscribed, final boolean all,
-			final Collection<ContactId> visible) {
+	private void updateGroup(final boolean subscribe, final boolean all) {
 		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
 					long now = System.currentTimeMillis();
 					if(subscribe) {
-						if(!wasSubscribed) db.addGroup(group);
-						db.setVisibleToAll(group.getId(), all);
-						if(!all) db.setVisibility(group.getId(), visible);
-					} else if(wasSubscribed) {
+						if(!subscribed) db.addGroup(group);
+						db.setVisibleToAll(groupId, all);
+						if(!all) db.setVisibility(groupId, selected);
+					} else if(subscribed) {
 						db.removeGroup(group);
 					}
 					long duration = System.currentTimeMillis() - now;
@@ -225,7 +225,7 @@ SelectContactsDialog.Listener {
 	public void contactCreationCancelled() {}
 
 	public void contactsSelected(Collection<ContactId> selected) {
-		this.selected = selected;
+		this.selected = Collections.unmodifiableCollection(selected);
 	}
 
 	public void contactSelectionCancelled() {}
diff --git a/briar-android/src/org/briarproject/android/groups/CreateGroupActivity.java b/briar-android/src/org/briarproject/android/groups/CreateGroupActivity.java
index 860f6013cb..bbe56e351c 100644
--- a/briar-android/src/org/briarproject/android/groups/CreateGroupActivity.java
+++ b/briar-android/src/org/briarproject/android/groups/CreateGroupActivity.java
@@ -70,7 +70,8 @@ SelectContactsDialog.Listener {
 	// Fields that are accessed from background threads must be volatile
 	@Inject private volatile GroupFactory groupFactory;
 	@Inject private volatile DatabaseComponent db;
-	private volatile Collection<ContactId> selected = Collections.emptyList();
+	private volatile Collection<Contact> contacts = null;
+	private volatile Collection<ContactId> selected = Collections.emptySet();
 
 	@Override
 	public void onCreate(Bundle state) {
@@ -144,115 +145,114 @@ SelectContactsDialog.Listener {
 	}
 
 	private void enableOrDisableCreateButton() {
-		if(nameEntry == null || radioGroup == null || createButton == null)
-			return; // Activity not created yet
+		if(createButton == null) return; // Activity not created yet
 		boolean nameNotEmpty = nameEntry.getText().length() > 0;
 		boolean visibilitySelected = radioGroup.getCheckedRadioButtonId() != -1;
 		createButton.setEnabled(nameNotEmpty && visibilitySelected);
 	}
 
+	// FIXME: What is this for?
 	public boolean onEditorAction(TextView textView, int actionId, KeyEvent e) {
 		validateName();
 		return true;
 	}
 
+	private boolean validateName() {
+		if(nameEntry.getText().length() == 0) return false;
+		byte[] b = StringUtils.toUtf8(nameEntry.getText().toString());
+		if(b.length > MAX_GROUP_NAME_LENGTH) return false;
+		// Hide the soft keyboard
+		Object o = getSystemService(INPUT_METHOD_SERVICE);
+		((InputMethodManager) o).toggleSoftInput(HIDE_IMPLICIT_ONLY, 0);
+		return true;
+	}
+
 	public void onClick(View view) {
 		if(view == visibleToAll) {
 			enableOrDisableCreateButton();
 		} else if(view == visibleToSome) {
-			loadContacts();
+			if(contacts == null) loadContacts();
+			else displayContacts();
 		} else if(view == createButton) {
-			if(!validateName()) return;
+			if(!validateName()) return; // FIXME: Show feedback
 			createButton.setVisibility(GONE);
 			progress.setVisibility(VISIBLE);
 			String name = nameEntry.getText().toString();
 			boolean all = visibleToAll.isChecked();
-			Collection<ContactId> visible =
-					Collections.unmodifiableCollection(selected);
-			storeGroup(name, all, visible);
+			storeGroup(name, all);
 		}
 	}
 
-	private void storeGroup(final String name, final boolean all,
-			final Collection<ContactId> visible) {
+	private void loadContacts() {
 		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					Group g = groupFactory.createGroup(name);
 					long now = System.currentTimeMillis();
-					db.addGroup(g);
-					if(all) db.setVisibleToAll(g.getId(), true);
-					else db.setVisibility(g.getId(), visible);
+					contacts = db.getContacts();
 					long duration = System.currentTimeMillis() - now;
 					if(LOG.isLoggable(INFO))
-						LOG.info("Storing group took " + duration + " ms");
-					displayGroup(g);
+						LOG.info("Load took " + duration + " ms");
+					displayContacts();
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-					finishOnUiThread();
 				}
 			}
 		});
 	}
 
-	private void displayGroup(final Group g) {
+	private void displayContacts() {
 		runOnUiThread(new Runnable() {
 			public void run() {
-				Intent i = new Intent(CreateGroupActivity.this,
-						GroupActivity.class);
-				i.putExtra("briar.GROUP_ID", g.getId().getBytes());
-				i.putExtra("briar.GROUP_NAME", g.getName());
-				startActivity(i);
-				Toast.makeText(CreateGroupActivity.this,
-						R.string.forum_created_toast, LENGTH_LONG).show();
-				finish();
+				FragmentManager fm = getSupportFragmentManager();
+				if(contacts.isEmpty()) {
+					noContactsDialog.show(fm, "NoContactsDialog");
+				} else {
+					selectContactsDialog.setContacts(contacts);
+					selectContactsDialog.setSelected(selected);
+					selectContactsDialog.show(fm, "SelectContactsDialog");
+				}
 			}
 		});
 	}
 
-	private void loadContacts() {
+	private void storeGroup(final String name, final boolean all) {
 		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
+					Group g = groupFactory.createGroup(name);
 					long now = System.currentTimeMillis();
-					Collection<Contact> contacts = db.getContacts();
+					db.addGroup(g);
+					if(all) db.setVisibleToAll(g.getId(), true);
+					else db.setVisibility(g.getId(), selected);
 					long duration = System.currentTimeMillis() - now;
 					if(LOG.isLoggable(INFO))
-						LOG.info("Load took " + duration + " ms");
-					displayContacts(contacts);
+						LOG.info("Storing group took " + duration + " ms");
+					displayGroup(g);
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
+					finishOnUiThread();
 				}
 			}
 		});
 	}
 
-	private void displayContacts(final Collection<Contact> contacts) {
+	private void displayGroup(final Group g) {
 		runOnUiThread(new Runnable() {
 			public void run() {
-				FragmentManager fm = getSupportFragmentManager();
-				if(contacts.isEmpty()) {
-					noContactsDialog.show(fm, "NoContactsDialog");
-				} else {
-					selectContactsDialog.setContacts(contacts);
-					selectContactsDialog.show(fm, "SelectContactsDialog");
-				}
+				Intent i = new Intent(CreateGroupActivity.this,
+						GroupActivity.class);
+				i.putExtra("briar.GROUP_ID", g.getId().getBytes());
+				i.putExtra("briar.GROUP_NAME", g.getName());
+				startActivity(i);
+				Toast.makeText(CreateGroupActivity.this,
+						R.string.forum_created_toast, LENGTH_LONG).show();
+				finish();
 			}
 		});
 	}
 
-	private boolean validateName() {
-		if(nameEntry.getText().length() == 0) return false;
-		byte[] b = StringUtils.toUtf8(nameEntry.getText().toString());
-		if(b.length > MAX_GROUP_NAME_LENGTH) return false;
-		// Hide the soft keyboard
-		Object o = getSystemService(INPUT_METHOD_SERVICE);
-		((InputMethodManager) o).toggleSoftInput(HIDE_IMPLICIT_ONLY, 0);
-		return true;
-	}
-
 	public void contactCreationSelected() {
 		startActivity(new Intent(this, AddContactActivity.class));
 	}
@@ -262,7 +262,7 @@ SelectContactsDialog.Listener {
 	}
 
 	public void contactsSelected(Collection<ContactId> selected) {
-		this.selected = selected;
+		this.selected = Collections.unmodifiableCollection(selected);
 		enableOrDisableCreateButton();
 	}
 
diff --git a/briar-android/src/org/briarproject/android/identity/CreateIdentityActivity.java b/briar-android/src/org/briarproject/android/identity/CreateIdentityActivity.java
index 55e40f59a9..dd13578710 100644
--- a/briar-android/src/org/briarproject/android/identity/CreateIdentityActivity.java
+++ b/briar-android/src/org/briarproject/android/identity/CreateIdentityActivity.java
@@ -109,13 +109,24 @@ implements OnEditorActionListener, OnClickListener {
 		setContentView(layout);
 	}
 
+	// FIXME: What is this for?
 	public boolean onEditorAction(TextView textView, int actionId, KeyEvent e) {
 		validateNickname();
 		return true;
 	}
 
+	private boolean validateNickname() {
+		if(nicknameEntry.getText().length() == 0) return false;
+		byte[] b = StringUtils.toUtf8(nicknameEntry.getText().toString());
+		if(b.length > MAX_AUTHOR_NAME_LENGTH) return false;
+		// Hide the soft keyboard
+		Object o = getSystemService(INPUT_METHOD_SERVICE);
+		((InputMethodManager) o).toggleSoftInput(HIDE_IMPLICIT_ONLY, 0);
+		return true;
+	}
+
 	public void onClick(View view) {
-		if(!validateNickname()) return;
+		if(!validateNickname()) return; // FIXME: Show feedback
 		final String nickname = nicknameEntry.getText().toString();
 		// Replace the button with a progress bar
 		createButton.setVisibility(GONE);
@@ -133,16 +144,6 @@ implements OnEditorActionListener, OnClickListener {
 		});
 	}
 
-	private boolean validateNickname() {
-		if(nicknameEntry.getText().length() == 0) return false;
-		byte[] b = StringUtils.toUtf8(nicknameEntry.getText().toString());
-		if(b.length > MAX_AUTHOR_NAME_LENGTH) return false;
-		// Hide the soft keyboard
-		Object o = getSystemService(INPUT_METHOD_SERVICE);
-		((InputMethodManager) o).toggleSoftInput(HIDE_IMPLICIT_ONLY, 0);
-		return true;
-	}
-
 	private void storeLocalAuthor(final LocalAuthor a) {
 		runOnDbThread(new Runnable() {
 			public void run() {
-- 
GitLab