1package eu.siacs.conversations.ui;
2
3import java.nio.channels.AlreadyConnectedException;
4
5import eu.siacs.conversations.R;
6import eu.siacs.conversations.entities.Account;
7import eu.siacs.conversations.entities.Conversation;
8import eu.siacs.conversations.entities.Message;
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(
89 focus.getWindowToken(),
90 InputMethodManager.HIDE_NOT_ALWAYS);
91 }
92 }
93
94 public boolean hasPgp() {
95 if (xmppConnectionService.getPgpEngine()!=null) {
96 return true;
97 } else {
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), new OnClickListener() {
104
105 @Override
106 public void onClick(DialogInterface dialog, int which) {
107 if (xmppConnectionServiceBound) {
108 unbindService(mConnection);
109 xmppConnectionServiceBound = false;
110 }
111 stopService(new Intent(XmppActivity.this, XmppConnectionService.class));
112 finish();
113 }
114 });
115 builder.setPositiveButton(getString(R.string.install), new OnClickListener() {
116
117 @Override
118 public void onClick(DialogInterface dialog, int which) {
119 Uri uri = Uri.parse("market://details?id=org.sufficientlysecure.keychain");
120 Intent intent = new Intent(Intent.ACTION_VIEW, uri);
121 startActivity(intent);
122 finish();
123 }
124 });
125 builder.create().show();
126 return false;
127 }
128 }
129
130 abstract void onBackendConnected();
131
132 public boolean onOptionsItemSelected(MenuItem item) {
133 switch (item.getItemId()) {
134 case R.id.action_settings:
135 startActivity(new Intent(this, SettingsActivity.class));
136 break;
137 case R.id.action_accounts:
138 startActivity(new Intent(this, ManageAccountActivity.class));
139 break;
140 }
141 return super.onOptionsItemSelected(item);
142 }
143
144 @Override
145 protected void onCreate(Bundle savedInstanceState) {
146 super.onCreate(savedInstanceState);
147 ExceptionHelper.init(getApplicationContext());
148 }
149
150 public void switchToConversation(Conversation conversation, String text) {
151 Intent viewConversationIntent = new Intent(this,
152 ConversationActivity.class);
153 viewConversationIntent.setAction(Intent.ACTION_VIEW);
154 viewConversationIntent.putExtra(ConversationActivity.CONVERSATION,
155 conversation.getUuid());
156 if (text!=null) {
157 viewConversationIntent.putExtra(ConversationActivity.TEXT, text);
158 }
159 viewConversationIntent.setType(ConversationActivity.VIEW_CONVERSATION);
160 viewConversationIntent.setFlags(viewConversationIntent.getFlags()
161 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
162 startActivity(viewConversationIntent);
163 }
164
165 protected void announcePgp(final Account account, final Conversation conversation) {
166 xmppConnectionService.getPgpEngine().generateSignature(account, "online", new UiCallback() {
167
168 @Override
169 public void userInputRequried(PendingIntent pi) {
170 try {
171 startIntentSenderForResult(pi.getIntentSender(), REQUEST_ANNOUNCE_PGP, null, 0, 0, 0);
172 } catch (SendIntentException e) {
173 Log.d("xmppService","coulnd start intent for pgp anncouncment");
174 }
175 }
176
177 @Override
178 public void success() {
179 xmppConnectionService.databaseBackend.updateAccount(account);
180 xmppConnectionService.sendPgpPresence(account, account.getPgpSignature());
181 if (conversation!=null) {
182 conversation.setNextEncryption(Message.ENCRYPTION_PGP);
183 }
184 }
185
186 @Override
187 public void error(int error) {
188 displayErrorDialog(error);
189 }
190 });
191 }
192
193 protected void displayErrorDialog(final int errorCode) {
194 runOnUiThread(new Runnable() {
195
196 @Override
197 public void run() {
198 AlertDialog.Builder builder = new AlertDialog.Builder(XmppActivity.this);
199 builder.setIconAttribute(android.R.attr.alertDialogIcon);
200 builder.setTitle(getString(R.string.error));
201 builder.setMessage(errorCode);
202 builder.setNeutralButton(R.string.accept, null);
203 builder.create().show();
204 }
205 });
206
207 }
208}