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