ShareWithActivity.java

  1package eu.siacs.conversations.ui;
  2
  3import android.app.PendingIntent;
  4import android.content.Intent;
  5import android.net.Uri;
  6import android.os.Bundle;
  7import android.util.Log;
  8import android.view.Menu;
  9import android.view.MenuItem;
 10import android.view.View;
 11import android.widget.AdapterView;
 12import android.widget.AdapterView.OnItemClickListener;
 13import android.widget.ListView;
 14import android.widget.Toast;
 15
 16import java.net.URLConnection;
 17import java.util.ArrayList;
 18import java.util.Iterator;
 19import java.util.List;
 20import java.util.concurrent.atomic.AtomicInteger;
 21
 22import eu.siacs.conversations.Config;
 23import eu.siacs.conversations.R;
 24import eu.siacs.conversations.entities.Account;
 25import eu.siacs.conversations.entities.Conversation;
 26import eu.siacs.conversations.entities.Message;
 27import eu.siacs.conversations.persistance.FileBackend;
 28import eu.siacs.conversations.services.XmppConnectionService;
 29import eu.siacs.conversations.ui.adapter.ConversationAdapter;
 30import eu.siacs.conversations.xmpp.XmppConnection;
 31import eu.siacs.conversations.xmpp.jid.InvalidJidException;
 32import eu.siacs.conversations.xmpp.jid.Jid;
 33
 34public class ShareWithActivity extends XmppActivity implements XmppConnectionService.OnConversationUpdate {
 35
 36	private boolean mReturnToPrevious = false;
 37
 38	@Override
 39	public void onConversationUpdate() {
 40		refreshUi();
 41	}
 42
 43	private class Share {
 44		public List<Uri> uris = new ArrayList<>();
 45		public boolean image;
 46		public String account;
 47		public String contact;
 48		public String text;
 49		public String uuid;
 50		public boolean multiple = false;
 51	}
 52
 53	private Share share;
 54
 55	private static final int REQUEST_START_NEW_CONVERSATION = 0x0501;
 56	private ListView mListView;
 57	private ConversationAdapter mAdapter;
 58	private List<Conversation> mConversations = new ArrayList<>();
 59	private Toast mToast;
 60	private AtomicInteger attachmentCounter = new AtomicInteger(0);
 61
 62	private UiCallback<Message> attachFileCallback = new UiCallback<Message>() {
 63
 64		@Override
 65		public void userInputRequried(PendingIntent pi, Message object) {
 66			// TODO Auto-generated method stub
 67
 68		}
 69
 70		@Override
 71		public void success(final Message message) {
 72			xmppConnectionService.sendMessage(message);
 73			runOnUiThread(new Runnable() {
 74				@Override
 75				public void run() {
 76					if (attachmentCounter.decrementAndGet() <=0 ) {
 77						int resId;
 78						if (share.image && share.multiple) {
 79							resId = R.string.shared_images_with_x;
 80						} else if (share.image) {
 81							resId = R.string.shared_image_with_x;
 82						} else {
 83							resId = R.string.shared_file_with_x;
 84						}
 85						replaceToast(getString(resId, message.getConversation().getName()));
 86						if (mReturnToPrevious) {
 87							finish();
 88						} else {
 89							switchToConversation(message.getConversation());
 90						}
 91					}
 92				}
 93			});
 94		}
 95
 96		@Override
 97		public void error(final int errorCode, Message object) {
 98			runOnUiThread(new Runnable() {
 99				@Override
100				public void run() {
101					replaceToast(getString(errorCode));
102					if (attachmentCounter.decrementAndGet() <=0 ) {
103						finish();
104					}
105				}
106			});
107		}
108	};
109
110	protected void hideToast() {
111		if (mToast != null) {
112			mToast.cancel();
113		}
114	}
115
116	protected void replaceToast(String msg) {
117		hideToast();
118		mToast = Toast.makeText(this, msg ,Toast.LENGTH_LONG);
119		mToast.show();
120	}
121
122	protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
123		super.onActivityResult(requestCode, resultCode, data);
124		if (requestCode == REQUEST_START_NEW_CONVERSATION
125				&& resultCode == RESULT_OK) {
126			share.contact = data.getStringExtra("contact");
127			share.account = data.getStringExtra(EXTRA_ACCOUNT);
128		}
129		if (xmppConnectionServiceBound
130				&& share != null
131				&& share.contact != null
132				&& share.account != null) {
133			share();
134		}
135	}
136
137	@Override
138	protected void onCreate(Bundle savedInstanceState) {
139		super.onCreate(savedInstanceState);
140
141		if (getActionBar() != null) {
142			getActionBar().setDisplayHomeAsUpEnabled(false);
143			getActionBar().setHomeButtonEnabled(false);
144		}
145
146		setContentView(R.layout.share_with);
147		setTitle(getString(R.string.title_activity_sharewith));
148
149		mListView = (ListView) findViewById(R.id.choose_conversation_list);
150		mAdapter = new ConversationAdapter(this, this.mConversations);
151		mListView.setAdapter(mAdapter);
152		mListView.setOnItemClickListener(new OnItemClickListener() {
153
154			@Override
155			public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
156				share(mConversations.get(position));
157			}
158		});
159
160		this.share = new Share();
161	}
162
163	@Override
164	public boolean onCreateOptionsMenu(Menu menu) {
165		getMenuInflater().inflate(R.menu.share_with, menu);
166		return true;
167	}
168
169	@Override
170	public boolean onOptionsItemSelected(final MenuItem item) {
171		switch (item.getItemId()) {
172			case R.id.action_add:
173				final Intent intent = new Intent(getApplicationContext(), ChooseContactActivity.class);
174				startActivityForResult(intent, REQUEST_START_NEW_CONVERSATION);
175				return true;
176		}
177		return super.onOptionsItemSelected(item);
178	}
179
180	@Override
181	public void onStart() {
182		super.onStart();
183		Intent intent = getIntent();
184		if (intent == null) {
185			return;
186		}
187		this.mReturnToPrevious = getPreferences().getBoolean("return_to_previous", false);
188		final String type = intent.getType();
189		final String action = intent.getAction();
190		Log.d(Config.LOGTAG, "action: "+action+ ", type:"+type);
191		share.uuid = intent.getStringExtra("uuid");
192		if (Intent.ACTION_SEND.equals(action)) {
193			final String text = intent.getStringExtra(Intent.EXTRA_TEXT);
194			final Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
195			if (type != null && uri != null && (text == null || !type.equals("text/plain"))) {
196				this.share.uris.clear();
197				this.share.uris.add(uri);
198				this.share.image = type.startsWith("image/") || isImage(uri);
199			} else {
200				this.share.text = text;
201			}
202		} else if (Intent.ACTION_SEND_MULTIPLE.equals(action)) {
203			this.share.image = type != null && type.startsWith("image/");
204			if (!this.share.image) {
205				return;
206			}
207			this.share.uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
208		}
209		if (xmppConnectionServiceBound) {
210			if (share.uuid != null) {
211				share();
212			} else {
213				xmppConnectionService.populateWithOrderedConversations(mConversations, this.share.uris.size() == 0);
214			}
215		}
216
217	}
218
219	protected boolean isImage(Uri uri) {
220		try {
221			String guess = URLConnection.guessContentTypeFromName(uri.toString());
222			return (guess != null && guess.startsWith("image/"));
223		} catch (final StringIndexOutOfBoundsException ignored) {
224			return false;
225		}
226	}
227
228	@Override
229	void onBackendConnected() {
230		if (xmppConnectionServiceBound && share != null
231				&& ((share.contact != null && share.account != null) || share.uuid != null)) {
232			share();
233			return;
234		}
235		refreshUiReal();
236	}
237
238	private void share() {
239		final Conversation conversation;
240		if (share.uuid != null) {
241			conversation = xmppConnectionService.findConversationByUuid(share.uuid);
242			if (conversation == null) {
243				return;
244			}
245		}else{
246			Account account;
247			try {
248				account = xmppConnectionService.findAccountByJid(Jid.fromString(share.account));
249			} catch (final InvalidJidException e) {
250				account = null;
251			}
252			if (account == null) {
253				return;
254			}
255
256			try {
257				conversation = xmppConnectionService
258						.findOrCreateConversation(account, Jid.fromString(share.contact), false);
259			} catch (final InvalidJidException e) {
260				return;
261			}
262		}
263		share(conversation);
264	}
265
266	private void share(final Conversation conversation) {
267		final Account account = conversation.getAccount();
268		final XmppConnection connection = account.getXmppConnection();
269		final long max = connection == null ? -1 : connection.getFeatures().getMaxHttpUploadSize();
270		mListView.setEnabled(false);
271		if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP && !hasPgp()) {
272			if (share.uuid == null) {
273				showInstallPgpDialog();
274			} else {
275				Toast.makeText(this,R.string.openkeychain_not_installed,Toast.LENGTH_SHORT).show();
276				finish();
277			}
278			return;
279		}
280		if (share.uris.size() != 0) {
281			OnPresenceSelected callback = new OnPresenceSelected() {
282				@Override
283				public void onPresenceSelected() {
284					attachmentCounter.set(share.uris.size());
285					if (share.image) {
286						share.multiple = share.uris.size() > 1;
287						replaceToast(getString(share.multiple ? R.string.preparing_images : R.string.preparing_image));
288						for (Iterator<Uri> i = share.uris.iterator(); i.hasNext(); i.remove()) {
289							ShareWithActivity.this.xmppConnectionService
290									.attachImageToConversation(conversation, i.next(),
291											attachFileCallback);
292						}
293					} else {
294						replaceToast(getString(R.string.preparing_file));
295						ShareWithActivity.this.xmppConnectionService
296								.attachFileToConversation(conversation, share.uris.get(0),
297										attachFileCallback);
298					}
299				}
300			};
301			if (account.httpUploadAvailable()
302					&& ((share.image && !neverCompressPictures())
303					|| conversation.getMode() == Conversation.MODE_MULTI
304					|| FileBackend.allFilesUnderSize(this, share.uris, max))
305					&& conversation.getNextEncryption() != Message.ENCRYPTION_OTR) {
306				callback.onPresenceSelected();
307			} else {
308				selectPresence(conversation, callback);
309			}
310		} else {
311			if (mReturnToPrevious && this.share.text != null && !this.share.text.isEmpty() ) {
312				final OnPresenceSelected callback = new OnPresenceSelected() {
313					@Override
314					public void onPresenceSelected() {
315						Message message = new Message(conversation,share.text, conversation.getNextEncryption());
316						if (conversation.getNextEncryption() == Message.ENCRYPTION_OTR) {
317							message.setCounterpart(conversation.getNextCounterpart());
318						}
319						xmppConnectionService.sendMessage(message);
320						replaceToast(getString(R.string.shared_text_with_x, conversation.getName()));
321						finish();
322					}
323				};
324				if (conversation.getNextEncryption() == Message.ENCRYPTION_OTR) {
325					selectPresence(conversation, callback);
326				} else {
327					callback.onPresenceSelected();
328				}
329			} else {
330				switchToConversation(conversation, this.share.text, true);
331			}
332		}
333
334	}
335
336	public void refreshUiReal() {
337		xmppConnectionService.populateWithOrderedConversations(mConversations, this.share != null && this.share.uris.size() == 0);
338		mAdapter.notifyDataSetChanged();
339	}
340
341	@Override
342	public void onBackPressed() {
343		if (attachmentCounter.get() >= 1) {
344			replaceToast(getString(R.string.sharing_files_please_wait));
345		} else {
346			super.onBackPressed();
347		}
348	}
349}