aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsteckbrief <steckbrief@chefmail.de>2016-05-13 11:23:45 +0200
committersteckbrief <steckbrief@chefmail.de>2016-05-13 11:23:45 +0200
commit351db27a77c200e526b86c318213b72cd65d1b7b (patch)
tree7802de24b0666d1a28ecffec0280d74173642d2b
parent70938a31a0e78203449d769fa5bda15ce73d1ed4 (diff)
parent10e607ac51dcc42fa1b54bacb698beed43750de7 (diff)
Merge branch 'master' into message_display_rework
-rw-r--r--gradle/wrapper/gradle-wrapper.properties2
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ConversationsPlusApplication.java3
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/crypto/PgpEngine.java8
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/crypto/axolotl/AxolotlServiceImpl.java3
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/entities/Conversation.java1
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/entities/Message.java17
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/generator/MessageGenerator.java4
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/http/HttpUploadConnection.java6
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/parser/MessageParser.java14
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/persistance/CursorHelper.java203
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/persistance/DatabaseBackend.java60
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/persistance/FileBackend.java42
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/persistance/MessageDatabaseAccess.java59
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/persistance/observers/FileDeletionObserver.java45
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java138
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/ConversationActivity.java5
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java3
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/SettingsActivity.java8
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/ShareWithActivity.java5
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/dialogs/MessageDetailsDialog.java21
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/listeners/ResizePictureUserDecisionListener.java7
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/utils/ConversationUtil.java75
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java29
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/utils/XmppConnectionServiceAccessor.java31
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/utils/ui/TextViewUtil.java16
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/httpuploadim/HttpUploadHint.java15
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java14
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnectionManager.java3
-rw-r--r--src/main/res/layout/dialog_message_details.xml22
-rw-r--r--src/main/res/values/strings.xml1
30 files changed, 681 insertions, 179 deletions
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 61de9bb3..e1adff10 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.12-all.zip
+distributionUrl=http\://services.gradle.org/distributions/gradle-2.12-all.zip
diff --git a/src/main/java/de/thedevstack/conversationsplus/ConversationsPlusApplication.java b/src/main/java/de/thedevstack/conversationsplus/ConversationsPlusApplication.java
index d2eb77b7..a9f0c6ad 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ConversationsPlusApplication.java
+++ b/src/main/java/de/thedevstack/conversationsplus/ConversationsPlusApplication.java
@@ -9,7 +9,6 @@ import java.io.File;
import de.thedevstack.conversationsplus.persistance.FileBackend;
import de.thedevstack.conversationsplus.utils.ImageUtil;
-import de.thedevstack.conversationsplus.R;
import de.thedevstack.conversationsplus.utils.SerialSingleThreadExecutor;
/**
@@ -32,7 +31,7 @@ public class ConversationsPlusApplication extends Application {
ConversationsPlusApplication.instance = this;
ConversationsPlusPreferences.init(PreferenceManager.getDefaultSharedPreferences(getAppContext()));
ImageUtil.initBitmapCache();
- FileBackend.createNoMedia();
+ FileBackend.init();
}
/**
diff --git a/src/main/java/de/thedevstack/conversationsplus/crypto/PgpEngine.java b/src/main/java/de/thedevstack/conversationsplus/crypto/PgpEngine.java
index 3f6f8ce7..bba52954 100644
--- a/src/main/java/de/thedevstack/conversationsplus/crypto/PgpEngine.java
+++ b/src/main/java/de/thedevstack/conversationsplus/crypto/PgpEngine.java
@@ -33,12 +33,18 @@ import de.thedevstack.conversationsplus.ui.UiCallback;
public class PgpEngine {
private OpenPgpApi api;
private XmppConnectionService mXmppConnectionService;
+ private static PgpEngine INSTANCE;
public PgpEngine(OpenPgpApi api, XmppConnectionService service) {
this.api = api;
this.mXmppConnectionService = service;
+ INSTANCE = this;
}
+ public static PgpEngine getInstance() {
+ return INSTANCE;
+ }
+
public void decrypt(final Message message, final UiCallback<Message> callback) {
Intent params = new Intent();
params.setAction(OpenPgpApi.ACTION_DECRYPT_VERIFY);
@@ -62,7 +68,7 @@ public class PgpEngine {
final HttpConnectionManager manager = mXmppConnectionService.getHttpConnectionManager();
if (message.trusted()
&& message.treatAsDownloadable() != Message.Decision.NEVER
- && ConversationsPlusPreferences.autoDownloadFileLink()
+ && (message.isHttpUploaded() || ConversationsPlusPreferences.autoDownloadFileLink())
&& ConversationsPlusPreferences.autoAcceptFileSize() > 0) {
manager.createNewDownloadConnection(message);
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/crypto/axolotl/AxolotlServiceImpl.java b/src/main/java/de/thedevstack/conversationsplus/crypto/axolotl/AxolotlServiceImpl.java
index f8856f90..4bc27a7d 100644
--- a/src/main/java/de/thedevstack/conversationsplus/crypto/axolotl/AxolotlServiceImpl.java
+++ b/src/main/java/de/thedevstack/conversationsplus/crypto/axolotl/AxolotlServiceImpl.java
@@ -41,6 +41,7 @@ import de.thedevstack.conversationsplus.entities.Message;
import de.thedevstack.conversationsplus.parser.IqParser;
import de.thedevstack.conversationsplus.services.XmppConnectionService;
import de.thedevstack.conversationsplus.utils.CryptoHelper;
+import de.thedevstack.conversationsplus.utils.MessageUtil;
import de.thedevstack.conversationsplus.utils.SerialSingleThreadExecutor;
import de.thedevstack.conversationsplus.xml.Element;
import de.thedevstack.conversationsplus.xmpp.OnAdvancedStreamFeaturesLoaded;
@@ -946,7 +947,7 @@ public class AxolotlServiceImpl implements OnAdvancedStreamFeaturesLoaded, Axolo
public void run() {
XmppAxolotlMessage axolotlMessage = encrypt(message);
if (axolotlMessage == null) {
- mXmppConnectionService.markMessage(message, Message.STATUS_SEND_FAILED);
+ MessageUtil.markMessage(message, Message.STATUS_SEND_FAILED);
//mXmppConnectionService.updateConversationUi();
} else {
Log.d(Config.LOGTAG, AxolotlServiceImpl.getLogprefix(account) + "Generated message, caching: " + message.getUuid());
diff --git a/src/main/java/de/thedevstack/conversationsplus/entities/Conversation.java b/src/main/java/de/thedevstack/conversationsplus/entities/Conversation.java
index 9e9366d7..bfd00b5d 100644
--- a/src/main/java/de/thedevstack/conversationsplus/entities/Conversation.java
+++ b/src/main/java/de/thedevstack/conversationsplus/entities/Conversation.java
@@ -140,6 +140,7 @@ public class Conversation extends AbstractEntity implements Blockable {
}
public Message findMessageWithFileAndUuid(final String uuid) {
+ // TODO Implement this method to find a message by a real filename - not uuid
synchronized (this.messages) {
for (final Message message : this.messages) {
if ((message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE)
diff --git a/src/main/java/de/thedevstack/conversationsplus/entities/Message.java b/src/main/java/de/thedevstack/conversationsplus/entities/Message.java
index 6a6a5e50..b0a5bb3b 100644
--- a/src/main/java/de/thedevstack/conversationsplus/entities/Message.java
+++ b/src/main/java/de/thedevstack/conversationsplus/entities/Message.java
@@ -83,6 +83,8 @@ public class Message extends AbstractEntity {
private String axolotlFingerprint = null;
private Decision mTreatAsDownloadAble = Decision.NOT_DECIDED;
+ private boolean httpUploaded;
+
private Message() {
}
@@ -535,6 +537,10 @@ public class Message extends AbstractEntity {
mTreatAsDownloadAble = Decision.NEVER;
}
+ public void setTreatAsDownloadable(Decision downloadable) {
+ this.mTreatAsDownloadAble = downloadable;
+ }
+
public Decision treatAsDownloadable() {
// only test this ones, body will not change
if (mTreatAsDownloadAble != Decision.NOT_DECIDED) {
@@ -554,9 +560,6 @@ public class Message extends AbstractEntity {
if (!url.getProtocol().equalsIgnoreCase("http") && !url.getProtocol().equalsIgnoreCase("https")) {
mTreatAsDownloadAble = Decision.NEVER;
return mTreatAsDownloadAble;
- } else if (oob) {
- mTreatAsDownloadAble = Decision.MUST;
- return mTreatAsDownloadAble;
}
String extension = extractRelevantExtension(url);
if (extension == null) {
@@ -754,6 +757,14 @@ public class Message extends AbstractEntity {
return inUnencryptedSession || getCleanedEncryption(this.getEncryption()) == pastEncryption;
}
+ public boolean isHttpUploaded() {
+ return httpUploaded;
+ }
+
+ public void setHttpUploaded(boolean httpUploaded) {
+ this.httpUploaded = httpUploaded;
+ }
+
private static int getCleanedEncryption(int encryption) {
if (encryption == ENCRYPTION_DECRYPTED || encryption == ENCRYPTION_DECRYPTION_FAILED) {
return ENCRYPTION_PGP;
diff --git a/src/main/java/de/thedevstack/conversationsplus/generator/MessageGenerator.java b/src/main/java/de/thedevstack/conversationsplus/generator/MessageGenerator.java
index 2e49ebfe..5a1d6f3f 100644
--- a/src/main/java/de/thedevstack/conversationsplus/generator/MessageGenerator.java
+++ b/src/main/java/de/thedevstack/conversationsplus/generator/MessageGenerator.java
@@ -16,6 +16,7 @@ import de.thedevstack.conversationsplus.entities.Conversation;
import de.thedevstack.conversationsplus.entities.Message;
import de.thedevstack.conversationsplus.xml.Element;
import de.thedevstack.conversationsplus.xmpp.chatstate.ChatState;
+import de.thedevstack.conversationsplus.xmpp.httpuploadim.HttpUploadHint;
import de.thedevstack.conversationsplus.xmpp.jid.Jid;
import de.thedevstack.conversationsplus.xmpp.stanzas.MessagePacket;
@@ -112,6 +113,9 @@ public class MessageGenerator extends AbstractGenerator {
if (message.hasFileOnRemoteHost()) {
Message.FileParams fileParams = message.getFileParams();
content = fileParams.url.toString();
+ if (message.isHttpUploaded()) {
+ packet.addChild(new HttpUploadHint());
+ }
packet.addChild("x","jabber:x:oob").addChild("url").setContent(content);
if (fileParams.width > 0 && fileParams.height > 0) {
addXhtmlImImage(packet,fileParams);
diff --git a/src/main/java/de/thedevstack/conversationsplus/http/HttpUploadConnection.java b/src/main/java/de/thedevstack/conversationsplus/http/HttpUploadConnection.java
index 6c546fee..231a6ca7 100644
--- a/src/main/java/de/thedevstack/conversationsplus/http/HttpUploadConnection.java
+++ b/src/main/java/de/thedevstack/conversationsplus/http/HttpUploadConnection.java
@@ -91,12 +91,14 @@ public class HttpUploadConnection implements Transferable {
private void fail() {
mHttpConnectionManager.finishUploadConnection(this);
message.setTransferable(null);
- mXmppConnectionService.markMessage(message, Message.STATUS_SEND_FAILED);
+ MessageUtil.markMessage(message, Message.STATUS_SEND_FAILED);
StreamUtil.close(mFileInputStream);
}
public void init(Message message, boolean delay) {
this.message = message;
+ this.message.setHttpUploaded(true);
+ this.message.setNoDownloadable();
this.account = message.getConversation().getAccount();
this.file = FileBackend.getFile(message, false);
this.mime = this.file.getMimeType();
@@ -143,7 +145,7 @@ public class HttpUploadConnection implements Transferable {
}
});
message.setTransferable(this);
- mXmppConnectionService.markMessage(message, Message.STATUS_UNSEND);
+ MessageUtil.markMessage(message, Message.STATUS_UNSEND);
}
private class FileUploader implements Runnable {
diff --git a/src/main/java/de/thedevstack/conversationsplus/parser/MessageParser.java b/src/main/java/de/thedevstack/conversationsplus/parser/MessageParser.java
index 6fb18266..a8e5929b 100644
--- a/src/main/java/de/thedevstack/conversationsplus/parser/MessageParser.java
+++ b/src/main/java/de/thedevstack/conversationsplus/parser/MessageParser.java
@@ -3,6 +3,8 @@ package de.thedevstack.conversationsplus.parser;
import android.util.Log;
import android.util.Pair;
+import de.thedevstack.conversationsplus.utils.MessageUtil;
+import de.thedevstack.conversationsplus.xmpp.httpuploadim.HttpUploadHint;
import de.tzur.conversations.Settings;
import net.java.otr4j.session.Session;
@@ -342,12 +344,12 @@ public class MessageParser extends AbstractParser implements
if (counterpart.getResourcepart().equals(conversation.getMucOptions().getActualNick())) {
status = Message.STATUS_SEND_RECEIVED;
isCarbon = true; //not really carbon but received from another resource
- if (mXmppConnectionService.markMessage(conversation, remoteMsgId, status)) {
+ if (MessageUtil.markMessage(conversation, remoteMsgId, status)) {
return;
} else if (remoteMsgId == null || Config.IGNORE_ID_REWRITE_IN_MUC) {
Message message = conversation.findSentMessageWithBody(packet.getBody());
if (message != null) {
- mXmppConnectionService.markMessage(message, status);
+ MessageUtil.markMessage(message, status);
return;
}
}
@@ -390,6 +392,10 @@ public class MessageParser extends AbstractParser implements
if (serverMsgId == null) {
serverMsgId = extractStanzaId(packet, isTypeGroupChat ? conversation.getJid().toBareJid() : account.getServer());
}
+ message.setHttpUploaded(packet.hasChild(HttpUploadHint.ELEMENT_NAME, HttpUploadHint.NAMESPACE));
+ if (message.isHttpUploaded()) {
+ message.setTreatAsDownloadable(Message.Decision.MUST);
+ }
message.setCounterpart(counterpart);
message.setRemoteMsgId(remoteMsgId);
@@ -465,7 +471,7 @@ public class MessageParser extends AbstractParser implements
if (message.trusted()
&& message.treatAsDownloadable() != Message.Decision.NEVER
&& ConversationsPlusPreferences.autoAcceptFileSize() > 0
- && ConversationsPlusPreferences.autoDownloadFileLink()) {
+ && (message.isHttpUploaded() || ConversationsPlusPreferences.autoDownloadFileLink())) {
this.mXmppConnectionService.getHttpConnectionManager().createNewDownloadConnection(message);
} else {
if (query == null) {
@@ -530,7 +536,7 @@ public class MessageParser extends AbstractParser implements
while (message != null
&& message.getStatus() == Message.STATUS_SEND_RECEIVED
&& message.getTimeSent() < displayedMessage.getTimeSent()) {
- mXmppConnectionService.markMessage(message, Message.STATUS_SEND_DISPLAYED);
+ MessageUtil.markMessage(message, Message.STATUS_SEND_DISPLAYED);
message = message.prev();
}
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/persistance/CursorHelper.java b/src/main/java/de/thedevstack/conversationsplus/persistance/CursorHelper.java
new file mode 100644
index 00000000..7e3fdab0
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/persistance/CursorHelper.java
@@ -0,0 +1,203 @@
+package de.thedevstack.conversationsplus.persistance;
+
+import android.database.Cursor;
+
+/**
+ * Created by steckbrief on 15.04.2016.
+ */
+public abstract class CursorHelper {
+
+ static double getDouble(Cursor cursor, String columnName) {
+ if (null == cursor) {
+ return Double.MIN_VALUE;
+ }
+ int columnIndex = getColumnIndex(cursor, columnName);
+ if (columnIndex < 0) {
+ return Double.MIN_VALUE;
+ }
+ return getDouble(cursor, columnIndex);
+ }
+
+ static String getString(Cursor cursor, String columnName) {
+ if (null == cursor) {
+ return null;
+ }
+ int columnIndex = getColumnIndex(cursor, columnName);
+ if (columnIndex < 0) {
+ return null;
+ }
+ return getString(cursor, columnIndex);
+ }
+
+ static float getFloat(Cursor cursor, String columnName) {
+ if (null == cursor) {
+ return Float.MIN_VALUE;
+ }
+ int columnIndex = getColumnIndex(cursor, columnName);
+ if (columnIndex < 0) {
+ return Float.MIN_VALUE;
+ }
+ return getFloat(cursor, columnIndex);
+ }
+
+ static int getInt(Cursor cursor, String columnName) {
+ if (null == cursor) {
+ return Integer.MIN_VALUE;
+ }
+ int columnIndex = getColumnIndex(cursor, columnName);
+ if (columnIndex < 0) {
+ return Integer.MIN_VALUE;
+ }
+ return getInt(cursor, columnIndex);
+ }
+
+ static long getLong(Cursor cursor, String columnName) {
+ if (null == cursor) {
+ return Long.MIN_VALUE;
+ }
+ int columnIndex = getColumnIndex(cursor, columnName);
+ if (columnIndex < 0) {
+ return Long.MIN_VALUE;
+ }
+ return getLong(cursor, columnIndex);
+ }
+
+ static int getShort(Cursor cursor, String columnName) {
+ if (null == cursor) {
+ return Short.MIN_VALUE;
+ }
+ int columnIndex = getColumnIndex(cursor, columnName);
+ if (columnIndex < 0) {
+ return Short.MIN_VALUE;
+ }
+ return getShort(cursor, columnIndex);
+ }
+
+ static byte[] getBlob(Cursor cursor, String columnName) {
+ if (null == cursor) {
+ return null;
+ }
+ int columnIndex = getColumnIndex(cursor, columnName);
+ if (columnIndex < 0) {
+ return null;
+ }
+ return getBlob(cursor, columnIndex);
+ }
+
+ /**
+ * Returns the zero-based index for the given column name, or -1 if the column doesn't exist.
+ * If you expect the column to exist use {@link Cursor#getColumnIndexOrThrow(String)} instead, which
+ * will make the error more clear.
+ *
+ * @param columnName the name of the target column.
+ * @return the zero-based column index for the given column name, or -1 if
+ * the column name does not exist.
+ * @see Cursor#getColumnIndexOrThrow(String)
+ */
+ static int getColumnIndex(Cursor cursor, String columnName) {
+ return cursor.getColumnIndex(columnName);
+ }
+
+ /**
+ * Returns the value of the requested column as a byte array.
+ *
+ * <p>The result and whether this method throws an exception when the
+ * column value is null or the column type is not a blob type is
+ * implementation-defined.
+ *
+ * @param columnIndex the zero-based index of the target column.
+ * @return the value of that column as a byte array.
+ */
+ static byte[] getBlob(Cursor cursor, int columnIndex) {
+ return cursor.getBlob(columnIndex);
+ }
+
+ /**
+ * Returns the value of the requested column as a String.
+ *
+ * <p>The result and whether this method throws an exception when the
+ * column value is null or the column type is not a string type is
+ * implementation-defined.
+ *
+ * @param columnIndex the zero-based index of the target column.
+ * @return the value of that column as a String.
+ */
+ static String getString(Cursor cursor, int columnIndex) {
+ return cursor.getString(columnIndex);
+ }
+
+ /**
+ * Returns the value of the requested column as a short.
+ *
+ * <p>The result and whether this method throws an exception when the
+ * column value is null, the column type is not an integral type, or the
+ * integer value is outside the range [<code>Short.MIN_VALUE</code>,
+ * <code>Short.MAX_VALUE</code>] is implementation-defined.
+ *
+ * @param columnIndex the zero-based index of the target column.
+ * @return the value of that column as a short.
+ */
+ static short getShort(Cursor cursor, int columnIndex) {
+ return cursor.getShort(columnIndex);
+ }
+
+ /**
+ * Returns the value of the requested column as an int.
+ *
+ * <p>The result and whether this method throws an exception when the
+ * column value is null, the column type is not an integral type, or the
+ * integer value is outside the range [<code>Integer.MIN_VALUE</code>,
+ * <code>Integer.MAX_VALUE</code>] is implementation-defined.
+ *
+ * @param columnIndex the zero-based index of the target column.
+ * @return the value of that column as an int.
+ */
+ static int getInt(Cursor cursor, int columnIndex) {
+ return cursor.getInt(columnIndex);
+ }
+
+ /**
+ * Returns the value of the requested column as a long.
+ *
+ * <p>The result and whether this method throws an exception when the
+ * column value is null, the column type is not an integral type, or the
+ * integer value is outside the range [<code>Long.MIN_VALUE</code>,
+ * <code>Long.MAX_VALUE</code>] is implementation-defined.
+ *
+ * @param columnIndex the zero-based index of the target column.
+ * @return the value of that column as a long.
+ */
+ static long getLong(Cursor cursor, int columnIndex) {
+ return cursor.getLong(columnIndex);
+ }
+
+ /**
+ * Returns the value of the requested column as a float.
+ *
+ * <p>The result and whether this method throws an exception when the
+ * column value is null, the column type is not a floating-point type, or the
+ * floating-point value is not representable as a <code>float</code> value is
+ * implementation-defined.
+ *
+ * @param columnIndex the zero-based index of the target column.
+ * @return the value of that column as a float.
+ */
+ static float getFloat(Cursor cursor, int columnIndex) {
+ return cursor.getFloat(columnIndex);
+ }
+
+ /**
+ * Returns the value of the requested column as a double.
+ *
+ * <p>The result and whether this method throws an exception when the
+ * column value is null, the column type is not a floating-point type, or the
+ * floating-point value is not representable as a <code>double</code> value is
+ * implementation-defined.
+ *
+ * @param columnIndex the zero-based index of the target column.
+ * @return the value of that column as a double.
+ */
+ static double getDouble(Cursor cursor, int columnIndex) {
+ return cursor.getDouble(columnIndex);
+ }
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/persistance/DatabaseBackend.java b/src/main/java/de/thedevstack/conversationsplus/persistance/DatabaseBackend.java
index 4157d6f8..5a5746d5 100644
--- a/src/main/java/de/thedevstack/conversationsplus/persistance/DatabaseBackend.java
+++ b/src/main/java/de/thedevstack/conversationsplus/persistance/DatabaseBackend.java
@@ -53,6 +53,10 @@ public class DatabaseBackend extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "history";
private static final int DATABASE_VERSION = 25;
+ private static final int C_TO_CPLUS_VERSION_OFFSET = 1000;
+ private static final int CPLUS_DATABASE_VERSION = 1;
+ private static final int CPLUS_DATABASE_VERSION_MULTIPLIER = 100;
+ private static final int PHYSICAL_DATABASE_VERSION = DATABASE_VERSION + C_TO_CPLUS_VERSION_OFFSET + (CPLUS_DATABASE_VERSION * CPLUS_DATABASE_VERSION_MULTIPLIER);
private static String CREATE_CONTATCS_STATEMENT = "create table "
+ Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, "
@@ -129,8 +133,17 @@ public class DatabaseBackend extends SQLiteOpenHelper {
+ ") ON CONFLICT IGNORE"
+ ");";
+ private static int calculateCDatabaseVersion(int physicalDatabaseVersion) {
+ return physicalDatabaseVersion % CPLUS_DATABASE_VERSION_MULTIPLIER;
+ }
+
+ private static int calculateCPLusDatabaseVersion(int physicalDatabaseVersion) {
+ int cPlusDatabaseVersion = (physicalDatabaseVersion - C_TO_CPLUS_VERSION_OFFSET) / CPLUS_DATABASE_VERSION_MULTIPLIER;
+ return cPlusDatabaseVersion < 0 ? 0 : cPlusDatabaseVersion;
+ }
+
private DatabaseBackend(Context context) {
- super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ super(context, DATABASE_NAME, null, PHYSICAL_DATABASE_VERSION);
}
@Override
@@ -176,10 +189,34 @@ public class DatabaseBackend extends SQLiteOpenHelper {
db.execSQL(CREATE_PREKEYS_STATEMENT);
db.execSQL(CREATE_SIGNED_PREKEYS_STATEMENT);
db.execSQL(CREATE_IDENTITIES_STATEMENT);
+
+ // Create Conversations+ related tables
+ db.execSQL(MessageDatabaseAccess.TABLE_ADDITIONAL_PARAMETERS_CREATE_V0);
}
+ protected void onUpgradeCPlusDatabase(SQLiteDatabase db, int oldVersion, int newVersion) {
+ Logging.d("db.upgrade.cplus", "Updating Conversations+ database from version '" + oldVersion + "' to '" + newVersion + "'");
+ if (oldVersion < newVersion) {
+ if (oldVersion == 0 && newVersion == 1) {
+ Logging.d("db.upgrade.cplus", "Creating additional parameters table for messages.");
+ db.execSQL(MessageDatabaseAccess.TABLE_ADDITIONAL_PARAMETERS_CREATE_V0);
+ db.execSQL("INSERT INTO " + MessageDatabaseAccess.TABLE_NAME_ADDITIONAL_PARAMETERS + "(" + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_MSGUUID + ") "
+ + " SELECT " + Message.UUID + " FROM " + Message.TABLENAME);
+ }
+ }
+ }
+
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ onUpgradeConversationsDatabase(db, calculateCDatabaseVersion(oldVersion), calculateCDatabaseVersion(newVersion));
+ onUpgradeCPlusDatabase(db, calculateCPLusDatabaseVersion(oldVersion), calculateCPLusDatabaseVersion(newVersion));
+ }
+
+ protected void onUpgradeConversationsDatabase(SQLiteDatabase db, int oldVersion, int newVersion) {
+ Logging.d("db.upgrade.conversations", "Updating Conversations database from version '" + oldVersion + "' to '" + newVersion + "'");
+ if (oldVersion == newVersion) {
+ return;
+ }
if (oldVersion < 2 && newVersion >= 2) {
db.execSQL("update " + Account.TABLENAME + " set "
+ Account.OPTIONS + " = " + Account.OPTIONS + " | 8");
@@ -396,8 +433,14 @@ public class DatabaseBackend extends SQLiteOpenHelper {
}
public void createMessage(Message message) {
+ Logging.d("db.msg.insert", "Inserting new message with uuid '" + message.getUuid() + "', isRead: " + message.isRead());
+
SQLiteDatabase db = this.getWritableDatabase();
+ db.beginTransaction();
db.insert(Message.TABLENAME, null, message.getContentValues());
+ db.insert(MessageDatabaseAccess.TABLE_NAME_ADDITIONAL_PARAMETERS, null, MessageDatabaseAccess.getAdditionalParametersContentValues(message));
+ db.setTransactionSuccessful();
+ db.endTransaction();
}
public void createAccount(Account account) {
@@ -471,6 +514,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
cursor.moveToLast();
do {
Message message = Message.fromCursor(cursor);
+ MessageDatabaseAccess.populateMessageParameters(db, message);
message.setConversation(conversation);
list.add(message);
} while (cursor.moveToPrevious());
@@ -502,6 +546,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
@Override
public Message next() {
Message message = Message.fromCursor(cursor);
+ MessageDatabaseAccess.populateMessageParameters(db, message);
cursor.moveToNext();
return message;
}
@@ -598,17 +643,28 @@ public class DatabaseBackend extends SQLiteOpenHelper {
}
public void updateMessage(Message message) {
+ Logging.d("db.msg.update", "Updating message with uuid '" + message.getUuid() + "', isRead: " + message.isRead());
SQLiteDatabase db = this.getWritableDatabase();
String[] args = {message.getUuid()};
+ db.beginTransaction();
db.update(Message.TABLENAME, message.getContentValues(), Message.UUID
+ "=?", args);
+ db.update(MessageDatabaseAccess.TABLE_NAME_ADDITIONAL_PARAMETERS, MessageDatabaseAccess.getAdditionalParametersContentValues(message), MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_MSGUUID + "=?", args);
+ db.setTransactionSuccessful();
+ db.endTransaction();
}
public void updateMessage(Message message, String uuid) {
+ Logging.d("db.msg.update", "Updating message with uuid '" + uuid + "', isRead: " + message.isRead());
+
SQLiteDatabase db = this.getWritableDatabase();
String[] args = {uuid};
+ db.beginTransaction();
db.update(Message.TABLENAME, message.getContentValues(), Message.UUID
+ "=?", args);
+ db.update(MessageDatabaseAccess.TABLE_NAME_ADDITIONAL_PARAMETERS, MessageDatabaseAccess.getAdditionalParametersContentValues(message), MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_MSGUUID + "=?", args);
+ db.setTransactionSuccessful();
+ db.endTransaction();
}
public void readRoster(Roster roster) {
@@ -642,6 +698,8 @@ public class DatabaseBackend extends SQLiteOpenHelper {
}
public void deleteMessagesInConversation(Conversation conversation) {
+ Logging.d("db.msg.delete", "Deleting messages in conversation with uuid '" + conversation.getUuid());
+
SQLiteDatabase db = this.getWritableDatabase();
String[] args = {conversation.getUuid()};
db.delete(Message.TABLENAME, Message.CONVERSATION + "=?", args);
diff --git a/src/main/java/de/thedevstack/conversationsplus/persistance/FileBackend.java b/src/main/java/de/thedevstack/conversationsplus/persistance/FileBackend.java
index 5645caf6..9f7e473e 100644
--- a/src/main/java/de/thedevstack/conversationsplus/persistance/FileBackend.java
+++ b/src/main/java/de/thedevstack/conversationsplus/persistance/FileBackend.java
@@ -21,6 +21,7 @@ import de.thedevstack.android.logcat.Logging;
import de.thedevstack.conversationsplus.ConversationsPlusApplication;
import de.thedevstack.conversationsplus.ConversationsPlusPreferences;
import de.thedevstack.conversationsplus.exceptions.FileCopyException;
+import de.thedevstack.conversationsplus.persistance.observers.FileDeletionObserver;
import de.thedevstack.conversationsplus.utils.StreamUtil;
import de.thedevstack.conversationsplus.Config;
import de.thedevstack.conversationsplus.R;
@@ -30,8 +31,34 @@ import de.thedevstack.conversationsplus.services.XmppConnectionService;
public class FileBackend {
private static final SimpleDateFormat imageDateFormat = new SimpleDateFormat("yyyyMMdd_HHmmssSSS", Locale.US);
+ private static FileBackend INSTANCE;
- public static void createNoMedia() {
+ private FileDeletionObserver privateFilesDirectoryObserver;
+ private FileDeletionObserver privateFilesImageDirectoryObserver;
+ private FileDeletionObserver conversationsFilesDirectoryObserver;
+ private FileDeletionObserver conversationsImagesDirectoryObserver;
+
+ public static void init() {
+ if (null == INSTANCE) {
+ INSTANCE = new FileBackend();
+ }
+ INSTANCE.initFileObservers();
+ INSTANCE.createNoMedia();
+ }
+
+ private void initFileObservers() {
+ this.privateFilesDirectoryObserver = new FileDeletionObserver(FileBackend.getPrivateFileDirectoryPath());
+ this.privateFilesImageDirectoryObserver = new FileDeletionObserver(FileBackend.getConversationsFileDirectory());
+ this.conversationsFilesDirectoryObserver = new FileDeletionObserver(FileBackend.getConversationsImageDirectory());
+ this.conversationsImagesDirectoryObserver = new FileDeletionObserver(FileBackend.getPrivateImageDirectoryPath());
+
+ this.privateFilesDirectoryObserver.startWatching();
+ this.privateFilesImageDirectoryObserver.startWatching();
+ this.conversationsFilesDirectoryObserver.startWatching();
+ this.conversationsImagesDirectoryObserver.startWatching();
+ }
+
+ private void createNoMedia() {
final File nomedia = new File(getConversationsFileDirectory()+".nomedia");
if (!nomedia.exists()) {
try {
@@ -42,6 +69,19 @@ public class FileBackend {
}
}
+ public static void onFileTransferFolderChanged() {
+ INSTANCE.conversationsFilesDirectoryObserver.stopWatching();
+ INSTANCE.conversationsFilesDirectoryObserver = new FileDeletionObserver(FileBackend.getConversationsFileDirectory());
+ INSTANCE.conversationsFilesDirectoryObserver.startWatching();
+ INSTANCE.createNoMedia();
+ }
+
+ public static void onImageTransferFolderChanged() {
+ INSTANCE.conversationsImagesDirectoryObserver.stopWatching();
+ INSTANCE.conversationsImagesDirectoryObserver = new FileDeletionObserver(FileBackend.getConversationsImageDirectory());
+ INSTANCE.conversationsImagesDirectoryObserver.startWatching();
+ }
+
public static void updateMediaScanner(File file, XmppConnectionService xmppConnectionService) {
if (file.getAbsolutePath().startsWith(getConversationsImageDirectory())) {
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
diff --git a/src/main/java/de/thedevstack/conversationsplus/persistance/MessageDatabaseAccess.java b/src/main/java/de/thedevstack/conversationsplus/persistance/MessageDatabaseAccess.java
new file mode 100644
index 00000000..7776174d
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/persistance/MessageDatabaseAccess.java
@@ -0,0 +1,59 @@
+package de.thedevstack.conversationsplus.persistance;
+
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+
+import de.thedevstack.android.logcat.Logging;
+import de.thedevstack.conversationsplus.entities.Message;
+import de.thedevstack.conversationsplus.xmpp.jid.InvalidJidException;
+import de.thedevstack.conversationsplus.xmpp.jid.Jid;
+
+/**
+ * Created by steckbrief on 15.04.2016.
+ */
+public class MessageDatabaseAccess {
+ static final String TABLE_NAME_ADDITIONAL_PARAMETERS = "message_parameters";
+ static final String COLUMN_NAME_MSG_PARAMS_HTTPUPLOAD = "httpupload";
+ static final String COLUMN_NAME_MSG_PARAMS_MSGUUID = "message_uuid";
+ static final String COLUMN_NAME_MSG_PARAMS_TREATASDOWNLOADABLE_DECISION = "treatasdownloadable_decision";
+
+ static final String TABLE_ADDITIONAL_PARAMETERS_CREATE_V0 = "CREATE TABLE " + MessageDatabaseAccess.TABLE_NAME_ADDITIONAL_PARAMETERS + " ("
+ + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_MSGUUID + " TEXT, "
+ + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_HTTPUPLOAD + " INTEGER DEFAULT 0, "
+ + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_TREATASDOWNLOADABLE_DECISION + " TEXT DEFAULT 'NOT_DECIDED', "
+ + "FOREIGN KEY(" + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_MSGUUID + ") REFERENCES " + Message.TABLENAME + "(" + Message.UUID + ") ON DELETE CASCADE)";
+
+ static ContentValues getAdditionalParametersContentValues(Message message) {
+ ContentValues additionalParameters = new ContentValues();
+ additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_MSGUUID, message.getUuid());
+ additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_HTTPUPLOAD, message.isHttpUploaded() ? 1 : 0);
+ additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_TREATASDOWNLOADABLE_DECISION, message.treatAsDownloadable().name());
+
+ return additionalParameters;
+ }
+
+ static void populateMessageParametersFromCursor(Cursor cursor, Message message) {
+ boolean isHttpUploaded = CursorHelper.getInt(cursor, COLUMN_NAME_MSG_PARAMS_HTTPUPLOAD) == 1;
+ message.setHttpUploaded(isHttpUploaded);
+ String downloadable = CursorHelper.getString(cursor, COLUMN_NAME_MSG_PARAMS_TREATASDOWNLOADABLE_DECISION);
+ Message.Decision treatAsDownloadable = Message.Decision.NOT_DECIDED;
+ try {
+ treatAsDownloadable = Message.Decision.valueOf(downloadable);
+ } catch (IllegalArgumentException e) {
+ // Should only happen if the database is corrupted, but to be on the save side catch it here
+ Logging.e("db.msg", "Unknown Decision for treatAsDownloadable found: '" + downloadable + "'");
+ }
+ message.setTreatAsDownloadable(treatAsDownloadable);
+ }
+
+ static void populateMessageParameters(SQLiteDatabase db, Message message) {
+ Cursor paramsCursor = db.query(MessageDatabaseAccess.TABLE_NAME_ADDITIONAL_PARAMETERS,
+ null, MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_MSGUUID + "=?",
+ new String[] {message.getUuid()},
+ null, null, null, null);
+ paramsCursor.moveToNext();
+ MessageDatabaseAccess.populateMessageParametersFromCursor(paramsCursor, message);
+ paramsCursor.close();
+ }
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/persistance/observers/FileDeletionObserver.java b/src/main/java/de/thedevstack/conversationsplus/persistance/observers/FileDeletionObserver.java
new file mode 100644
index 00000000..3534ccd2
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/persistance/observers/FileDeletionObserver.java
@@ -0,0 +1,45 @@
+package de.thedevstack.conversationsplus.persistance.observers;
+
+import android.os.FileObserver;
+
+import de.thedevstack.conversationsplus.entities.Conversation;
+import de.thedevstack.conversationsplus.entities.Message;
+import de.thedevstack.conversationsplus.entities.Transferable;
+import de.thedevstack.conversationsplus.entities.TransferablePlaceholder;
+import de.thedevstack.conversationsplus.utils.MessageUtil;
+import de.thedevstack.conversationsplus.utils.UiUpdateHelper;
+import de.thedevstack.conversationsplus.utils.XmppConnectionServiceAccessor;
+
+/**
+ * Observer to mark messages containing files which are deleted.
+ */
+public class FileDeletionObserver extends FileObserver {
+ public FileDeletionObserver(String path) {
+ super(path, FileObserver.DELETE);
+ }
+
+ @Override
+ public void onEvent(int event, String path) {
+ if (null != path) {
+ markFileDeleted(path.split("\\.")[0]);
+ }
+ }
+
+ private void markFileDeleted(String uuid) {
+ if (null != XmppConnectionServiceAccessor.xmppConnectionService) {
+ for (Conversation conversation : XmppConnectionServiceAccessor.xmppConnectionService.getConversations()) {
+ Message message = conversation.findMessageWithFileAndUuid(uuid);
+ if (message != null) {
+ message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_DELETED));
+ final int s = message.getStatus();
+ if (s == Message.STATUS_WAITING || s == Message.STATUS_OFFERED || s == Message.STATUS_UNSEND) {
+ MessageUtil.markMessage(message, Message.STATUS_SEND_FAILED);
+ } else {
+ UiUpdateHelper.updateConversationUi();
+ }
+ return;
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java b/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java
index c1426080..9c0e55db 100644
--- a/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java
+++ b/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java
@@ -7,7 +7,6 @@ import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.SharedPreferences;
import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.media.AudioManager;
@@ -17,13 +16,11 @@ import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
-import android.os.FileObserver;
import android.os.IBinder;
import android.os.Looper;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.SystemClock;
-import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.security.KeyChain;
import android.util.DisplayMetrics;
@@ -66,6 +63,7 @@ import de.thedevstack.conversationsplus.utils.FileUtils;
import de.thedevstack.conversationsplus.utils.ImageUtil;
import de.thedevstack.conversationsplus.utils.MessageUtil;
import de.thedevstack.conversationsplus.utils.UiUpdateHelper;
+import de.thedevstack.conversationsplus.utils.XmppConnectionServiceAccessor;
import de.thedevstack.conversationsplus.utils.XmppSendUtil;
import de.tzur.conversations.Settings;
import de.thedevstack.conversationsplus.Config;
@@ -204,16 +202,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
private MessageArchiveService mMessageArchiveService = new MessageArchiveService(this);
private PushManagementService mPushManagementService = new PushManagementService(this);
private OnConversationUpdate mOnConversationUpdate = null;
- private final FileObserver fileObserver = new FileObserver(
- FileBackend.getConversationsImageDirectory()) {
-
- @Override
- public void onEvent(int event, String path) {
- if (event == FileObserver.DELETE) {
- markFileDeleted(path.split("\\.")[0]);
- }
- }
- };
private final OnJinglePacketReceived jingleListener = new OnJinglePacketReceived() {
@Override
@@ -229,7 +217,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
if (conversation.getAccount() == account) {
Message message = conversation.findUnsentMessageWithUuid(uuid);
if (message != null) {
- markMessage(message, Message.STATUS_SEND);
+ MessageUtil.markMessage(message, Message.STATUS_SEND);
}
}
}
@@ -372,64 +360,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
}
}
- public void attachLocationToConversation(final Conversation conversation,
- final Uri uri,
- final UiCallback<Message> callback) {
- int encryption = conversation.getNextEncryption();
- if (encryption == Message.ENCRYPTION_PGP) {
- encryption = Message.ENCRYPTION_DECRYPTED;
- }
- Message message = new Message(conversation, uri.toString(), encryption);
- if (conversation.getNextCounterpart() != null) {
- message.setCounterpart(conversation.getNextCounterpart());
- }
- if (encryption == Message.ENCRYPTION_DECRYPTED) {
- getPgpEngine().encrypt(message, callback);
- } else {
- callback.success(message);
- }
- }
-
- public void attachFileToConversation(final Conversation conversation,
- final Uri uri,
- final UiCallback<Message> callback) {
- final Message message;
- if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) {
- message = new Message(conversation, "", Message.ENCRYPTION_DECRYPTED);
- } else {
- message = new Message(conversation, "", conversation.getNextEncryption());
- }
- message.setCounterpart(conversation.getNextCounterpart());
- message.setType(Message.TYPE_FILE);
- String path = FileUtils.getPath(uri);
- if (path != null) {
- message.setRelativeFilePath(path);
- MessageUtil.updateFileParams(message);
- if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) {
- getPgpEngine().encrypt(message, callback);
- } else {
- callback.success(message);
- }
- } else {
- ConversationsPlusApplication.executeFileAdding(new Runnable() {
- @Override
- public void run() {
- try {
- FileBackend.copyFileToPrivateStorage(message, uri);
- MessageUtil.updateFileParams(message);
- if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) {
- getPgpEngine().encrypt(message, callback);
- } else {
- callback.success(message);
- }
- } catch (FileCopyException e) {
- callback.error(e.getResId(), message);
- }
- }
- });
- }
- }
-
public Conversation find(Bookmark bookmark) {
return find(bookmark.getAccount(), bookmark.getJid());
}
@@ -665,7 +595,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
restoreFromDatabase();
getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, contactObserver);
- this.fileObserver.startWatching();
if (Config.supportOpenPgp()) {
this.pgpServiceConnection = new OpenPgpServiceConnection(getApplicationContext(), "org.sufficientlysecure.keychain", new OpenPgpServiceConnection.OnBound() {
@@ -690,6 +619,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
toggleForegroundService();
updateUnreadCountBadge();
UiUpdateHelper.initXmppConnectionService(this);
+ XmppConnectionServiceAccessor.initXmppConnectionService(this);
toggleScreenEventReceiver();
}
@@ -840,7 +770,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
new Conversation.OnMessageFound() {
@Override
public void onMessageFound(Message message) {
- markMessage(message, Message.STATUS_SEND_FAILED);
+ MessageUtil.markMessage(message, Message.STATUS_SEND_FAILED);
}
});
}
@@ -952,9 +882,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
if (resend) {
if (packet != null && addToConversation) {
if (account.getXmppConnection().getFeatures().sm() || conversation.getMode() == Conversation.MODE_MULTI) {
- markMessage(message, Message.STATUS_UNSEND);
+ MessageUtil.markMessage(message, Message.STATUS_UNSEND);
} else {
- markMessage(message, Message.STATUS_SEND);
+ MessageUtil.markMessage(message, Message.STATUS_SEND);
}
}
} else {
@@ -1170,31 +1100,13 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_DELETED));
final int s = message.getStatus();
if (s == Message.STATUS_WAITING || s == Message.STATUS_OFFERED || s == Message.STATUS_UNSEND) {
- markMessage(message, Message.STATUS_SEND_FAILED);
+ MessageUtil.markMessage(message, Message.STATUS_SEND_FAILED);
}
}
}
});
}
- private void markFileDeleted(String uuid) {
- for (Conversation conversation : getConversations()) {
- Message message = conversation.findMessageWithFileAndUuid(uuid);
- if (message != null) {
- if (!FileBackend.isFileAvailable(message)) {
- message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_DELETED));
- final int s = message.getStatus();
- if (s == Message.STATUS_WAITING || s == Message.STATUS_OFFERED || s == Message.STATUS_UNSEND) {
- markMessage(message, Message.STATUS_SEND_FAILED);
- } else {
- updateConversationUi();
- }
- }
- return;
- }
- }
- }
-
public void populateWithOrderedConversations(final List<Conversation> list) {
populateWithOrderedConversations(list, true);
}
@@ -2203,11 +2115,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
updateConversationUi();
}
- public void updateMessage(Message message, String uuid) {
- databaseBackend.updateMessage(message, uuid);
- updateConversationUi();
- }
-
protected void syncDirtyContacts(Account account) {
for (Contact contact : account.getRoster().getContacts()) {
if (contact.getOption(Contact.Options.DIRTY_PUSH)) {
@@ -2379,7 +2286,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
@Override
public void onMessageFound(Message message) {
- markMessage(message, Message.STATUS_WAITING);
+ MessageUtil.markMessage(message, Message.STATUS_WAITING);
}
});
}
@@ -2394,7 +2301,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
if (conversation.getJid().toBareJid().equals(recipient) && conversation.getAccount() == account) {
final Message message = conversation.findSentMessageWithUuidOrRemoteId(uuid);
if (message != null) {
- markMessage(message, status);
+ MessageUtil.markMessage(message, status);
}
return message;
}
@@ -2402,31 +2309,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
return null;
}
- public boolean markMessage(Conversation conversation, String uuid, int status) {
- if (uuid == null) {
- return false;
- } else {
- Message message = conversation.findSentMessageWithUuid(uuid);
- if (message != null) {
- markMessage(message, status);
- return true;
- } else {
- return false;
- }
- }
- }
-
- public void markMessage(Message message, int status) {
- if (status == Message.STATUS_SEND_FAILED
- && (message.getStatus() == Message.STATUS_SEND_RECEIVED || message
- .getStatus() == Message.STATUS_SEND_DISPLAYED)) {
- return;
- }
- message.setStatus(status);
- databaseBackend.updateMessage(message);
- updateConversationUi();
- }
-
public int unreadCount() {
int count = 0;
for (Conversation conversation : getConversations()) {
@@ -2724,7 +2606,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
public void resendFailedMessages(final Message message) {
if (message.getStatus() == Message.STATUS_SEND_FAILED) {
message.setTime(System.currentTimeMillis());
- markMessage(message, Message.STATUS_WAITING);
+ MessageUtil.markMessage(message, Message.STATUS_WAITING);
this.resendMessage(message, false);
}
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/ConversationActivity.java b/src/main/java/de/thedevstack/conversationsplus/ui/ConversationActivity.java
index e46095e7..7138f8e3 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ui/ConversationActivity.java
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/ConversationActivity.java
@@ -52,6 +52,7 @@ import de.thedevstack.conversationsplus.ConversationsPlusPreferences;
import de.thedevstack.conversationsplus.services.AvatarService;
import de.thedevstack.conversationsplus.ui.dialogs.UserDecisionDialog;
import de.thedevstack.conversationsplus.ui.listeners.ResizePictureUserDecisionListener;
+import de.thedevstack.conversationsplus.utils.ConversationUtil;
import de.timroes.android.listview.EnhancedListView;
import de.thedevstack.conversationsplus.Config;
import de.thedevstack.conversationsplus.R;
@@ -1483,7 +1484,7 @@ public class ConversationActivity extends XmppActivity
if (conversation == null) {
return;
}
- xmppConnectionService.attachLocationToConversation(conversation,uri, new UiCallback<Message>() {
+ ConversationUtil.attachLocationToConversation(conversation,uri, new UiCallback<Message>() {
@Override
public void success(Message message) {
@@ -1508,7 +1509,7 @@ public class ConversationActivity extends XmppActivity
}
final Toast prepareFileToast = Toast.makeText(getApplicationContext(),getText(R.string.preparing_file), Toast.LENGTH_LONG);
prepareFileToast.show();
- xmppConnectionService.attachFileToConversation(conversation, uri, new UiCallback<Message>() {
+ ConversationUtil.attachFileToConversation(conversation, uri, new UiCallback<Message>() {
@Override
public void success(Message message) {
hidePrepareFileToast(prepareFileToast);
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java b/src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java
index 4ae88a5e..f065a25b 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java
@@ -69,6 +69,7 @@ import de.thedevstack.conversationsplus.ui.adapter.MessageAdapter.OnContactPictu
import de.thedevstack.conversationsplus.ui.adapter.MessageAdapter.OnContactPictureLongClicked;
import de.thedevstack.conversationsplus.ui.listeners.ConversationSwipeRefreshListener;
import de.thedevstack.conversationsplus.utils.GeoHelper;
+import de.thedevstack.conversationsplus.utils.MessageUtil;
import de.thedevstack.conversationsplus.utils.UIHelper;
import de.thedevstack.conversationsplus.xmpp.chatstate.ChatState;
import de.thedevstack.conversationsplus.xmpp.jid.Jid;
@@ -693,7 +694,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
if (transferable != null) {
transferable.cancel();
} else {
- activity.xmppConnectionService.markMessage(message, Message.STATUS_SEND_FAILED);
+ MessageUtil.markMessage(message, Message.STATUS_SEND_FAILED);
}
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/SettingsActivity.java b/src/main/java/de/thedevstack/conversationsplus/ui/SettingsActivity.java
index 35816cff..84eb7016 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ui/SettingsActivity.java
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/SettingsActivity.java
@@ -9,13 +9,10 @@ import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
-import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceCategory;
import android.preference.PreferenceManager;
-import android.preference.PreferenceScreen;
-import android.util.Log;
import android.widget.Toast;
import java.security.KeyStoreException;
@@ -31,7 +28,6 @@ import de.tzur.conversations.Settings;
import de.thedevstack.conversationsplus.R;
import de.thedevstack.conversationsplus.entities.Account;
import de.thedevstack.conversationsplus.persistance.FileBackend;
-import de.thedevstack.conversationsplus.services.ExportLogsService;
import de.thedevstack.conversationsplus.xmpp.XmppConnection;
import github.ankushsachdeva.emojicon.EmojiconHandler;
@@ -187,7 +183,9 @@ public class SettingsActivity extends XmppActivity implements
} else if ("parse_emoticons".equals(name)) {
EmojiconHandler.setParseEmoticons(Settings.PARSE_EMOTICONS);
} else if ("file_transfer_folder".equals(name)) {
- FileBackend.createNoMedia();
+ FileBackend.onFileTransferFolderChanged();
+ } else if ("img_transfer_folder".equals(name)) {
+ FileBackend.onImageTransferFolderChanged();
}
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/ShareWithActivity.java b/src/main/java/de/thedevstack/conversationsplus/ui/ShareWithActivity.java
index fe3ed73f..28e8beb8 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ui/ShareWithActivity.java
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/ShareWithActivity.java
@@ -31,6 +31,7 @@ import de.thedevstack.conversationsplus.entities.Message;
import de.thedevstack.conversationsplus.persistance.FileBackend;
import de.thedevstack.conversationsplus.services.XmppConnectionService;
import de.thedevstack.conversationsplus.ui.adapter.ConversationAdapter;
+import de.thedevstack.conversationsplus.utils.ConversationUtil;
import de.thedevstack.conversationsplus.utils.FileUtils;
import de.thedevstack.conversationsplus.xmpp.jid.InvalidJidException;
import de.thedevstack.conversationsplus.xmpp.jid.Jid;
@@ -300,9 +301,7 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer
@Override
public void onPresenceSelected() {
replaceToast(getString(R.string.preparing_file));
- ShareWithActivity.this.xmppConnectionService
- .attachFileToConversation(conversation, share.uris.get(0),
- attachFileCallback);
+ ConversationUtil.attachFileToConversation(conversation, share.uris.get(0), attachFileCallback);
switchToConversation(conversation, null, true);
finish();
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/dialogs/MessageDetailsDialog.java b/src/main/java/de/thedevstack/conversationsplus/ui/dialogs/MessageDetailsDialog.java
index dfa3147d..e1c30a56 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ui/dialogs/MessageDetailsDialog.java
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/dialogs/MessageDetailsDialog.java
@@ -13,6 +13,7 @@ import de.thedevstack.conversationsplus.R;
import de.thedevstack.conversationsplus.entities.Conversation;
import de.thedevstack.conversationsplus.entities.Message;
import de.thedevstack.conversationsplus.utils.UIHelper;
+import de.thedevstack.conversationsplus.utils.ui.TextViewUtil;
/**
* Fills the contents to the message details dialog.
@@ -59,11 +60,11 @@ public class MessageDetailsDialog extends AbstractAlertDialog {
view.findViewById(R.id.dlgMsgDetFileTable).setVisibility(View.VISIBLE);
if (null != message.getFileParams()) {
Message.FileParams params = message.getFileParams();
- TextView tvFilesize = (TextView) view.findViewById(R.id.dlgMsgDetFileSize);
- tvFilesize.setText(UIHelper.getHumanReadableFileSize(params.size));
+ TextViewUtil.setText(view, R.id.dlgMsgDetFileSize, UIHelper.getHumanReadableFileSize(params.size));
}
- TextView mimetype = (TextView) view.findViewById(R.id.dlgMsgDetFileMimeType);
- mimetype.setText(message.getMimeType());
+ TextViewUtil.setText(view, R.id.dlgMsgDetFileMimeType, message.getMimeType());
+
+ TextViewUtil.setText(view, R.id.dlgMsgDetFileHttpUploaded, message.isHttpUploaded() ? R.string.cplus_yes : R.string.cplus_no);
}
}
@@ -107,7 +108,6 @@ public class MessageDetailsDialog extends AbstractAlertDialog {
* @param message the message to display in dialog
*/
protected void displayMessageTypeInfo(View view, Message message) {
- TextView msgTypeTextView = (TextView) view.findViewById(R.id.dlgMsgDetMsgType);
int msgTypeResId;
switch (message.getType()) {
case Message.TYPE_PRIVATE:
@@ -126,7 +126,7 @@ public class MessageDetailsDialog extends AbstractAlertDialog {
default:
msgTypeResId = R.string.dlg_msg_details_msg_type_text;
}
- msgTypeTextView.setText(msgTypeResId);
+ TextViewUtil.setText(view, R.id.dlgMsgDetMsgType, msgTypeResId);
}
/**
@@ -146,10 +146,8 @@ public class MessageDetailsDialog extends AbstractAlertDialog {
if (conversation.getMode() == Conversation.MODE_MULTI) {
// Change label of sending and receiving party to MUC terminology
- TextView senderLabel = (TextView) view.findViewById(R.id.dlgMsgDetLblSender);
- senderLabel.setText(R.string.dlg_msg_details_sender_nick);
- TextView receipientLabel = (TextView) view.findViewById(R.id.dlgMsgDetLblReceipient);
- receipientLabel.setText(R.string.dlg_msg_details_receipient_nick);
+ TextViewUtil.setText(view, R.id.dlgMsgDetLblSender, R.string.dlg_msg_details_sender_nick);
+ TextViewUtil.setText(view, R.id.dlgMsgDetLblReceipient, R.string.dlg_msg_details_receipient_nick);
// Get own nick for MUC
me = conversation.getMucOptions().getActualNick();
@@ -173,7 +171,6 @@ public class MessageDetailsDialog extends AbstractAlertDialog {
* @param message the message to display in dialog
*/
protected void displayMessageSentTime(View view, Message message) {
- TextView timeSent = (TextView) view.findViewById(R.id.dlgMsgDetTimeSent);
- timeSent.setText(DateFormat.format("dd.MM.yyyy kk:mm:ss", new Date(message.getTimeSent())));
+ TextViewUtil.setText(view, R.id.dlgMsgDetTimeSent, DateFormat.format("dd.MM.yyyy kk:mm:ss", new Date(message.getTimeSent())));
}
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ResizePictureUserDecisionListener.java b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ResizePictureUserDecisionListener.java
index 231f738c..b7340ce0 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ResizePictureUserDecisionListener.java
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ResizePictureUserDecisionListener.java
@@ -13,6 +13,7 @@ import java.io.InputStream;
import de.thedevstack.android.logcat.Logging;
import de.thedevstack.conversationsplus.ConversationsPlusApplication;
import de.thedevstack.conversationsplus.ConversationsPlusPreferences;
+import de.thedevstack.conversationsplus.crypto.PgpEngine;
import de.thedevstack.conversationsplus.enums.UserDecision;
import de.thedevstack.conversationsplus.exceptions.UiException;
import de.thedevstack.conversationsplus.utils.FileUtils;
@@ -29,7 +30,7 @@ import de.thedevstack.conversationsplus.ui.XmppActivity;
import de.thedevstack.conversationsplus.utils.StreamUtil;
/**
- * Created by tzur on 31.10.2015.
+ * Listener to let the user decide whether to resize a picture before sending or not.
*/
public class ResizePictureUserDecisionListener implements UserDecisionListener {
protected Uri uri;
@@ -156,7 +157,7 @@ public class ResizePictureUserDecisionListener implements UserDecisionListener {
String filePath = FileUtils.getPath(uri);
MessageUtil.updateMessageWithImageDetails(message, filePath, imageSize, imageWidth, imageHeight);
if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) {
- xmppConnectionService.getPgpEngine().encrypt(message, callback);
+ PgpEngine.getInstance().encrypt(message, callback);
} else {
callback.success(message);
}
@@ -195,7 +196,7 @@ public class ResizePictureUserDecisionListener implements UserDecisionListener {
int imageHeight = resizedAndRotatedImage.getHeight();
MessageUtil.updateMessageWithImageDetails(message, filePath, imageSize, imageWidth, imageHeight);
if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) {
- xmppConnectionService.getPgpEngine().encrypt(message, callback);
+ PgpEngine.getInstance().encrypt(message, callback);
} else {
callback.success(message);
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/ConversationUtil.java b/src/main/java/de/thedevstack/conversationsplus/utils/ConversationUtil.java
new file mode 100644
index 00000000..77c2c728
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/utils/ConversationUtil.java
@@ -0,0 +1,75 @@
+package de.thedevstack.conversationsplus.utils;
+
+import android.net.Uri;
+
+import de.thedevstack.conversationsplus.ConversationsPlusApplication;
+import de.thedevstack.conversationsplus.crypto.PgpEngine;
+import de.thedevstack.conversationsplus.entities.Conversation;
+import de.thedevstack.conversationsplus.entities.Message;
+import de.thedevstack.conversationsplus.exceptions.FileCopyException;
+import de.thedevstack.conversationsplus.persistance.FileBackend;
+import de.thedevstack.conversationsplus.ui.UiCallback;
+
+/**
+ * Utility class to work with conversations.
+ */
+public class ConversationUtil {
+
+ public static void attachLocationToConversation(final Conversation conversation,
+ final Uri uri,
+ final UiCallback<Message> callback) {
+ int encryption = conversation.getNextEncryption();
+ if (encryption == Message.ENCRYPTION_PGP) {
+ encryption = Message.ENCRYPTION_DECRYPTED;
+ }
+ Message message = new Message(conversation, uri.toString(), encryption);
+ if (conversation.getNextCounterpart() != null) {
+ message.setCounterpart(conversation.getNextCounterpart());
+ }
+ if (encryption == Message.ENCRYPTION_DECRYPTED) {
+ PgpEngine.getInstance().encrypt(message, callback);
+ } else {
+ callback.success(message);
+ }
+ }
+
+ public static void attachFileToConversation(final Conversation conversation,
+ final Uri uri,
+ final UiCallback<Message> callback) {
+ final Message message;
+ if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) {
+ message = new Message(conversation, "", Message.ENCRYPTION_DECRYPTED);
+ } else {
+ message = new Message(conversation, "", conversation.getNextEncryption());
+ }
+ message.setCounterpart(conversation.getNextCounterpart());
+ message.setType(Message.TYPE_FILE);
+ String path = FileUtils.getPath(uri);
+ if (path != null) {
+ message.setRelativeFilePath(path);
+ MessageUtil.updateFileParams(message);
+ if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) {
+ PgpEngine.getInstance().encrypt(message, callback);
+ } else {
+ callback.success(message);
+ }
+ } else {
+ ConversationsPlusApplication.executeFileAdding(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ FileBackend.copyFileToPrivateStorage(message, uri);
+ MessageUtil.updateFileParams(message);
+ if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) {
+ PgpEngine.getInstance().encrypt(message, callback);
+ } else {
+ callback.success(message);
+ }
+ } catch (FileCopyException e) {
+ callback.error(e.getResId(), message);
+ }
+ }
+ });
+ }
+ }
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java b/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java
index 6a668938..67433b31 100644
--- a/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java
+++ b/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java
@@ -6,8 +6,11 @@ import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import de.thedevstack.conversationsplus.ConversationsPlusApplication;
+import de.thedevstack.conversationsplus.entities.Conversation;
import de.thedevstack.conversationsplus.entities.DownloadableFile;
import de.thedevstack.conversationsplus.entities.Message;
+import de.thedevstack.conversationsplus.persistance.DatabaseBackend;
import de.thedevstack.conversationsplus.persistance.FileBackend;
/**
@@ -15,6 +18,32 @@ import de.thedevstack.conversationsplus.persistance.FileBackend;
*/
public final class MessageUtil {
+
+ public static boolean markMessage(Conversation conversation, String uuid, int status) {
+ if (uuid == null) {
+ return false;
+ } else {
+ Message message = conversation.findSentMessageWithUuid(uuid);
+ if (message != null) {
+ markMessage(message, status);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ public static void markMessage(Message message, int status) {
+ if (status == Message.STATUS_SEND_FAILED
+ && (message.getStatus() == Message.STATUS_SEND_RECEIVED || message
+ .getStatus() == Message.STATUS_SEND_DISPLAYED)) {
+ return;
+ }
+ message.setStatus(status);
+ DatabaseBackend.getInstance(ConversationsPlusApplication.getAppContext()).updateMessage(message);
+ UiUpdateHelper.updateConversationUi();
+ }
+
public static boolean wasHighlightedOrPrivate(final Message message) {
final String nick = message.getConversation().getMucOptions().getActualNick();
final Pattern highlight = generateNickHighlightPattern(nick);
diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/XmppConnectionServiceAccessor.java b/src/main/java/de/thedevstack/conversationsplus/utils/XmppConnectionServiceAccessor.java
new file mode 100644
index 00000000..1f1d7cf4
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/utils/XmppConnectionServiceAccessor.java
@@ -0,0 +1,31 @@
+package de.thedevstack.conversationsplus.utils;
+
+import de.thedevstack.android.logcat.Logging;
+import de.thedevstack.conversationsplus.services.XmppConnectionService;
+
+/**
+ * Accessor utility to access XmppConnectionService without having to pass the XmppConnectionService every time.
+ */
+public final class XmppConnectionServiceAccessor {
+ public static XmppConnectionService xmppConnectionService;
+
+ /**
+ * Initializes the XmppConnectionService.
+ * This method needs to be called once in XmppConnectionService#onCreate.
+ * @param xmppConnectionService
+ */
+ public static void initXmppConnectionService(XmppConnectionService xmppConnectionService) {
+ if (null == XmppConnectionServiceAccessor.xmppConnectionService) {
+ XmppConnectionServiceAccessor.xmppConnectionService = xmppConnectionService;
+ } else {
+ Logging.e("XmppConnectionServiceAccessor", "XMPP Connection Service already instantiated.");
+ }
+ }
+
+ /**
+ * Avoid instantiation
+ */
+ private XmppConnectionServiceAccessor() {
+ // avoid instantiation
+ }
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/ui/TextViewUtil.java b/src/main/java/de/thedevstack/conversationsplus/utils/ui/TextViewUtil.java
index bb08014b..a775dad6 100644
--- a/src/main/java/de/thedevstack/conversationsplus/utils/ui/TextViewUtil.java
+++ b/src/main/java/de/thedevstack/conversationsplus/utils/ui/TextViewUtil.java
@@ -1,12 +1,28 @@
package de.thedevstack.conversationsplus.utils.ui;
import android.support.annotation.StringRes;
+import android.view.View;
import android.widget.TextView;
/**
* Created by steckbrief on 29.03.2016.
*/
public final class TextViewUtil {
+
+ public static void setText(View parentView, int textViewId, CharSequence text) {
+ TextView tv = (TextView) parentView.findViewById(textViewId);
+ if (null != tv) {
+ tv.setText(text);
+ }
+ }
+
+ public static void setText(View parentView, int textViewId, int textResId) {
+ TextView tv = (TextView) parentView.findViewById(textViewId);
+ if (null != tv) {
+ tv.setText(textResId);
+ }
+ }
+
public static void enable(TextView tv) {
setColorEnabledAndTextResId(tv, null, true, null);
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/httpuploadim/HttpUploadHint.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/httpuploadim/HttpUploadHint.java
new file mode 100644
index 00000000..3e9d7f2b
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/httpuploadim/HttpUploadHint.java
@@ -0,0 +1,15 @@
+package de.thedevstack.conversationsplus.xmpp.httpuploadim;
+
+import de.thedevstack.conversationsplus.xml.Element;
+
+/**
+ * Created by steckbrief on 17.04.2016.
+ */
+public class HttpUploadHint extends Element {
+ public static final String NAMESPACE = "urn:xmpp:hints";
+ public static final String ELEMENT_NAME = "httpupload";
+
+ public HttpUploadHint() {
+ super(ELEMENT_NAME, NAMESPACE);
+ }
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java
index b4c05ce4..422bdff0 100644
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java
+++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java
@@ -103,7 +103,7 @@ public class JingleConnection implements Transferable {
sendSuccess();
MessageUtil.updateFileParams(message);
mXmppConnectionService.databaseBackend.createMessage(message);
- mXmppConnectionService.markMessage(message,Message.STATUS_RECEIVED);
+ MessageUtil.markMessage(message,Message.STATUS_RECEIVED);
if (acceptedAutomatically) {
message.markUnread();
JingleConnection.this.mXmppConnectionService.getNotificationService().push(message);
@@ -457,7 +457,7 @@ public class JingleConnection implements Transferable {
if (packet.getType() == IqPacket.TYPE.RESULT) {
Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": other party received offer");
mJingleStatus = JINGLE_STATUS_INITIATED;
- mXmppConnectionService.markMessage(message, Message.STATUS_OFFERED);
+ MessageUtil.markMessage(message, Message.STATUS_OFFERED);
} else {
fail();
}
@@ -548,7 +548,7 @@ public class JingleConnection implements Transferable {
mergeCandidates(JingleCandidate.parse(content.socks5transport()
.getChildren()));
this.mJingleStatus = JINGLE_STATUS_ACCEPTED;
- mXmppConnectionService.markMessage(message, Message.STATUS_UNSEND);
+ MessageUtil.markMessage(message, Message.STATUS_UNSEND);
this.connectNextCandidate();
return true;
}
@@ -780,7 +780,7 @@ public class JingleConnection implements Transferable {
private void receiveSuccess() {
this.mJingleStatus = JINGLE_STATUS_FINISHED;
- this.mXmppConnectionService.markMessage(this.message,Message.STATUS_SEND_RECEIVED);
+ MessageUtil.markMessage(this.message,Message.STATUS_SEND_RECEIVED);
this.disconnectSocks5Connections();
if (this.transport != null && this.transport instanceof JingleInbandTransport) {
this.transport.disconnect();
@@ -803,8 +803,7 @@ public class JingleConnection implements Transferable {
}
this.mXmppConnectionService.updateConversationUi();
} else {
- this.mXmppConnectionService.markMessage(this.message,
- Message.STATUS_SEND_FAILED);
+ MessageUtil.markMessage(this.message, Message.STATUS_SEND_FAILED);
this.message.setTransferable(null);
}
}
@@ -825,8 +824,7 @@ public class JingleConnection implements Transferable {
}
this.mXmppConnectionService.updateConversationUi();
} else {
- this.mXmppConnectionService.markMessage(this.message,
- Message.STATUS_SEND_FAILED);
+ MessageUtil.markMessage(this.message, Message.STATUS_SEND_FAILED);
this.message.setTransferable(null);
}
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnectionManager.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnectionManager.java
index 3284a936..2deb79c6 100644
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnectionManager.java
+++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnectionManager.java
@@ -15,6 +15,7 @@ import de.thedevstack.conversationsplus.entities.Message;
import de.thedevstack.conversationsplus.entities.Transferable;
import de.thedevstack.conversationsplus.services.AbstractConnectionManager;
import de.thedevstack.conversationsplus.services.XmppConnectionService;
+import de.thedevstack.conversationsplus.utils.MessageUtil;
import de.thedevstack.conversationsplus.utils.Xmlns;
import de.thedevstack.conversationsplus.xml.Element;
import de.thedevstack.conversationsplus.xmpp.OnIqPacketReceived;
@@ -65,7 +66,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
old.cancel();
}
JingleConnection connection = new JingleConnection(this);
- mXmppConnectionService.markMessage(message,Message.STATUS_WAITING);
+ MessageUtil.markMessage(message,Message.STATUS_WAITING);
connection.init(message);
this.connections.add(connection);
return connection;
diff --git a/src/main/res/layout/dialog_message_details.xml b/src/main/res/layout/dialog_message_details.xml
index 84159f44..7c5d92cb 100644
--- a/src/main/res/layout/dialog_message_details.xml
+++ b/src/main/res/layout/dialog_message_details.xml
@@ -128,6 +128,28 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:text="@string/dlg_msg_details_httpuploaded" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text=""
+ android:textAlignment="textEnd"
+ android:gravity="end"
+ android:id="@+id/dlgMsgDetFileHttpUploaded" />
+ </TableRow>
+
+ <TableRow
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@color/white"
+ android:layout_marginTop="0.3dp"
+ android:layout_marginLeft="0.3dp"
+ android:layout_marginRight="0.3dp">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:text="@string/dlg_msg_details_file_mime" />
<TextView
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index b6aa8899..3da33010 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -670,6 +670,7 @@
<string name="select_image_and_crop">Select image and crop</string>
<string name="this_account_is_disabled">You have disabled this account</string>
<string name="cplus_copy_item">Copy item</string>
+ <string name="dlg_msg_details_httpuploaded">Shared using HTTP upload</string>
<string name="security_error_invalid_file_access">Security error: Invalid file access</string>
<string name="no_application_to_share_uri">No application found to share URI</string>
<string name="share_uri_with">Share URI with…</string>