ContactDetailsActivity.java

  1package eu.siacs.conversations.ui;
  2
  3import java.math.BigInteger;
  4import java.util.Iterator;
  5import java.util.Locale;
  6
  7import org.openintents.openpgp.util.OpenPgpUtils;
  8
  9import android.app.AlertDialog;
 10import android.app.PendingIntent;
 11import android.content.Context;
 12import android.content.DialogInterface;
 13import android.content.Intent;
 14import android.content.IntentSender.SendIntentException;
 15import android.net.Uri;
 16import android.os.Bundle;
 17import android.provider.ContactsContract.CommonDataKinds;
 18import android.provider.ContactsContract.Contacts;
 19import android.provider.ContactsContract.Intents;
 20import android.util.Log;
 21import android.view.LayoutInflater;
 22import android.view.Menu;
 23import android.view.MenuItem;
 24import android.view.View;
 25import android.view.View.OnClickListener;
 26import android.widget.CheckBox;
 27import android.widget.EditText;
 28import android.widget.LinearLayout;
 29import android.widget.QuickContactBadge;
 30import android.widget.TextView;
 31import android.widget.Toast;
 32import eu.siacs.conversations.R;
 33import eu.siacs.conversations.crypto.PgpEngine;
 34import eu.siacs.conversations.entities.Contact;
 35import eu.siacs.conversations.entities.Presences;
 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 String uuid;
 44	private Contact contact;
 45
 46	private EditText name;
 47	private TextView contactJid;
 48	private TextView accountJid;
 49	private TextView status;
 50	private TextView askAgain;
 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.deleteContact(contact);
 60			activity.finish();
 61		}
 62	};
 63
 64	private DialogInterface.OnClickListener editContactNameListener = new DialogInterface.OnClickListener() {
 65
 66		@Override
 67		public void onClick(DialogInterface dialog, int which) {
 68			contact.setDisplayName(name.getText().toString());
 69			activity.xmppConnectionService.updateContact(contact);
 70			populateView();
 71		}
 72	};
 73
 74	private DialogInterface.OnClickListener addToPhonebook = new DialogInterface.OnClickListener() {
 75
 76		@Override
 77		public void onClick(DialogInterface dialog, int which) {
 78			Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
 79			intent.setType(Contacts.CONTENT_ITEM_TYPE);
 80			intent.putExtra(Intents.Insert.IM_HANDLE, contact.getJid());
 81			intent.putExtra(Intents.Insert.IM_PROTOCOL,
 82					CommonDataKinds.Im.PROTOCOL_JABBER);
 83			intent.putExtra("finishActivityOnSaveCompleted", true);
 84			activity.startActivityForResult(intent, 0);
 85		}
 86	};
 87	private OnClickListener onBadgeClick = new OnClickListener() {
 88
 89		@Override
 90		public void onClick(View v) {
 91			AlertDialog.Builder builder = new AlertDialog.Builder(activity);
 92			builder.setTitle("Add to phone book");
 93			builder.setMessage("Do you want to add " + contact.getJid()
 94					+ " to your phones contact list?");
 95			builder.setNegativeButton("Cancel", null);
 96			builder.setPositiveButton("Add", addToPhonebook);
 97			builder.create().show();
 98		}
 99	};
100
101	private LinearLayout keys;
102
103	@Override
104	protected void onCreate(Bundle savedInstanceState) {
105		super.onCreate(savedInstanceState);
106		if (getIntent().getAction().equals(ACTION_VIEW_CONTACT)) {
107			this.uuid = getIntent().getExtras().getString("uuid");
108		}
109		setContentView(R.layout.activity_contact_details);
110
111		contactJid = (TextView) findViewById(R.id.details_contactjid);
112		accountJid = (TextView) findViewById(R.id.details_account);
113		status = (TextView) findViewById(R.id.details_contactstatus);
114		send = (CheckBox) findViewById(R.id.details_send_presence);
115		receive = (CheckBox) findViewById(R.id.details_receive_presence);
116		askAgain = (TextView) findViewById(R.id.ask_again);
117		badge = (QuickContactBadge) findViewById(R.id.details_contact_badge);
118		keys = (LinearLayout) findViewById(R.id.details_contact_keys);
119		getActionBar().setHomeButtonEnabled(true);
120		getActionBar().setDisplayHomeAsUpEnabled(true);
121
122	}
123
124	@Override
125	public boolean onOptionsItemSelected(MenuItem menuItem) {
126		AlertDialog.Builder builder = new AlertDialog.Builder(this);
127		builder.setNegativeButton("Cancel", null);
128		switch (menuItem.getItemId()) {
129		case android.R.id.home:
130			finish();
131			break;
132		case R.id.action_delete_contact:
133			builder.setTitle("Delete from roster")
134					.setMessage(
135							getString(R.string.remove_contact_text,
136									contact.getJid()))
137					.setPositiveButton("Delete", removeFromRoster).create()
138					.show();
139			break;
140		case R.id.action_edit_contact:
141			if (contact.getSystemAccount() == null) {
142
143				View view = (View) getLayoutInflater().inflate(
144						R.layout.edit_contact_name, null);
145				name = (EditText) view.findViewById(R.id.editText1);
146				name.setText(contact.getDisplayName());
147				builder.setView(view).setTitle(contact.getJid())
148						.setPositiveButton("Edit", editContactNameListener)
149						.create().show();
150
151			} else {
152				Intent intent = new Intent(Intent.ACTION_EDIT);
153				String[] systemAccount = contact.getSystemAccount().split("#");
154				long id = Long.parseLong(systemAccount[0]);
155				Uri uri = Contacts.getLookupUri(id, systemAccount[1]);
156				intent.setDataAndType(uri, Contacts.CONTENT_ITEM_TYPE);
157				intent.putExtra("finishActivityOnSaveCompleted", true);
158				startActivity(intent);
159			}
160			break;
161		}
162		return super.onOptionsItemSelected(menuItem);
163	}
164
165	@Override
166	public boolean onCreateOptionsMenu(Menu menu) {
167		getMenuInflater().inflate(R.menu.contact_details, menu);
168		return true;
169	}
170
171	private void populateView() {
172		setTitle(contact.getDisplayName());
173		if (contact.getSubscriptionOption(Contact.Subscription.FROM)) {
174			send.setChecked(true);
175		} else {
176			send.setText(R.string.preemptively_grant);
177			if (contact
178					.getSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT)) {
179				send.setChecked(true);
180			} else {
181				send.setChecked(false);
182			}
183		}
184		if (contact.getSubscriptionOption(Contact.Subscription.TO)) {
185			receive.setChecked(true);
186		} else {
187			receive.setText(R.string.ask_for_presence_updates);
188			askAgain.setVisibility(View.VISIBLE);
189			askAgain.setOnClickListener(new OnClickListener() {
190				
191				@Override
192				public void onClick(View v) {
193					Toast.makeText(getApplicationContext(), "Asked for presence updates",Toast.LENGTH_SHORT).show();
194					xmppConnectionService.requestPresenceUpdatesFrom(contact);
195					
196				}
197			});
198			if (contact.getSubscriptionOption(Contact.Subscription.ASKING)) {
199				receive.setChecked(true);
200			} else {
201				receive.setChecked(false);
202			}
203		}
204
205		switch (contact.getMostAvailableStatus()) {
206		case Presences.CHAT:
207			status.setText("free to chat");
208			status.setTextColor(0xFF83b600);
209			break;
210		case Presences.ONLINE:
211			status.setText("online");
212			status.setTextColor(0xFF83b600);
213			break;
214		case Presences.AWAY:
215			status.setText("away");
216			status.setTextColor(0xFFffa713);
217			break;
218		case Presences.XA:
219			status.setText("extended away");
220			status.setTextColor(0xFFffa713);
221			break;
222		case Presences.DND:
223			status.setText("do not disturb");
224			status.setTextColor(0xFFe92727);
225			break;
226		case Presences.OFFLINE:
227			status.setText("offline");
228			status.setTextColor(0xFFe92727);
229			break;
230		default:
231			status.setText("offline");
232			status.setTextColor(0xFFe92727);
233			break;
234		}
235		if (contact.getPresences().size() > 1) {
236			contactJid.setText(contact.getJid()+" ("+contact.getPresences().size()+")");
237		} else {
238			contactJid.setText(contact.getJid());
239		}
240		accountJid.setText(contact.getAccount().getJid());
241
242		UIHelper.prepareContactBadge(this, badge, contact, getApplicationContext());
243
244		if (contact.getSystemAccount() == null) {
245			badge.setOnClickListener(onBadgeClick);
246		}
247
248		keys.removeAllViews();
249		LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
250		for (Iterator<String> iterator = contact.getOtrFingerprints()
251				.iterator(); iterator.hasNext();) {
252			String otrFingerprint = iterator.next();
253			View view = (View) inflater.inflate(R.layout.contact_key, null);
254			TextView key = (TextView) view.findViewById(R.id.key);
255			TextView keyType = (TextView) view.findViewById(R.id.key_type);
256			keyType.setText("OTR Fingerprint");
257			key.setText(otrFingerprint);
258			keys.addView(view);
259		}
260		if (contact.getPgpKeyId() != 0) {
261			View view = (View) inflater.inflate(R.layout.contact_key, null);
262			TextView key = (TextView) view.findViewById(R.id.key);
263			TextView keyType = (TextView) view.findViewById(R.id.key_type);
264			keyType.setText("PGP Key ID");
265			key.setText(OpenPgpUtils.convertKeyIdToHex(contact.getPgpKeyId()));
266			view.setOnClickListener(new OnClickListener() {
267				
268				@Override
269				public void onClick(View v) {
270					PgpEngine pgp = activity.xmppConnectionService.getPgpEngine();
271					if (pgp!=null) {
272						PendingIntent intent = pgp.getIntentForKey(contact);
273						if (intent!=null) {
274							try {
275								startIntentSenderForResult(intent.getIntentSender(), 0, null, 0, 0, 0);
276							} catch (SendIntentException e) {
277								
278							}
279						}
280					}
281				}
282			});
283			keys.addView(view);
284		}
285	}
286
287	@Override
288	public void onBackendConnected() {
289		if (uuid != null) {
290			this.contact = xmppConnectionService.findContact(uuid);
291			if (this.contact != null) {
292				populateView();
293			}
294		}
295	}
296
297	@Override
298	protected void onStop() {
299		super.onStop();
300		boolean needsUpdating = false;
301		if (contact.getSubscriptionOption(Contact.Subscription.FROM)) {
302			if (!send.isChecked()) {
303				contact.resetSubscriptionOption(Contact.Subscription.FROM);
304				contact.resetSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT);
305				activity.xmppConnectionService.stopPresenceUpdatesTo(contact);
306				needsUpdating = true;
307			}
308		} else {
309			if (contact
310					.getSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT)) {
311				if (!send.isChecked()) {
312					contact.resetSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT);
313					needsUpdating = true;
314				}
315			} else {
316				if (send.isChecked()) {
317					contact.setSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT);
318					needsUpdating = true;
319				}
320			}
321		}
322		if (contact.getSubscriptionOption(Contact.Subscription.TO)) {
323			if (!receive.isChecked()) {
324				contact.resetSubscriptionOption(Contact.Subscription.TO);
325				activity.xmppConnectionService.stopPresenceUpdatesFrom(contact);
326				needsUpdating = true;
327			}
328		} else {
329			if (contact.getSubscriptionOption(Contact.Subscription.ASKING)) {
330				if (!receive.isChecked()) {
331					contact.resetSubscriptionOption(Contact.Subscription.ASKING);
332					activity.xmppConnectionService
333							.stopPresenceUpdatesFrom(contact);
334					needsUpdating = true;
335				}
336			} else {
337				if (receive.isChecked()) {
338					contact.setSubscriptionOption(Contact.Subscription.ASKING);
339					activity.xmppConnectionService
340							.requestPresenceUpdatesFrom(contact);
341					needsUpdating = true;
342				}
343			}
344		}
345		if (needsUpdating) {
346			Toast.makeText(getApplicationContext(), "Subscription updated", Toast.LENGTH_SHORT).show();
347			activity.xmppConnectionService.updateContact(contact);
348		}
349	}
350
351}