XmppActivity.java

  1package eu.siacs.conversations.ui;
  2
  3import eu.siacs.conversations.R;
  4import eu.siacs.conversations.entities.Account;
  5import eu.siacs.conversations.entities.Contact;
  6import eu.siacs.conversations.entities.Conversation;
  7import eu.siacs.conversations.entities.Message;
  8import eu.siacs.conversations.entities.Presences;
  9import eu.siacs.conversations.services.XmppConnectionService;
 10import eu.siacs.conversations.services.XmppConnectionService.XmppConnectionBinder;
 11import eu.siacs.conversations.utils.ExceptionHelper;
 12import android.app.Activity;
 13import android.app.AlertDialog;
 14import android.app.PendingIntent;
 15import android.app.AlertDialog.Builder;
 16import android.content.ComponentName;
 17import android.content.Context;
 18import android.content.DialogInterface;
 19import android.content.DialogInterface.OnClickListener;
 20import android.content.IntentSender.SendIntentException;
 21import android.content.Intent;
 22import android.content.ServiceConnection;
 23import android.net.Uri;
 24import android.os.Bundle;
 25import android.os.IBinder;
 26import android.util.Log;
 27import android.view.MenuItem;
 28import android.view.View;
 29import android.view.inputmethod.InputMethodManager;
 30
 31public abstract class XmppActivity extends Activity {
 32
 33	public static final int REQUEST_ANNOUNCE_PGP = 0x73731;
 34
 35	protected final static String LOGTAG = "xmppService";
 36
 37	public XmppConnectionService xmppConnectionService;
 38	public boolean xmppConnectionServiceBound = false;
 39	protected boolean handledViewIntent = false;
 40
 41	protected ServiceConnection mConnection = new ServiceConnection() {
 42
 43		@Override
 44		public void onServiceConnected(ComponentName className, IBinder service) {
 45			XmppConnectionBinder binder = (XmppConnectionBinder) service;
 46			xmppConnectionService = binder.getService();
 47			xmppConnectionServiceBound = true;
 48			onBackendConnected();
 49		}
 50
 51		@Override
 52		public void onServiceDisconnected(ComponentName arg0) {
 53			xmppConnectionServiceBound = false;
 54		}
 55	};
 56
 57	@Override
 58	protected void onStart() {
 59		super.onStart();
 60		if (!xmppConnectionServiceBound) {
 61			connectToBackend();
 62		}
 63	}
 64
 65	public void connectToBackend() {
 66		Intent intent = new Intent(this, XmppConnectionService.class);
 67		intent.setAction("ui");
 68		startService(intent);
 69		bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
 70	}
 71
 72	@Override
 73	protected void onStop() {
 74		super.onStop();
 75		if (xmppConnectionServiceBound) {
 76			unbindService(mConnection);
 77			xmppConnectionServiceBound = false;
 78		}
 79	}
 80
 81	protected void hideKeyboard() {
 82		InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
 83
 84		View focus = getCurrentFocus();
 85
 86		if (focus != null) {
 87
 88			inputManager.hideSoftInputFromWindow(focus.getWindowToken(),
 89					InputMethodManager.HIDE_NOT_ALWAYS);
 90		}
 91	}
 92
 93	public boolean hasPgp() {
 94		return xmppConnectionService.getPgpEngine() != null;
 95	}
 96
 97	public void showInstallPgpDialog() {
 98		Builder builder = new AlertDialog.Builder(this);
 99		builder.setTitle(getString(R.string.openkeychain_required));
100		builder.setIconAttribute(android.R.attr.alertDialogIcon);
101		builder.setMessage(getText(R.string.openkeychain_required_long));
102		builder.setNegativeButton(getString(R.string.cancel), null);
103		builder.setNeutralButton(getString(R.string.restart),
104				new OnClickListener() {
105
106					@Override
107					public void onClick(DialogInterface dialog, int which) {
108						if (xmppConnectionServiceBound) {
109							unbindService(mConnection);
110							xmppConnectionServiceBound = false;
111						}
112						stopService(new Intent(XmppActivity.this,
113								XmppConnectionService.class));
114						finish();
115					}
116				});
117		builder.setPositiveButton(getString(R.string.install),
118				new OnClickListener() {
119
120					@Override
121					public void onClick(DialogInterface dialog, int which) {
122						Uri uri = Uri
123								.parse("market://details?id=org.sufficientlysecure.keychain");
124						Intent intent = new Intent(Intent.ACTION_VIEW, uri);
125						startActivity(intent);
126						finish();
127					}
128				});
129		builder.create().show();
130	}
131
132	abstract void onBackendConnected();
133
134	public boolean onOptionsItemSelected(MenuItem item) {
135		switch (item.getItemId()) {
136		case R.id.action_settings:
137			startActivity(new Intent(this, SettingsActivity.class));
138			break;
139		case R.id.action_accounts:
140			startActivity(new Intent(this, ManageAccountActivity.class));
141			break;
142		}
143		return super.onOptionsItemSelected(item);
144	}
145
146	@Override
147	protected void onCreate(Bundle savedInstanceState) {
148		super.onCreate(savedInstanceState);
149		ExceptionHelper.init(getApplicationContext());
150	}
151
152	public void switchToConversation(Conversation conversation) {
153		switchToConversation(conversation, null, false);
154	}
155
156	public void switchToConversation(Conversation conversation, String text,
157			boolean newTask) {
158		Intent viewConversationIntent = new Intent(this,
159				ConversationActivity.class);
160		viewConversationIntent.setAction(Intent.ACTION_VIEW);
161		viewConversationIntent.putExtra(ConversationActivity.CONVERSATION,
162				conversation.getUuid());
163		if (text != null) {
164			viewConversationIntent.putExtra(ConversationActivity.TEXT, text);
165		}
166		viewConversationIntent.setType(ConversationActivity.VIEW_CONVERSATION);
167		if (newTask) {
168			viewConversationIntent.setFlags(viewConversationIntent.getFlags()
169					| Intent.FLAG_ACTIVITY_NEW_TASK
170					| Intent.FLAG_ACTIVITY_SINGLE_TOP);
171		} else {
172			viewConversationIntent.setFlags(viewConversationIntent.getFlags()
173					| Intent.FLAG_ACTIVITY_CLEAR_TOP);
174		}
175		startActivity(viewConversationIntent);
176	}
177
178	public void switchToContactDetails(Contact contact) {
179		Intent intent = new Intent(this, ContactDetailsActivity.class);
180		intent.setAction(ContactDetailsActivity.ACTION_VIEW_CONTACT);
181		intent.putExtra("account", contact.getAccount().getJid());
182		intent.putExtra("contact", contact.getJid());
183		startActivity(intent);
184	}
185
186	protected void announcePgp(Account account, final Conversation conversation) {
187		xmppConnectionService.getPgpEngine().generateSignature(account,
188				"online", new UiCallback<Account>() {
189
190					@Override
191					public void userInputRequried(PendingIntent pi,
192							Account account) {
193						try {
194							startIntentSenderForResult(pi.getIntentSender(),
195									REQUEST_ANNOUNCE_PGP, null, 0, 0, 0);
196						} catch (SendIntentException e) {
197							Log.d("xmppService",
198									"coulnd start intent for pgp anncouncment");
199						}
200					}
201
202					@Override
203					public void success(Account account) {
204						xmppConnectionService.databaseBackend
205								.updateAccount(account);
206						xmppConnectionService.sendPresencePacket(account,
207								xmppConnectionService.getPresenceGenerator()
208										.sendPresence(account));
209						if (conversation != null) {
210							conversation
211									.setNextEncryption(Message.ENCRYPTION_PGP);
212						}
213					}
214
215					@Override
216					public void error(int error, Account account) {
217						displayErrorDialog(error);
218					}
219				});
220	}
221
222	protected void displayErrorDialog(final int errorCode) {
223		runOnUiThread(new Runnable() {
224
225			@Override
226			public void run() {
227				AlertDialog.Builder builder = new AlertDialog.Builder(
228						XmppActivity.this);
229				builder.setIconAttribute(android.R.attr.alertDialogIcon);
230				builder.setTitle(getString(R.string.error));
231				builder.setMessage(errorCode);
232				builder.setNeutralButton(R.string.accept, null);
233				builder.create().show();
234			}
235		});
236
237	}
238
239	protected void showAddToRosterDialog(final Conversation conversation) {
240		String jid = conversation.getContactJid();
241		AlertDialog.Builder builder = new AlertDialog.Builder(this);
242		builder.setTitle(jid);
243		builder.setMessage(getString(R.string.not_in_roster));
244		builder.setNegativeButton(getString(R.string.cancel), null);
245		builder.setPositiveButton(getString(R.string.add_contact),
246				new DialogInterface.OnClickListener() {
247
248					@Override
249					public void onClick(DialogInterface dialog, int which) {
250						String jid = conversation.getContactJid();
251						Account account = conversation.getAccount();
252						Contact contact = account.getRoster().getContact(jid);
253						xmppConnectionService.createContact(contact);
254					}
255				});
256		builder.create().show();
257	}
258
259	public void selectPresence(final Conversation conversation,
260			final OnPresenceSelected listener) {
261		Contact contact = conversation.getContact();
262		if (contact == null) {
263			showAddToRosterDialog(conversation);
264		} else {
265			Presences presences = contact.getPresences();
266			if (presences.size() == 0) {
267				conversation.setNextPresence(null);
268				listener.onPresenceSelected();
269			} else if (presences.size() == 1) {
270				String presence = (String) presences.asStringArray()[0];
271				conversation.setNextPresence(presence);
272				listener.onPresenceSelected();
273			} else {
274				final StringBuilder presence = new StringBuilder();
275				AlertDialog.Builder builder = new AlertDialog.Builder(this);
276				builder.setTitle(getString(R.string.choose_presence));
277				final String[] presencesArray = presences.asStringArray();
278				int preselectedPresence = 0;
279				for (int i = 0; i < presencesArray.length; ++i) {
280					if (presencesArray[i].equals(contact.lastseen.presence)) {
281						preselectedPresence = i;
282						break;
283					}
284				}
285				presence.append(presencesArray[preselectedPresence]);
286				builder.setSingleChoiceItems(presencesArray,
287						preselectedPresence,
288						new DialogInterface.OnClickListener() {
289
290							@Override
291							public void onClick(DialogInterface dialog,
292									int which) {
293								presence.delete(0, presence.length());
294								presence.append(presencesArray[which]);
295							}
296						});
297				builder.setNegativeButton(R.string.cancel, null);
298				builder.setPositiveButton(R.string.ok, new OnClickListener() {
299
300					@Override
301					public void onClick(DialogInterface dialog, int which) {
302						conversation.setNextPresence(presence.toString());
303						listener.onPresenceSelected();
304					}
305				});
306				builder.create().show();
307			}
308		}
309	}
310}