diff --git a/briar-android/src/net/sf/briar/android/contact/ContactListActivity.java b/briar-android/src/net/sf/briar/android/contact/ContactListActivity.java index ef3b7897a8f35d06bf04b5ae4429e0f272ded59a..c08ecde48851b9a974f610387db6b76147b68b21 100644 --- a/briar-android/src/net/sf/briar/android/contact/ContactListActivity.java +++ b/briar-android/src/net/sf/briar/android/contact/ContactListActivity.java @@ -9,8 +9,7 @@ import static java.util.logging.Level.WARNING; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; -import java.util.List; +import java.util.Comparator; import java.util.concurrent.Executor; import java.util.logging.Logger; @@ -21,12 +20,15 @@ import net.sf.briar.android.BriarService.BriarBinder; import net.sf.briar.android.BriarService.BriarServiceConnection; import net.sf.briar.android.invitation.AddContactActivity; import net.sf.briar.api.Contact; +import net.sf.briar.api.ContactId; import net.sf.briar.api.db.DatabaseComponent; import net.sf.briar.api.db.DatabaseExecutor; import net.sf.briar.api.db.DbException; import net.sf.briar.api.db.event.ContactAddedEvent; import net.sf.briar.api.db.event.DatabaseEvent; import net.sf.briar.api.db.event.DatabaseListener; +import net.sf.briar.api.transport.ConnectionListener; +import net.sf.briar.api.transport.ConnectionRegistry; import android.content.Intent; import android.os.Bundle; import android.os.IBinder; @@ -41,18 +43,20 @@ import android.widget.RelativeLayout.LayoutParams; import com.google.inject.Inject; public class ContactListActivity extends BriarActivity -implements OnClickListener, DatabaseListener { +implements OnClickListener, DatabaseListener, ConnectionListener { private static final Logger LOG = Logger.getLogger(ContactListActivity.class.getName()); + private static final ItemComparator COMPARATOR = new ItemComparator(); private final BriarServiceConnection serviceConnection = new BriarServiceConnection(); @Inject private DatabaseComponent db; @Inject @DatabaseExecutor private Executor dbExecutor; + @Inject private ConnectionRegistry connectionRegistry; - private ArrayAdapter<String> adapter = null; + private ArrayAdapter<ContactListItem> adapter = null; @Override public void onCreate(Bundle state) { @@ -63,9 +67,9 @@ implements OnClickListener, DatabaseListener { layout.setOrientation(VERTICAL); layout.setGravity(CENTER_HORIZONTAL); - adapter = new ArrayAdapter<String>(this, + adapter = new ArrayAdapter<ContactListItem>(this, android.R.layout.simple_expandable_list_item_1, - new ArrayList<String>()); + new ArrayList<ContactListItem>()); ListView listView = new ListView(this); listView.setAdapter(adapter); layout.addView(listView); @@ -80,9 +84,10 @@ implements OnClickListener, DatabaseListener { layout.addView(addContactButton); setContentView(layout); - - // Listen for database events + + // Listen for database events and connection events db.addListener(this); + connectionRegistry.addListener(this); // Bind to the service bindService(new Intent(BriarService.class.getName()), @@ -118,6 +123,8 @@ implements OnClickListener, DatabaseListener { @Override public void onDestroy() { super.onDestroy(); + db.removeListener(this); + connectionRegistry.removeListener(this); unbindService(serviceConnection); } @@ -140,7 +147,7 @@ implements OnClickListener, DatabaseListener { final Collection<Contact> contacts = db.getContacts(); if(LOG.isLoggable(INFO)) LOG.info("Loaded " + contacts.size() + " contacts"); - // Update the contact list on the UI thread + // Update the contact list runOnUiThread(new Runnable() { public void run() { updateContactList(contacts); @@ -158,11 +165,61 @@ implements OnClickListener, DatabaseListener { }); } + // UI thread private void updateContactList(Collection<Contact> contacts) { - List<String> names = new ArrayList<String>(contacts.size()); - for(Contact c : contacts) names.add(c.getName()); - Collections.sort(names); adapter.clear(); - for(String name : names) adapter.add(name); + for(Contact c : contacts) { + boolean connected = connectionRegistry.isConnected(c.getId()); + adapter.add(new ContactListItem(c, connected)); + } + adapter.sort(COMPARATOR); + } + + public void contactConnected(final ContactId c) { + setConnected(c, true); + } + + public void contactDisconnected(ContactId c) { + setConnected(c, false); + } + + private void setConnected(final ContactId c, final boolean connected) { + runOnUiThread(new Runnable() { + public void run() { + int count = adapter.getCount(); + for(int i = 0; i < count; i++) { + ContactListItem item = adapter.getItem(i); + if(item.contact.getId().equals(c)) { + item.connected = connected; + return; + } + } + } + }); + } + + private static class ItemComparator implements Comparator<ContactListItem> { + + @Override + public int compare(ContactListItem a, ContactListItem b) { + return String.CASE_INSENSITIVE_ORDER.compare(a.contact.getName(), + b.contact.getName()); + } + } + + private static class ContactListItem { + + private final Contact contact; + private boolean connected; // UI thread + + private ContactListItem(Contact contact, boolean connected) { + this.contact = contact; + this.connected = connected; + } + + @Override + public String toString() { + return contact.getName() + " (" + connected + ")"; + } } }