aboutsummaryrefslogtreecommitdiffstats
path: root/src/eu
diff options
context:
space:
mode:
Diffstat (limited to 'src/eu')
-rw-r--r--src/eu/siacs/conversations/Config.java2
-rw-r--r--src/eu/siacs/conversations/entities/Account.java27
-rw-r--r--src/eu/siacs/conversations/entities/Conversation.java46
-rw-r--r--src/eu/siacs/conversations/entities/Downloadable.java3
-rw-r--r--src/eu/siacs/conversations/http/HttpConnection.java72
-rw-r--r--src/eu/siacs/conversations/http/HttpConnectionManager.java2
-rw-r--r--src/eu/siacs/conversations/parser/MessageParser.java8
-rw-r--r--src/eu/siacs/conversations/parser/PresenceParser.java3
-rw-r--r--src/eu/siacs/conversations/persistance/DatabaseBackend.java10
-rw-r--r--src/eu/siacs/conversations/services/NotificationService.java27
-rw-r--r--src/eu/siacs/conversations/services/XmppConnectionService.java43
-rw-r--r--src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java2
-rw-r--r--src/eu/siacs/conversations/ui/adapter/MessageAdapter.java45
-rw-r--r--src/eu/siacs/conversations/xmpp/XmppConnection.java36
-rw-r--r--src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java27
15 files changed, 213 insertions, 140 deletions
diff --git a/src/eu/siacs/conversations/Config.java b/src/eu/siacs/conversations/Config.java
index a11e1763..1725eca6 100644
--- a/src/eu/siacs/conversations/Config.java
+++ b/src/eu/siacs/conversations/Config.java
@@ -10,7 +10,7 @@ public final class Config {
public static final int PING_MIN_INTERVAL = 30;
public static final int PING_TIMEOUT = 10;
public static final int CONNECT_TIMEOUT = 90;
- public static final int CARBON_GRACE_PERIOD = 120;
+ public static final int CARBON_GRACE_PERIOD = 60;
public static final int AVATAR_SIZE = 192;
public static final Bitmap.CompressFormat AVATAR_FORMAT = Bitmap.CompressFormat.WEBP;
diff --git a/src/eu/siacs/conversations/entities/Account.java b/src/eu/siacs/conversations/entities/Account.java
index 9b1cbcab..ff509ba1 100644
--- a/src/eu/siacs/conversations/entities/Account.java
+++ b/src/eu/siacs/conversations/entities/Account.java
@@ -11,6 +11,7 @@ import net.java.otr4j.crypto.OtrCryptoException;
import org.json.JSONException;
import org.json.JSONObject;
+import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.crypto.OtrEngine;
import eu.siacs.conversations.persistance.FileBackend;
@@ -21,6 +22,7 @@ import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
+import android.os.SystemClock;
public class Account extends AbstractEntity {
@@ -64,16 +66,14 @@ public class Account extends AbstractEntity {
protected boolean online = false;
- transient OtrEngine otrEngine = null;
- transient XmppConnection xmppConnection = null;
- transient protected Presences presences = new Presences();
-
+ private OtrEngine otrEngine = null;
+ private XmppConnection xmppConnection = null;
+ private Presences presences = new Presences();
+ private long mEndGracePeriod = 0L;
private String otrFingerprint;
-
private Roster roster = null;
-
+
private List<Bookmark> bookmarks = new CopyOnWriteArrayList<Bookmark>();
-
public List<Conversation> pendingConferenceJoins = new CopyOnWriteArrayList<Conversation>();
public List<Conversation> pendingConferenceLeaves = new CopyOnWriteArrayList<Conversation>();
@@ -401,4 +401,17 @@ public class Account extends AbstractEntity {
return R.string.account_status_unknown;
}
}
+
+ public void activateGracePeriod() {
+ this.mEndGracePeriod = SystemClock.elapsedRealtime()
+ + (Config.CARBON_GRACE_PERIOD * 1000);
+ }
+
+ public void deactivateGracePeriod() {
+ this.mEndGracePeriod = 0L;
+ }
+
+ public boolean inGracePeriod() {
+ return SystemClock.elapsedRealtime() < this.mEndGracePeriod;
+ }
}
diff --git a/src/eu/siacs/conversations/entities/Conversation.java b/src/eu/siacs/conversations/entities/Conversation.java
index 5f204ec2..600b9d38 100644
--- a/src/eu/siacs/conversations/entities/Conversation.java
+++ b/src/eu/siacs/conversations/entities/Conversation.java
@@ -1,8 +1,8 @@
package eu.siacs.conversations.entities;
import java.security.interfaces.DSAPublicKey;
+import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
import org.json.JSONException;
import org.json.JSONObject;
@@ -57,7 +57,7 @@ public class Conversation extends AbstractEntity {
private String nextPresence;
- private transient CopyOnWriteArrayList<Message> messages = null;
+ private transient ArrayList<Message> messages = new ArrayList<Message>();
private transient Account account = null;
private transient SessionImpl otrSession;
@@ -72,8 +72,6 @@ public class Conversation extends AbstractEntity {
private byte[] symmetricKey;
- private boolean otrSessionNeedsStarting = false;
-
private Bookmark bookmark;
public Conversation(String name, Account account, String contactJid,
@@ -106,17 +104,6 @@ public class Conversation extends AbstractEntity {
}
public List<Message> getMessages() {
- if (messages == null) {
- this.messages = new CopyOnWriteArrayList<Message>(); // prevent null
- // pointer
- }
-
- // populate with Conversation (this)
-
- for (Message msg : messages) {
- msg.setConversation(this);
- }
-
return messages;
}
@@ -167,7 +154,7 @@ public class Conversation extends AbstractEntity {
}
}
- public void setMessages(CopyOnWriteArrayList<Message> msgs) {
+ public void setMessages(ArrayList<Message> msgs) {
this.messages = msgs;
}
@@ -264,10 +251,7 @@ public class Conversation extends AbstractEntity {
try {
if (sendStart) {
this.otrSession.startSession();
- this.otrSessionNeedsStarting = false;
return this.otrSession;
- } else {
- this.otrSessionNeedsStarting = true;
}
return this.otrSession;
} catch (OtrException e) {
@@ -283,12 +267,12 @@ public class Conversation extends AbstractEntity {
public void resetOtrSession() {
this.otrFingerprint = null;
- this.otrSessionNeedsStarting = false;
this.otrSession = null;
}
public void startOtrIfNeeded() {
- if (this.otrSession != null && this.otrSessionNeedsStarting) {
+ if (this.otrSession != null
+ && this.otrSession.getSessionStatus() != SessionStatus.ENCRYPTED) {
try {
this.otrSession.startSession();
} catch (OtrException e) {
@@ -297,18 +281,23 @@ public class Conversation extends AbstractEntity {
}
}
- public void endOtrIfNeeded() {
+ public boolean endOtrIfNeeded() {
if (this.otrSession != null) {
if (this.otrSession.getSessionStatus() == SessionStatus.ENCRYPTED) {
try {
this.otrSession.endSession();
this.resetOtrSession();
+ return true;
} catch (OtrException e) {
this.resetOtrSession();
+ return false;
}
} else {
this.resetOtrSession();
+ return false;
}
+ } else {
+ return false;
}
}
@@ -507,4 +496,17 @@ public class Conversation extends AbstractEntity {
}
}
}
+
+ public void add(Message message) {
+ message.setConversation(this);
+ synchronized (this.messages) {
+ this.messages.add(message);
+ }
+ }
+
+ public void addAll(int index, List<Message> messages) {
+ synchronized (this.messages) {
+ this.messages.addAll(index, messages);
+ }
+ }
}
diff --git a/src/eu/siacs/conversations/entities/Downloadable.java b/src/eu/siacs/conversations/entities/Downloadable.java
index c8ca599f..70516b20 100644
--- a/src/eu/siacs/conversations/entities/Downloadable.java
+++ b/src/eu/siacs/conversations/entities/Downloadable.java
@@ -11,8 +11,9 @@ public interface Downloadable {
public static final int STATUS_OFFER = 0x203;
public static final int STATUS_DOWNLOADING = 0x204;
public static final int STATUS_DELETED = 0x205;
+ public static final int STATUS_OFFER_CHECK_FILESIZE = 0x206;
- public void start();
+ public boolean start();
public int getStatus();
diff --git a/src/eu/siacs/conversations/http/HttpConnection.java b/src/eu/siacs/conversations/http/HttpConnection.java
index 34036412..3eb8bb84 100644
--- a/src/eu/siacs/conversations/http/HttpConnection.java
+++ b/src/eu/siacs/conversations/http/HttpConnection.java
@@ -6,8 +6,13 @@ import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.X509TrustManager;
import android.content.Intent;
import android.graphics.BitmapFactory;
@@ -35,9 +40,18 @@ public class HttpConnection implements Downloadable {
}
@Override
- public void start() {
- changeStatus(STATUS_DOWNLOADING);
- new Thread(new FileDownloader()).start();
+ public boolean start() {
+ if (mXmppConnectionService.hasInternetConnection()) {
+ if (this.mStatus == STATUS_OFFER_CHECK_FILESIZE) {
+ checkFileSize(true);
+ } else {
+ changeStatus(STATUS_DOWNLOADING);
+ new Thread(new FileDownloader()).start();
+ }
+ return true;
+ } else {
+ return false;
+ }
}
public void init(Message message) {
@@ -45,25 +59,24 @@ public class HttpConnection implements Downloadable {
this.message.setDownloadable(this);
try {
mUrl = new URL(message.getBody());
- this.file = mXmppConnectionService.getFileBackend()
- .getFile(message, false);
+ this.file = mXmppConnectionService.getFileBackend().getFile(
+ message, false);
this.mAutostart = true;
- checkFileSize();
+ checkFileSize(false);
} catch (MalformedURLException e) {
this.cancel();
}
}
- private void checkFileSize() {
+ private void checkFileSize(boolean interactive) {
changeStatus(STATUS_CHECKING);
- new Thread(new FileSizeChecker()).start();
+ new Thread(new FileSizeChecker(interactive)).start();
}
public void cancel() {
mHttpConnectionManager.finishConnection(this);
message.setDownloadable(null);
- message.setBody(mUrl.toString());
- mXmppConnectionService.updateMessage(message);
+ mXmppConnectionService.updateConversationUi();
}
private void finish() {
@@ -78,34 +91,62 @@ public class HttpConnection implements Downloadable {
this.mStatus = status;
mXmppConnectionService.updateConversationUi();
}
+
+ private void setupTrustManager(HttpsURLConnection connection, boolean interactive) {
+ X509TrustManager trustManager;
+ if (interactive) {
+ trustManager = mXmppConnectionService.getMemorizingTrustManager();
+ } else {
+ trustManager = mXmppConnectionService.getMemorizingTrustManager().getNonInteractive();
+ }
+ try {
+ SSLContext sc = SSLContext.getInstance("TLS");
+ sc.init(null,new X509TrustManager[] { trustManager },mXmppConnectionService.getRNG());
+ connection.setSSLSocketFactory(sc.getSocketFactory());
+ } catch (KeyManagementException e) {
+ return;
+ } catch (NoSuchAlgorithmException e) {
+ return;
+ }
+ }
private class FileSizeChecker implements Runnable {
+
+ private boolean interactive = false;
+
+ public FileSizeChecker(boolean interactive) {
+ this.interactive = interactive;
+ }
@Override
public void run() {
long size;
try {
size = retrieveFileSize();
+ } catch (SSLHandshakeException e) {
+ changeStatus(STATUS_OFFER_CHECK_FILESIZE);
+ return;
} catch (IOException e) {
cancel();
return;
}
file.setExpectedSize(size);
- message.setType(Message.TYPE_IMAGE);
- if (size <= mHttpConnectionManager.getAutoAcceptFileSize() && mAutostart) {
+ if (size <= mHttpConnectionManager.getAutoAcceptFileSize()
+ && mAutostart) {
start();
} else {
changeStatus(STATUS_OFFER);
}
}
- private long retrieveFileSize() throws IOException {
+ private long retrieveFileSize() throws IOException, SSLHandshakeException {
HttpURLConnection connection = (HttpURLConnection) mUrl
.openConnection();
connection.setRequestMethod("HEAD");
if (connection instanceof HttpsURLConnection) {
-
+ setupTrustManager((HttpsURLConnection) connection, interactive);
}
+ connection.connect();
String contentLength = connection.getHeaderField("Content-Length");
if (contentLength == null) {
throw new IOException();
@@ -136,7 +177,7 @@ public class HttpConnection implements Downloadable {
HttpURLConnection connection = (HttpURLConnection) mUrl
.openConnection();
if (connection instanceof HttpsURLConnection) {
-
+ setupTrustManager((HttpsURLConnection) connection, true);
}
BufferedInputStream is = new BufferedInputStream(
connection.getInputStream());
@@ -159,6 +200,7 @@ public class HttpConnection implements Downloadable {
int imageWidth = options.outWidth;
message.setBody(mUrl.toString() + "," + file.getSize() + ','
+ imageWidth + ',' + imageHeight);
+ message.setType(Message.TYPE_IMAGE);
mXmppConnectionService.updateMessage(message);
}
diff --git a/src/eu/siacs/conversations/http/HttpConnectionManager.java b/src/eu/siacs/conversations/http/HttpConnectionManager.java
index ff71d45c..9a2a2405 100644
--- a/src/eu/siacs/conversations/http/HttpConnectionManager.java
+++ b/src/eu/siacs/conversations/http/HttpConnectionManager.java
@@ -1,11 +1,9 @@
package eu.siacs.conversations.http;
-import java.net.URL;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import eu.siacs.conversations.entities.Message;
-import eu.siacs.conversations.entities.Message.ImageParams;
import eu.siacs.conversations.services.AbstractConnectionManager;
import eu.siacs.conversations.services.XmppConnectionService;
diff --git a/src/eu/siacs/conversations/parser/MessageParser.java b/src/eu/siacs/conversations/parser/MessageParser.java
index 486dd389..daf0174c 100644
--- a/src/eu/siacs/conversations/parser/MessageParser.java
+++ b/src/eu/siacs/conversations/parser/MessageParser.java
@@ -417,8 +417,7 @@ public class MessageParser extends AbstractParser implements
message = this.parseCarbonMessage(packet, account);
if (message != null) {
if (message.getStatus() == Message.STATUS_SEND) {
- mXmppConnectionService.getNotificationService()
- .activateGracePeriod();
+ account.activateGracePeriod();
notify = false;
mXmppConnectionService.markRead(
message.getConversation(), false);
@@ -440,8 +439,7 @@ public class MessageParser extends AbstractParser implements
} else {
mXmppConnectionService.markRead(message.getConversation(),
false);
- mXmppConnectionService.getNotificationService()
- .activateGracePeriod();
+ account.activateGracePeriod();
notify = false;
}
}
@@ -471,7 +469,7 @@ public class MessageParser extends AbstractParser implements
}
}
Conversation conversation = message.getConversation();
- conversation.getMessages().add(message);
+ conversation.add(message);
if (packet.getType() != MessagePacket.TYPE_ERROR) {
if (message.getEncryption() == Message.ENCRYPTION_NONE
|| mXmppConnectionService.saveEncryptedMessages()) {
diff --git a/src/eu/siacs/conversations/parser/PresenceParser.java b/src/eu/siacs/conversations/parser/PresenceParser.java
index 2c3a7dbc..d54ddca0 100644
--- a/src/eu/siacs/conversations/parser/PresenceParser.java
+++ b/src/eu/siacs/conversations/parser/PresenceParser.java
@@ -58,8 +58,7 @@ public class PresenceParser extends AbstractParser implements
Presences.parseShow(packet.findChild("show")));
} else if (type.equals("unavailable")) {
account.removePresence(fromParts[1]);
- mXmppConnectionService.getNotificationService()
- .deactivateGracePeriod();
+ account.deactivateGracePeriod();
}
}
} else {
diff --git a/src/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/eu/siacs/conversations/persistance/DatabaseBackend.java
index d90b5c62..d3d6ccf2 100644
--- a/src/eu/siacs/conversations/persistance/DatabaseBackend.java
+++ b/src/eu/siacs/conversations/persistance/DatabaseBackend.java
@@ -152,14 +152,14 @@ public class DatabaseBackend extends SQLiteOpenHelper {
return list;
}
- public CopyOnWriteArrayList<Message> getMessages(
+ public ArrayList<Message> getMessages(
Conversation conversations, int limit) {
return getMessages(conversations, limit, -1);
}
- public CopyOnWriteArrayList<Message> getMessages(Conversation conversation,
+ public ArrayList<Message> getMessages(Conversation conversation,
int limit, long timestamp) {
- CopyOnWriteArrayList<Message> list = new CopyOnWriteArrayList<Message>();
+ ArrayList<Message> list = new ArrayList<Message>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor;
if (timestamp == -1) {
@@ -178,7 +178,9 @@ public class DatabaseBackend extends SQLiteOpenHelper {
if (cursor.getCount() > 0) {
cursor.moveToLast();
do {
- list.add(Message.fromCursor(cursor));
+ Message message = Message.fromCursor(cursor);
+ message.setConversation(conversation);
+ list.add(message);
} while (cursor.moveToPrevious());
}
return list;
diff --git a/src/eu/siacs/conversations/services/NotificationService.java b/src/eu/siacs/conversations/services/NotificationService.java
index e65085fb..0b30e58e 100644
--- a/src/eu/siacs/conversations/services/NotificationService.java
+++ b/src/eu/siacs/conversations/services/NotificationService.java
@@ -13,13 +13,12 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.PowerManager;
-import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.text.Html;
-import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
+import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.ui.ConversationActivity;
@@ -34,9 +33,7 @@ public class NotificationService {
public int NOTIFICATION_ID = 0x2342;
private Conversation mOpenConversation;
private boolean mIsInForeground;
-
- private long mEndGracePeriod = 0L;
-
+
public NotificationService(XmppConnectionService service) {
this.mXmppConnectionService = service;
this.mNotificationManager = (NotificationManager) service
@@ -62,8 +59,9 @@ public class NotificationService {
notifications.put(conversationUuid, mList);
}
}
+ Account account = message.getConversation().getAccount();
updateNotification((!(this.mIsInForeground && this.mOpenConversation == null) || !isScreenOn)
- && !inGracePeriod());
+ && !account.inGracePeriod());
}
public void clear() {
@@ -170,9 +168,7 @@ public class NotificationService {
}
}
mBuilder.setDeleteIntent(createDeleteIntent());
- if (!inGracePeriod()) {
- mBuilder.setLights(0xffffffff, 2000, 4000);
- }
+ mBuilder.setLights(0xffffffff, 2000, 4000);
Notification notification = mBuilder.build();
mNotificationManager.notify(NOTIFICATION_ID, notification);
}
@@ -231,17 +227,4 @@ public class NotificationService {
public void setIsInForeground(boolean foreground) {
this.mIsInForeground = foreground;
}
-
- public void activateGracePeriod() {
- this.mEndGracePeriod = SystemClock.elapsedRealtime()
- + (Config.CARBON_GRACE_PERIOD * 1000);
- }
-
- public void deactivateGracePeriod() {
- this.mEndGracePeriod = 0L;
- }
-
- private boolean inGracePeriod() {
- return SystemClock.elapsedRealtime() < this.mEndGracePeriod;
- }
}
diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java
index 9a540df0..f557c3e1 100644
--- a/src/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/eu/siacs/conversations/services/XmppConnectionService.java
@@ -346,15 +346,10 @@ public class XmppConnectionService extends Service {
}
}
this.wakeLock.acquire();
- ConnectivityManager cm = (ConnectivityManager) getApplicationContext()
- .getSystemService(Context.CONNECTIVITY_SERVICE);
- NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
- boolean isConnected = activeNetwork != null
- && activeNetwork.isConnected();
-
+
for (Account account : accounts) {
if (!account.isOptionSet(Account.OPTION_DISABLED)) {
- if (!isConnected) {
+ if (!hasInternetConnection()) {
account.setStatus(Account.STATUS_NO_INTERNET);
if (statusListener != null) {
statusListener.onStatusChanged(account);
@@ -412,6 +407,13 @@ public class XmppConnectionService extends Service {
}
return START_STICKY;
}
+
+ public boolean hasInternetConnection() {
+ ConnectivityManager cm = (ConnectivityManager) getApplicationContext()
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
+ return activeNetwork != null && activeNetwork.isConnected();
+ }
@SuppressLint("TrulyRandom")
@Override
@@ -527,8 +529,9 @@ public class XmppConnectionService extends Service {
return connection;
}
- synchronized public void sendMessage(Message message) {
+ public void sendMessage(Message message) {
Account account = message.getConversation().getAccount();
+ account.deactivateGracePeriod();
Conversation conv = message.getConversation();
MessagePacket packet = null;
boolean saveInDb = true;
@@ -612,7 +615,7 @@ public class XmppConnectionService extends Service {
}
}
- conv.getMessages().add(message);
+ conv.add(message);
if (saveInDb) {
if (message.getEncryption() == Message.ENCRYPTION_NONE
|| saveEncryptedMessages()) {
@@ -878,7 +881,7 @@ public class XmppConnectionService extends Service {
for (Message message : messages) {
message.setConversation(conversation);
}
- conversation.getMessages().addAll(0, messages);
+ conversation.addAll(0, messages);
return messages.size();
}
@@ -1019,7 +1022,6 @@ public class XmppConnectionService extends Service {
return;
}
synchronized (this.convChangedListenerCount) {
- this.mNotificationService.deactivateGracePeriod();
if (checkListeners()) {
switchToForeground();
}
@@ -1049,7 +1051,6 @@ public class XmppConnectionService extends Service {
return;
}
synchronized (this.accountChangedListenerCount) {
- this.mNotificationService.deactivateGracePeriod();
if (checkListeners()) {
switchToForeground();
}
@@ -1077,7 +1078,6 @@ public class XmppConnectionService extends Service {
return;
}
synchronized (this.rosterChangedListenerCount) {
- this.mNotificationService.deactivateGracePeriod();
if (checkListeners()) {
switchToForeground();
}
@@ -1110,11 +1110,10 @@ public class XmppConnectionService extends Service {
XmppConnection connection = account.getXmppConnection();
if (connection != null && connection.getFeatures().csi()) {
connection.sendActive();
- Log.d(Config.LOGTAG, account.getJid()
- + " sending csi//active");
}
}
}
+ Log.d(Config.LOGTAG,"app switched into foreground");
}
private void switchToBackground() {
@@ -1123,11 +1122,11 @@ public class XmppConnectionService extends Service {
XmppConnection connection = account.getXmppConnection();
if (connection != null && connection.getFeatures().csi()) {
connection.sendInactive();
- Log.d(Config.LOGTAG, account.getJid()
- + " sending csi//inactive");
}
}
}
+ this.mNotificationService.setIsInForeground(false);
+ Log.d(Config.LOGTAG,"app switched into background");
}
private boolean isScreenOn() {
@@ -1271,7 +1270,7 @@ public class XmppConnectionService extends Service {
conversation.getMucOptions().setOffline();
conversation.deregisterWithBookmark();
Log.d(Config.LOGTAG, conversation.getAccount().getJid()
- + " leaving muc " + conversation.getContactJid());
+ + ": leaving muc " + conversation.getContactJid());
} else {
account.pendingConferenceLeaves.add(conversation);
}
@@ -1288,7 +1287,9 @@ public class XmppConnectionService extends Service {
if (conversation.getMode() == Conversation.MODE_MULTI) {
leaveMuc(conversation);
} else {
- conversation.endOtrIfNeeded();
+ if (conversation.endOtrIfNeeded()) {
+ Log.d(Config.LOGTAG,account.getJid()+": ended otr session with "+conversation.getContactJid());
+ }
}
}
}
@@ -1874,8 +1875,8 @@ public class XmppConnectionService extends Service {
private class DeletedDownloadable implements Downloadable {
@Override
- public void start() {
- return;
+ public boolean start() {
+ return false;
}
@Override
diff --git a/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java
index bd37f7fc..20c7bee2 100644
--- a/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java
+++ b/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java
@@ -92,6 +92,8 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
mLastMessage.setText(R.string.receiving_image);
} else if (d.getStatus() == Downloadable.STATUS_OFFER) {
mLastMessage.setText(R.string.image_offered_for_download);
+ } else if (d.getStatus() == Downloadable.STATUS_OFFER_CHECK_FILESIZE) {
+ mLastMessage.setText(R.string.image_offered_for_download);
} else if (d.getStatus() == Downloadable.STATUS_DELETED) {
mLastMessage.setText(R.string.image_file_deleted);
} else {
diff --git a/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java
index 24a824b3..db783b7f 100644
--- a/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java
+++ b/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java
@@ -102,7 +102,8 @@ public class MessageAdapter extends ArrayAdapter<Message> {
}
boolean multiReceived = message.getConversation().getMode() == Conversation.MODE_MULTI
&& message.getMergedStatus() <= Message.STATUS_RECEIVED;
- if (message.getType() == Message.TYPE_IMAGE) {
+ if (message.getType() == Message.TYPE_IMAGE
+ || message.getDownloadable() != null) {
ImageParams params = message.getImageParams();
if (params.size != 0) {
filesize = params.size / 1024 + " KB";
@@ -262,6 +263,21 @@ public class MessageAdapter extends ArrayAdapter<Message> {
viewHolder.messageBody.setTextIsSelectable(true);
}
+ private void displayDownloadableMessage(ViewHolder viewHolder,
+ final Message message, int resid) {
+ viewHolder.image.setVisibility(View.GONE);
+ viewHolder.messageBody.setVisibility(View.GONE);
+ viewHolder.download_button.setVisibility(View.VISIBLE);
+ viewHolder.download_button.setText(resid);
+ viewHolder.download_button.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ startDonwloadable(message);
+ }
+ });
+ }
+
private void displayImageMessage(ViewHolder viewHolder,
final Message message) {
if (viewHolder.download_button != null) {
@@ -474,20 +490,13 @@ public class MessageAdapter extends ArrayAdapter<Message> {
} else if (d != null
&& d.getStatus() == Downloadable.STATUS_CHECKING) {
displayInfoMessage(viewHolder, R.string.checking_image);
- } else if (d != null && d.getStatus() == Downloadable.STATUS_DELETED) {
+ } else if (d != null
+ && d.getStatus() == Downloadable.STATUS_DELETED) {
displayInfoMessage(viewHolder, R.string.image_file_deleted);
} else if (d != null && d.getStatus() == Downloadable.STATUS_OFFER) {
- viewHolder.image.setVisibility(View.GONE);
- viewHolder.messageBody.setVisibility(View.GONE);
- viewHolder.download_button.setVisibility(View.VISIBLE);
- viewHolder.download_button
- .setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- startDonwloadable(item);
- }
- });
+ displayDownloadableMessage(viewHolder, item,R.string.download_image);
+ } else if (d != null && d.getStatus() == Downloadable.STATUS_OFFER_CHECK_FILESIZE) {
+ displayDownloadableMessage(viewHolder, item,R.string.check_image_filesize);
} else if ((item.getEncryption() == Message.ENCRYPTION_DECRYPTED)
|| (item.getEncryption() == Message.ENCRYPTION_NONE)
|| (item.getEncryption() == Message.ENCRYPTION_OTR)) {
@@ -525,13 +534,13 @@ public class MessageAdapter extends ArrayAdapter<Message> {
return view;
}
- public boolean startDonwloadable(Message message) {
+ public void startDonwloadable(Message message) {
Downloadable downloadable = message.getDownloadable();
if (downloadable != null) {
- downloadable.start();
- return true;
- } else {
- return false;
+ if (!downloadable.start()) {
+ Toast.makeText(activity, R.string.not_connected_try_again,
+ Toast.LENGTH_SHORT).show();
+ }
}
}
diff --git a/src/eu/siacs/conversations/xmpp/XmppConnection.java b/src/eu/siacs/conversations/xmpp/XmppConnection.java
index 0ae51fb5..0252d80e 100644
--- a/src/eu/siacs/conversations/xmpp/XmppConnection.java
+++ b/src/eu/siacs/conversations/xmpp/XmppConnection.java
@@ -86,6 +86,7 @@ public class XmppConnection implements Runnable {
private SparseArray<String> messageReceipts = new SparseArray<String>();
private boolean usingCompression = false;
+ private boolean usingEncryption = false;
private int stanzasReceived = 0;
private int stanzasSent = 0;
@@ -143,6 +144,7 @@ public class XmppConnection implements Runnable {
protected void connect() {
Log.d(Config.LOGTAG, account.getJid() + ": connecting");
usingCompression = false;
+ usingEncryption = false;
lastConnect = SystemClock.elapsedRealtime();
lastPingSent = SystemClock.elapsedRealtime();
this.attempt++;
@@ -169,10 +171,23 @@ public class XmppConnection implements Runnable {
+ "[" + srvIpServer + "]:" + srvRecordPort);
socket = new Socket(srvIpServer, srvRecordPort);
} else {
- Log.d(Config.LOGTAG, account.getJid()
- + ": using values from dns " + srvRecordServer
- + ":" + srvRecordPort);
- socket = new Socket(srvRecordServer, srvRecordPort);
+ boolean socketError = true;
+ int srvIndex = 0;
+ while (socketError && namePort.containsKey("name" + srvIndex)){
+ try {
+ srvRecordServer = namePort.getString("name" + srvIndex);
+ srvRecordPort = namePort.getInt("port" + srvIndex);
+ Log.d(Config.LOGTAG, account.getJid()
+ + ": using values from dns " + srvRecordServer
+ + ":" + srvRecordPort);
+ socket = new Socket(srvRecordServer, srvRecordPort);
+ socketError = false;
+ } catch (UnknownHostException e) {
+ srvIndex++;
+ } catch (IOException e) {
+ srvIndex++;
+ }
+ }
}
} else if (namePort.containsKey("error")
&& "nosrv".equals(namePort.getString("error", null))) {
@@ -564,6 +579,7 @@ public class XmppConnection implements Runnable {
sendStartStream();
Log.d(Config.LOGTAG, account.getJid()
+ ": TLS connection established");
+ usingEncryption = true;
processStream(tagReader.readTag());
sslSocket.close();
} catch (NoSuchAlgorithmException e1) {
@@ -593,20 +609,19 @@ public class XmppConnection implements Runnable {
private void processStreamFeatures(Tag currentTag)
throws XmlPullParserException, IOException {
this.streamFeatures = tagReader.readElement(currentTag);
- if (this.streamFeatures.hasChild("starttls")
- && account.isOptionSet(Account.OPTION_USETLS)) {
+ if (this.streamFeatures.hasChild("starttls") && !usingEncryption) {
sendStartTLS();
} else if (compressionAvailable()) {
sendCompressionZlib();
} else if (this.streamFeatures.hasChild("register")
- && (account.isOptionSet(Account.OPTION_REGISTER))) {
+ && account.isOptionSet(Account.OPTION_REGISTER) && usingEncryption) {
sendRegistryRequest();
} else if (!this.streamFeatures.hasChild("register")
- && (account.isOptionSet(Account.OPTION_REGISTER))) {
+ && account.isOptionSet(Account.OPTION_REGISTER)) {
changeStatus(Account.STATUS_REGISTRATION_NOT_SUPPORTED);
disconnect(true);
} else if (this.streamFeatures.hasChild("mechanisms")
- && shouldAuthenticate) {
+ && shouldAuthenticate && usingEncryption) {
List<String> mechanisms = extractMechanisms(streamFeatures
.findChild("mechanisms"));
if (mechanisms.contains("PLAIN")) {
@@ -622,6 +637,9 @@ public class XmppConnection implements Runnable {
this.tagWriter.writeStanzaAsync(resume);
} else if (this.streamFeatures.hasChild("bind") && shouldBind) {
sendBindRequest();
+ } else {
+ Log.d(Config.LOGTAG,account.getJid()+": incompatible server. disconnecting");
+ disconnect(true);
}
}
diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java
index bfc3c18c..5b3dfbff 100644
--- a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java
+++ b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java
@@ -307,7 +307,7 @@ public class JingleConnection implements Downloadable {
if (supportedFile) {
long size = Long.parseLong(fileSize.getContent());
message.setBody(Long.toString(size));
- conversation.getMessages().add(message);
+ conversation.add(message);
mXmppConnectionService.updateConversationUi();
if (size <= this.mJingleConnectionManager
.getAutoAcceptFileSize()) {
@@ -634,6 +634,7 @@ public class JingleConnection implements Downloadable {
}
private void sendFallbackToIbb() {
+ Log.d(Config.LOGTAG,"sending fallback to ibb");
JinglePacket packet = this.bootstrapPacket("transport-replace");
Content content = new Content(this.contentCreator, this.contentName);
this.transportId = this.mJingleConnectionManager.nextRandomId();
@@ -645,6 +646,7 @@ public class JingleConnection implements Downloadable {
}
private boolean receiveFallbackToIbb(JinglePacket packet) {
+ Log.d(Config.LOGTAG,"receiving fallack to ibb");
String receivedBlockSize = packet.getJingleContent().ibbTransport()
.getAttribute("block-size");
if (receivedBlockSize != null) {
@@ -875,17 +877,20 @@ public class JingleConnection implements Downloadable {
return this.transport;
}
- public void start() {
- if (mJingleStatus == JINGLE_STATUS_INITIATED) {
- new Thread(new Runnable() {
-
- @Override
- public void run() {
- sendAccept();
- }
- }).start();
+ public boolean start() {
+ if (account.getStatus() == Account.STATUS_ONLINE) {
+ if (mJingleStatus == JINGLE_STATUS_INITIATED) {
+ new Thread(new Runnable() {
+
+ @Override
+ public void run() {
+ sendAccept();
+ }
+ }).start();
+ }
+ return true;
} else {
- Log.d(Config.LOGTAG, "status (" + mJingleStatus + ") was not ok");
+ return false;
}
}