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}