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.LinearLayout;
 25import android.widget.QuickContactBadge;
 26import android.widget.TextView;
 27import android.widget.Toast;
 28import eu.siacs.conversations.R;
 29import eu.siacs.conversations.crypto.PgpEngine;
 30import eu.siacs.conversations.entities.Account;
 31import eu.siacs.conversations.entities.Contact;
 32import eu.siacs.conversations.entities.Presences;
 33import eu.siacs.conversations.services.XmppConnectionService;
 34import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
 35import eu.siacs.conversations.utils.UIHelper;
 36import eu.siacs.conversations.xmpp.stanzas.PresencePacket;
 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, 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	@Override
108	protected void onCreate(Bundle savedInstanceState) {
109		super.onCreate(savedInstanceState);
110		if (getIntent().getAction().equals(ACTION_VIEW_CONTACT)) {
111			this.accountJid = getIntent().getExtras().getString("account");
112			this.contactJid = getIntent().getExtras().getString("contact");
113		}
114		setContentView(R.layout.activity_contact_details);
115
116		contactJidTv = (TextView) findViewById(R.id.details_contactjid);
117		accountJidTv = (TextView) findViewById(R.id.details_account);
118		status = (TextView) findViewById(R.id.details_contactstatus);
119		lastseen = (TextView) findViewById(R.id.details_lastseen);
120		send = (CheckBox) findViewById(R.id.details_send_presence);
121		receive = (CheckBox) findViewById(R.id.details_receive_presence);
122		badge = (QuickContactBadge) findViewById(R.id.details_contact_badge);
123		keys = (LinearLayout) findViewById(R.id.details_contact_keys);
124		getActionBar().setHomeButtonEnabled(true);
125		getActionBar().setDisplayHomeAsUpEnabled(true);
126
127	}
128
129	@Override
130	public boolean onOptionsItemSelected(MenuItem menuItem) {
131		AlertDialog.Builder builder = new AlertDialog.Builder(this);
132		builder.setNegativeButton(getString(R.string.cancel), null);
133		switch (menuItem.getItemId()) {
134		case android.R.id.home:
135			finish();
136			break;
137		case R.id.action_delete_contact:
138			builder.setTitle(getString(R.string.action_delete_contact))
139					.setMessage(
140							getString(R.string.remove_contact_text,
141									contact.getJid()))
142					.setPositiveButton(getString(R.string.delete), removeFromRoster).create()
143					.show();
144			break;
145		case R.id.action_edit_contact:
146			if (contact.getSystemAccount() == null) {
147				quickEdit(contact.getDisplayName(), new OnValueEdited() {
148					
149					@Override
150					public void onValueEdited(String value) {
151						contact.setServerName(value);
152						activity.xmppConnectionService.pushContactToServer(contact);
153						populateView();
154					}
155				});
156			} else {
157				Intent intent = new Intent(Intent.ACTION_EDIT);
158				String[] systemAccount = contact.getSystemAccount().split("#");
159				long id = Long.parseLong(systemAccount[0]);
160				Uri uri = Contacts.getLookupUri(id, systemAccount[1]);
161				intent.setDataAndType(uri, Contacts.CONTENT_ITEM_TYPE);
162				intent.putExtra("finishActivityOnSaveCompleted", true);
163				startActivity(intent);
164			}
165			break;
166		}
167		return super.onOptionsItemSelected(menuItem);
168	}
169
170	@Override
171	public boolean onCreateOptionsMenu(Menu menu) {
172		getMenuInflater().inflate(R.menu.contact_details, menu);
173		return true;
174	}
175
176	private void populateView() {
177		setTitle(contact.getDisplayName());
178		if (contact.getOption(Contact.Options.FROM)) {
179			send.setChecked(true);
180		} else if (contact.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)){
181			send.setChecked(false);
182		} else {
183			send.setText(R.string.preemptively_grant);
184			if (contact
185					.getOption(Contact.Options.PREEMPTIVE_GRANT)) {
186				send.setChecked(true);
187			} else {
188				send.setChecked(false);
189			}
190		}
191		if (contact.getOption(Contact.Options.TO)) {
192			receive.setChecked(true);
193		} else {
194			receive.setText(R.string.ask_for_presence_updates);
195			if (contact.getOption(Contact.Options.ASKING)) {
196				receive.setChecked(true);
197			} else {
198				receive.setChecked(false);
199			}
200		}
201		
202		lastseen.setText(UIHelper.lastseen(getApplicationContext(),contact.lastseen.time));
203
204		switch (contact.getMostAvailableStatus()) {
205		case Presences.CHAT:
206			status.setText(R.string.contact_status_free_to_chat);
207			status.setTextColor(0xFF83b600);
208			break;
209		case Presences.ONLINE:
210			status.setText(R.string.contact_status_online);
211			status.setTextColor(0xFF83b600);
212			break;
213		case Presences.AWAY:
214			status.setText(R.string.contact_status_away);
215			status.setTextColor(0xFFffa713);
216			break;
217		case Presences.XA:
218			status.setText(R.string.contact_status_extended_away);
219			status.setTextColor(0xFFffa713);
220			break;
221		case Presences.DND:
222			status.setText(R.string.contact_status_do_not_disturb);
223			status.setTextColor(0xFFe92727);
224			break;
225		case Presences.OFFLINE:
226			status.setText(R.string.contact_status_offline);
227			status.setTextColor(0xFFe92727);
228			break;
229		default:
230			status.setText(R.string.contact_status_offline);
231			status.setTextColor(0xFFe92727);
232			break;
233		}
234		if (contact.getPresences().size() > 1) {
235			contactJidTv.setText(contact.getJid()+" ("+contact.getPresences().size()+")");
236		} else {
237			contactJidTv.setText(contact.getJid());
238		}
239		accountJidTv.setText(contact.getAccount().getJid());
240
241		UIHelper.prepareContactBadge(this, badge, contact, getApplicationContext());
242
243		if (contact.getSystemAccount() == null) {
244			badge.setOnClickListener(onBadgeClick);
245		}
246
247		keys.removeAllViews();
248		LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
249		for (Iterator<String> iterator = contact.getOtrFingerprints()
250				.iterator(); iterator.hasNext();) {
251			String otrFingerprint = iterator.next();
252			View view = (View) inflater.inflate(R.layout.contact_key, null);
253			TextView key = (TextView) view.findViewById(R.id.key);
254			TextView keyType = (TextView) view.findViewById(R.id.key_type);
255			keyType.setText("OTR Fingerprint");
256			key.setText(otrFingerprint);
257			keys.addView(view);
258		}
259		if (contact.getPgpKeyId() != 0) {
260			View view = (View) inflater.inflate(R.layout.contact_key, null);
261			TextView key = (TextView) view.findViewById(R.id.key);
262			TextView keyType = (TextView) view.findViewById(R.id.key_type);
263			keyType.setText("PGP Key ID");
264			key.setText(OpenPgpUtils.convertKeyIdToHex(contact.getPgpKeyId()));
265			view.setOnClickListener(new OnClickListener() {
266				
267				@Override
268				public void onClick(View v) {
269					PgpEngine pgp = activity.xmppConnectionService.getPgpEngine();
270					if (pgp!=null) {
271						PendingIntent intent = pgp.getIntentForKey(contact);
272						if (intent!=null) {
273							try {
274								startIntentSenderForResult(intent.getIntentSender(), 0, null, 0, 0, 0);
275							} catch (SendIntentException e) {
276								
277							}
278						}
279					}
280				}
281			});
282			keys.addView(view);
283		}
284	}
285
286	@Override
287	public void onBackendConnected() {
288		xmppConnectionService.setOnRosterUpdateListener(this.rosterUpdate );
289		if ((accountJid != null)&&(contactJid != null)) {
290			Account account = xmppConnectionService.findAccountByJid(accountJid);
291			if (account==null) {
292				return;
293			}
294			this.contact = account.getRoster().getContact(contactJid);
295			populateView();
296		}
297	}
298
299	@Override
300	protected void onStop() {
301		super.onStop();
302		XmppConnectionService xcs = activity.xmppConnectionService;
303		PresencePacket packet = null;
304		boolean updated = false;
305		if (contact!=null) {
306			boolean online = contact.getAccount().getStatus() == Account.STATUS_ONLINE;
307			if (contact.getOption(Contact.Options.FROM)) {
308				if (!send.isChecked()) {
309					if (online) {
310						contact.resetOption(Contact.Options.FROM);
311						contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
312						packet = xcs.getPresenceGenerator().stopPresenceUpdatesTo(contact);
313					}
314					updated = true;
315				}
316			} else {
317				if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) {
318					if (!send.isChecked()) {
319						if (online) {
320							contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
321						}
322						updated = true;
323					}
324				} else {
325					if (send.isChecked()) {
326						if (online) {
327							if (contact.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) {
328								packet = xcs.getPresenceGenerator().sendPresenceUpdatesTo(contact);
329							} else {
330								contact.setOption(Contact.Options.PREEMPTIVE_GRANT);
331							}
332						}
333						updated = true;
334					}
335				}
336			}
337			if (contact.getOption(Contact.Options.TO)) {
338				if (!receive.isChecked()) {
339					if (online) {
340						contact.resetOption(Contact.Options.TO);
341						packet = xcs.getPresenceGenerator().stopPresenceUpdatesFrom(contact);
342					}
343					updated = true;
344				}
345			} else {
346				if (contact.getOption(Contact.Options.ASKING)) {
347					if (!receive.isChecked()) {
348						if (online) {
349							contact.resetOption(Contact.Options.ASKING);
350							packet = xcs.getPresenceGenerator().stopPresenceUpdatesFrom(contact);
351						}
352						updated = true;
353					}
354				} else {
355					if (receive.isChecked()) {
356						if (online) {
357							contact.setOption(Contact.Options.ASKING);
358							packet = xcs.getPresenceGenerator().requestPresenceUpdatesFrom(contact);
359						}
360						updated = true;
361					}
362				}
363			}
364			if (updated) {
365				if (online) {
366					if (packet!=null) {
367						xcs.sendPresencePacket(contact.getAccount(), packet);
368					}
369					Toast.makeText(getApplicationContext(), getString(R.string.subscription_updated), Toast.LENGTH_SHORT).show();
370				} else {
371					Toast.makeText(getApplicationContext(), getString(R.string.subscription_not_updated_offline), Toast.LENGTH_SHORT).show();
372				}
373			}
374		}
375		xmppConnectionService.removeOnRosterUpdateListener();
376	}
377
378}