ContactDetailsActivity.java

  1package eu.siacs.conversations.ui;
  2
  3import java.util.Iterator;
  4
  5import org.openintents.openpgp.util.OpenPgpUtils;
  6
  7import android.app.AlertDialog;
  8import android.app.PendingIntent;
  9import android.content.Context;
 10import android.content.DialogInterface;
 11import android.content.Intent;
 12import android.content.IntentSender.SendIntentException;
 13import android.net.Uri;
 14import android.os.Bundle;
 15import android.provider.ContactsContract.CommonDataKinds;
 16import android.provider.ContactsContract.Contacts;
 17import android.provider.ContactsContract.Intents;
 18import android.view.LayoutInflater;
 19import android.view.Menu;
 20import android.view.MenuItem;
 21import android.view.View;
 22import android.view.View.OnClickListener;
 23import android.widget.CheckBox;
 24import android.widget.CompoundButton.OnCheckedChangeListener;
 25import android.widget.CompoundButton;
 26import android.widget.LinearLayout;
 27import android.widget.QuickContactBadge;
 28import android.widget.TextView;
 29import eu.siacs.conversations.R;
 30import eu.siacs.conversations.crypto.PgpEngine;
 31import eu.siacs.conversations.entities.Account;
 32import eu.siacs.conversations.entities.Contact;
 33import eu.siacs.conversations.entities.Presences;
 34import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
 35import eu.siacs.conversations.utils.UIHelper;
 36
 37public class ContactDetailsActivity extends XmppActivity {
 38	public static final String ACTION_VIEW_CONTACT = "view_contact";
 39
 40	protected ContactDetailsActivity activity = this;
 41
 42	private Contact contact;
 43
 44	private String accountJid;
 45	private String contactJid;
 46
 47	private TextView contactJidTv;
 48	private TextView accountJidTv;
 49	private TextView status;
 50	private TextView lastseen;
 51	private CheckBox send;
 52	private CheckBox receive;
 53	private QuickContactBadge badge;
 54
 55	private DialogInterface.OnClickListener removeFromRoster = new DialogInterface.OnClickListener() {
 56
 57		@Override
 58		public void onClick(DialogInterface dialog, int which) {
 59			activity.xmppConnectionService.deleteContactOnServer(contact);
 60			activity.finish();
 61		}
 62	};
 63
 64	private DialogInterface.OnClickListener addToPhonebook = new DialogInterface.OnClickListener() {
 65
 66		@Override
 67		public void onClick(DialogInterface dialog, int which) {
 68			Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
 69			intent.setType(Contacts.CONTENT_ITEM_TYPE);
 70			intent.putExtra(Intents.Insert.IM_HANDLE, contact.getJid());
 71			intent.putExtra(Intents.Insert.IM_PROTOCOL,
 72					CommonDataKinds.Im.PROTOCOL_JABBER);
 73			intent.putExtra("finishActivityOnSaveCompleted", true);
 74			activity.startActivityForResult(intent, 0);
 75		}
 76	};
 77	private OnClickListener onBadgeClick = new OnClickListener() {
 78
 79		@Override
 80		public void onClick(View v) {
 81			AlertDialog.Builder builder = new AlertDialog.Builder(activity);
 82			builder.setTitle(getString(R.string.action_add_phone_book));
 83			builder.setMessage(getString(R.string.add_phone_book_text,
 84					contact.getJid()));
 85			builder.setNegativeButton(getString(R.string.cancel), null);
 86			builder.setPositiveButton(getString(R.string.add), addToPhonebook);
 87			builder.create().show();
 88		}
 89	};
 90
 91	private LinearLayout keys;
 92
 93	private OnRosterUpdate rosterUpdate = new OnRosterUpdate() {
 94
 95		@Override
 96		public void onRosterUpdate() {
 97			runOnUiThread(new Runnable() {
 98
 99				@Override
100				public void run() {
101					populateView();
102				}
103			});
104		}
105	};
106
107	private OnCheckedChangeListener mOnSendCheckedChange = new OnCheckedChangeListener() {
108
109		@Override
110		public void onCheckedChanged(CompoundButton buttonView,
111				boolean isChecked) {
112			if (isChecked) {
113				if (contact.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) {
114					xmppConnectionService.sendPresencePacket(contact
115							.getAccount(),
116							xmppConnectionService.getPresenceGenerator()
117									.sendPresenceUpdatesTo(contact));
118				} else {
119					contact.setOption(Contact.Options.PREEMPTIVE_GRANT);
120				}
121			} else {
122				contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
123				xmppConnectionService.sendPresencePacket(contact.getAccount(),
124						xmppConnectionService.getPresenceGenerator()
125								.stopPresenceUpdatesTo(contact));
126			}
127		}
128	};
129
130	private OnCheckedChangeListener mOnReceiveCheckedChange = new OnCheckedChangeListener() {
131
132		@Override
133		public void onCheckedChanged(CompoundButton buttonView,
134				boolean isChecked) {
135			if (isChecked) {
136				xmppConnectionService.sendPresencePacket(contact.getAccount(),
137						xmppConnectionService.getPresenceGenerator()
138								.requestPresenceUpdatesFrom(contact));
139			} else {
140				xmppConnectionService.sendPresencePacket(contact.getAccount(),
141						xmppConnectionService.getPresenceGenerator()
142								.stopPresenceUpdatesFrom(contact));
143			}
144		}
145	};
146
147	@Override
148	protected void onCreate(Bundle savedInstanceState) {
149		super.onCreate(savedInstanceState);
150		if (getIntent().getAction().equals(ACTION_VIEW_CONTACT)) {
151			this.accountJid = getIntent().getExtras().getString("account");
152			this.contactJid = getIntent().getExtras().getString("contact");
153		}
154		setContentView(R.layout.activity_contact_details);
155
156		contactJidTv = (TextView) findViewById(R.id.details_contactjid);
157		accountJidTv = (TextView) findViewById(R.id.details_account);
158		status = (TextView) findViewById(R.id.details_contactstatus);
159		lastseen = (TextView) findViewById(R.id.details_lastseen);
160		send = (CheckBox) findViewById(R.id.details_send_presence);
161		send.setOnCheckedChangeListener(this.mOnSendCheckedChange);
162		receive = (CheckBox) findViewById(R.id.details_receive_presence);
163		receive.setOnCheckedChangeListener(this.mOnReceiveCheckedChange);
164		badge = (QuickContactBadge) findViewById(R.id.details_contact_badge);
165		keys = (LinearLayout) findViewById(R.id.details_contact_keys);
166		getActionBar().setHomeButtonEnabled(true);
167		getActionBar().setDisplayHomeAsUpEnabled(true);
168
169	}
170
171	@Override
172	public boolean onOptionsItemSelected(MenuItem menuItem) {
173		AlertDialog.Builder builder = new AlertDialog.Builder(this);
174		builder.setNegativeButton(getString(R.string.cancel), null);
175		switch (menuItem.getItemId()) {
176		case android.R.id.home:
177			finish();
178			break;
179		case R.id.action_delete_contact:
180			builder.setTitle(getString(R.string.action_delete_contact))
181					.setMessage(
182							getString(R.string.remove_contact_text,
183									contact.getJid()))
184					.setPositiveButton(getString(R.string.delete),
185							removeFromRoster).create().show();
186			break;
187		case R.id.action_edit_contact:
188			if (contact.getSystemAccount() == null) {
189				quickEdit(contact.getDisplayName(), new OnValueEdited() {
190
191					@Override
192					public void onValueEdited(String value) {
193						contact.setServerName(value);
194						activity.xmppConnectionService
195								.pushContactToServer(contact);
196						populateView();
197					}
198				});
199			} else {
200				Intent intent = new Intent(Intent.ACTION_EDIT);
201				String[] systemAccount = contact.getSystemAccount().split("#");
202				long id = Long.parseLong(systemAccount[0]);
203				Uri uri = Contacts.getLookupUri(id, systemAccount[1]);
204				intent.setDataAndType(uri, Contacts.CONTENT_ITEM_TYPE);
205				intent.putExtra("finishActivityOnSaveCompleted", true);
206				startActivity(intent);
207			}
208			break;
209		}
210		return super.onOptionsItemSelected(menuItem);
211	}
212
213	@Override
214	public boolean onCreateOptionsMenu(Menu menu) {
215		getMenuInflater().inflate(R.menu.contact_details, menu);
216		return true;
217	}
218
219	private void populateView() {
220		setTitle(contact.getDisplayName());
221		if (contact.getOption(Contact.Options.FROM)) {
222			send.setText(R.string.send_presence_updates);
223			send.setChecked(true);
224		} else if (contact
225				.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) {
226			send.setChecked(false);
227			send.setText(R.string.send_presence_updates);
228		} else {
229			send.setText(R.string.preemptively_grant);
230			if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) {
231				send.setChecked(true);
232			} else {
233				send.setChecked(false);
234			}
235		}
236		if (contact.getOption(Contact.Options.TO)) {
237			receive.setText(R.string.receive_presence_updates);
238			receive.setChecked(true);
239		} else {
240			receive.setText(R.string.ask_for_presence_updates);
241			if (contact.getOption(Contact.Options.ASKING)) {
242				receive.setChecked(true);
243			} else {
244				receive.setChecked(false);
245			}
246		}
247
248		lastseen.setText(UIHelper.lastseen(getApplicationContext(),
249				contact.lastseen.time));
250
251		switch (contact.getMostAvailableStatus()) {
252		case Presences.CHAT:
253			status.setText(R.string.contact_status_free_to_chat);
254			status.setTextColor(0xFF83b600);
255			break;
256		case Presences.ONLINE:
257			status.setText(R.string.contact_status_online);
258			status.setTextColor(0xFF83b600);
259			break;
260		case Presences.AWAY:
261			status.setText(R.string.contact_status_away);
262			status.setTextColor(0xFFffa713);
263			break;
264		case Presences.XA:
265			status.setText(R.string.contact_status_extended_away);
266			status.setTextColor(0xFFffa713);
267			break;
268		case Presences.DND:
269			status.setText(R.string.contact_status_do_not_disturb);
270			status.setTextColor(0xFFe92727);
271			break;
272		case Presences.OFFLINE:
273			status.setText(R.string.contact_status_offline);
274			status.setTextColor(0xFFe92727);
275			break;
276		default:
277			status.setText(R.string.contact_status_offline);
278			status.setTextColor(0xFFe92727);
279			break;
280		}
281		if (contact.getPresences().size() > 1) {
282			contactJidTv.setText(contact.getJid() + " ("
283					+ contact.getPresences().size() + ")");
284		} else {
285			contactJidTv.setText(contact.getJid());
286		}
287		accountJidTv.setText(contact.getAccount().getJid());
288
289		UIHelper.prepareContactBadge(this, badge, contact,
290				getApplicationContext());
291
292		if (contact.getSystemAccount() == null) {
293			badge.setOnClickListener(onBadgeClick);
294		}
295
296		keys.removeAllViews();
297		LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
298		for (Iterator<String> iterator = contact.getOtrFingerprints()
299				.iterator(); iterator.hasNext();) {
300			String otrFingerprint = iterator.next();
301			View view = (View) inflater.inflate(R.layout.contact_key, null);
302			TextView key = (TextView) view.findViewById(R.id.key);
303			TextView keyType = (TextView) view.findViewById(R.id.key_type);
304			keyType.setText("OTR Fingerprint");
305			key.setText(otrFingerprint);
306			keys.addView(view);
307		}
308		if (contact.getPgpKeyId() != 0) {
309			View view = (View) inflater.inflate(R.layout.contact_key, null);
310			TextView key = (TextView) view.findViewById(R.id.key);
311			TextView keyType = (TextView) view.findViewById(R.id.key_type);
312			keyType.setText("PGP Key ID");
313			key.setText(OpenPgpUtils.convertKeyIdToHex(contact.getPgpKeyId()));
314			view.setOnClickListener(new OnClickListener() {
315
316				@Override
317				public void onClick(View v) {
318					PgpEngine pgp = activity.xmppConnectionService
319							.getPgpEngine();
320					if (pgp != null) {
321						PendingIntent intent = pgp.getIntentForKey(contact);
322						if (intent != null) {
323							try {
324								startIntentSenderForResult(
325										intent.getIntentSender(), 0, null, 0,
326										0, 0);
327							} catch (SendIntentException e) {
328
329							}
330						}
331					}
332				}
333			});
334			keys.addView(view);
335		}
336	}
337
338	@Override
339	public void onBackendConnected() {
340		xmppConnectionService.setOnRosterUpdateListener(this.rosterUpdate);
341		if ((accountJid != null) && (contactJid != null)) {
342			Account account = xmppConnectionService
343					.findAccountByJid(accountJid);
344			if (account == null) {
345				return;
346			}
347			this.contact = account.getRoster().getContact(contactJid);
348			populateView();
349		}
350	}
351
352	@Override
353	protected void onStop() {
354		super.onStop();
355		xmppConnectionService.removeOnRosterUpdateListener();
356	}
357
358}