aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/java/de/pixart/messenger/Config.java2
-rw-r--r--src/main/java/de/pixart/messenger/entities/Conversation.java14
-rw-r--r--src/main/java/de/pixart/messenger/parser/MessageParser.java10
-rw-r--r--src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java7
-rw-r--r--src/main/java/de/pixart/messenger/services/MessageArchiveService.java11
-rw-r--r--src/main/java/de/pixart/messenger/services/XmppConnectionService.java67
-rw-r--r--src/main/java/de/pixart/messenger/ui/ConversationActivity.java7
-rw-r--r--src/main/java/de/pixart/messenger/ui/ConversationFragment.java11
-rw-r--r--src/main/java/de/pixart/messenger/ui/SettingsActivity.java3
-rw-r--r--src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java11
-rw-r--r--src/main/res/values-de/strings.xml7
-rw-r--r--src/main/res/values/arrays.xml20
-rw-r--r--src/main/res/values/strings.xml3
-rw-r--r--src/main/res/xml/preferences.xml12
14 files changed, 141 insertions, 44 deletions
diff --git a/src/main/java/de/pixart/messenger/Config.java b/src/main/java/de/pixart/messenger/Config.java
index fcd5948b0..eef639e40 100644
--- a/src/main/java/de/pixart/messenger/Config.java
+++ b/src/main/java/de/pixart/messenger/Config.java
@@ -125,6 +125,8 @@ public final class Config {
public static final ChatState DEFAULT_CHATSTATE = ChatState.ACTIVE;
public static final int TYPING_TIMEOUT = 5;
+ public static final int EXPIRY_INTERVAL = 30 * 60 * 1000; // 30 minutes
+
public static final String UPDATE_URL = BuildConfig.UPDATE_URL;
public static final long UPDATE_CHECK_TIMER = 24 * 60 * 60; // in seconds
diff --git a/src/main/java/de/pixart/messenger/entities/Conversation.java b/src/main/java/de/pixart/messenger/entities/Conversation.java
index 0928c2ebf..526c60f6c 100644
--- a/src/main/java/de/pixart/messenger/entities/Conversation.java
+++ b/src/main/java/de/pixart/messenger/entities/Conversation.java
@@ -20,7 +20,9 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
+import java.util.ListIterator;
import java.util.Locale;
+import java.util.concurrent.atomic.AtomicBoolean;
import de.pixart.messenger.Config;
import de.pixart.messenger.crypto.PgpDecryptionService;
@@ -90,6 +92,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
private String mLastReceivedOtrMessageId = null;
private String mFirstMamReference = null;
private Message correctingMessage;
+ public AtomicBoolean messagesLoaded = new AtomicBoolean(true);
public boolean hasMessagesLeftOnServer() {
return messagesLeftOnServer;
@@ -943,6 +946,17 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
account.getPgpDecryptionService().decrypt(messages);
}
+ public void expireOldMessages(long timestamp) {
+ synchronized (this.messages) {
+ for (ListIterator<Message> iterator = this.messages.listIterator(); iterator.hasNext(); ) {
+ if (iterator.next().getTimeSent() < timestamp) {
+ iterator.remove();
+ }
+ }
+ untieMessages();
+ }
+ }
+
public void sort() {
synchronized (this.messages) {
Collections.sort(this.messages, new Comparator<Message>() {
diff --git a/src/main/java/de/pixart/messenger/parser/MessageParser.java b/src/main/java/de/pixart/messenger/parser/MessageParser.java
index ec341eb37..b69b5312e 100644
--- a/src/main/java/de/pixart/messenger/parser/MessageParser.java
+++ b/src/main/java/de/pixart/messenger/parser/MessageParser.java
@@ -520,6 +520,12 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
}
}
+ long deletionDate = mXmppConnectionService.getAutomaticMessageDeletionDate();
+ if (deletionDate != 0 && message.getTimeSent() < deletionDate) {
+ Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": skipping message from " + message.getCounterpart().toString() + " because it was sent prior to our deletion date");
+ return;
+ }
+
boolean checkForDuplicates = query != null
|| (isTypeGroupChat && packet.hasChild("delay", "urn:xmpp:delay"))
|| message.getType() == Message.TYPE_PRIVATE;
@@ -565,9 +571,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
conversation.endOtrIfNeeded();
}
- if (message.getEncryption() == Message.ENCRYPTION_NONE || mXmppConnectionService.saveEncryptedMessages()) {
- mXmppConnectionService.databaseBackend.createMessage(message);
- }
+ mXmppConnectionService.databaseBackend.createMessage(message);
final HttpConnectionManager manager = this.mXmppConnectionService.getHttpConnectionManager();
if (message.trusted() && message.treatAsDownloadable() != Message.Decision.NEVER && manager.getAutoAcceptFileSize() > 0) {
manager.createNewDownloadConnection(message);
diff --git a/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java b/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java
index bb4652308..b40452f1a 100644
--- a/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java
+++ b/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java
@@ -774,6 +774,13 @@ public class DatabaseBackend extends SQLiteOpenHelper {
db.delete(Message.TABLENAME, Message.CONVERSATION + "=?", args);
}
+ public boolean expireOldMessages(long timestamp) {
+ String where = Message.TIME_SENT + "<?";
+ String[] whereArgs = {String.valueOf(timestamp)};
+ SQLiteDatabase db = this.getReadableDatabase();
+ return db.delete(Message.TABLENAME, where, whereArgs) > 0;
+ }
+
public Pair<Long, String> getLastMessageReceived(Account account) {
Cursor cursor = null;
try {
diff --git a/src/main/java/de/pixart/messenger/services/MessageArchiveService.java b/src/main/java/de/pixart/messenger/services/MessageArchiveService.java
index 4a1fe2a87..003f12991 100644
--- a/src/main/java/de/pixart/messenger/services/MessageArchiveService.java
+++ b/src/main/java/de/pixart/messenger/services/MessageArchiveService.java
@@ -56,6 +56,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
startCatchup = lastClearDate.first;
reference = null;
}
+ startCatchup = Math.max(startCatchup,mXmppConnectionService.getAutomaticMessageDeletionDate());
long endCatchup = account.getXmppConnection().getLastSessionEstablished();
final Query query;
if (startCatchup == 0) {
@@ -107,12 +108,14 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
public Query query(Conversation conversation, long start, long end) {
synchronized (this.queries) {
- if (start > end) {
- return null;
- }
final Query query = new Query(conversation, start, end, PagingOrder.REVERSE);
if (start == 0) {
query.reference = conversation.getFirstMamReference();
+ Log.d(Config.LOGTAG, "setting mam reference");
+ }
+ query.start = Math.max(start, mXmppConnectionService.getAutomaticMessageDeletionDate());
+ if (start > end) {
+ return null;
}
this.queries.add(query);
this.execute(query);
@@ -222,7 +225,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
query.getConversation().setFirstMamReference(first == null ? null : first.getContent());
}
if (complete || relevant == null || abort) {
- final boolean done = (complete || query.getMessageCount() == 0) && query.getStart() == 0;
+ final boolean done = (complete || query.getMessageCount() == 0) && query.getStart() <= mXmppConnectionService.getAutomaticMessageDeletionDate();
this.finalizeQuery(query, done);
Log.d(Config.LOGTAG, query.getAccount().getJid().toBareJid() + ": finished mam after " + query.getTotalCount() + " messages. messages left=" + Boolean.toString(!done));
if (query.getWith() == null && query.getMessageCount() > 0) {
diff --git a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
index 1c7118f0f..55b87074a 100644
--- a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
+++ b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
@@ -69,6 +69,7 @@ import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicLong;
import de.duenndns.ssl.MemorizingTrustManager;
import de.pixart.messenger.Config;
@@ -300,6 +301,7 @@ public class XmppConnectionService extends Service {
}
};
private int keyStatusUpdatedListenerCount = 0;
+ private AtomicLong mLastExpiryRun = new AtomicLong(0);
private SecureRandom mRandom;
private LruCache<Pair<String, String>, ServiceDiscoveryResult> discoCache = new LruCache<>(20);
private OnStatusChanged statusListener = new OnStatusChanged() {
@@ -518,7 +520,6 @@ public class XmppConnectionService extends Service {
if (!progressTracker.contains(p) && p != 100 && p != 0) {
progressTracker.add(p);
if (informableCallback != null) {
-
informableCallback.inform(getString(R.string.transcoding_video_progress, p));
}
}
@@ -560,7 +561,6 @@ public class XmppConnectionService extends Service {
} else {
processAsFile();
}
-
}
});
}
@@ -715,6 +715,9 @@ public class XmppConnectionService extends Service {
}
}
}
+ if (SystemClock.elapsedRealtime() - mLastExpiryRun.get() >= Config.EXPIRY_INTERVAL) {
+ expireOldMessages();
+ }
return START_STICKY;
}
@@ -925,6 +928,33 @@ public class XmppConnectionService extends Service {
}
}
+ private void expireOldMessages() {
+ expireOldMessages(false);
+ }
+
+ public void expireOldMessages(final boolean resetHasMessagesLeftOnServer) {
+ mLastExpiryRun.set(SystemClock.elapsedRealtime());
+ mDatabaseExecutor.execute(new Runnable() {
+ @Override
+ public void run() {
+ long timestamp = getAutomaticMessageDeletionDate();
+ if (timestamp > 0) {
+ databaseBackend.expireOldMessages(timestamp);
+ synchronized (XmppConnectionService.this.conversations) {
+ for (Conversation conversation : XmppConnectionService.this.conversations) {
+ conversation.expireOldMessages(timestamp);
+ if (resetHasMessagesLeftOnServer) {
+ conversation.messagesLoaded.set(true);
+ conversation.setHasMessagesLeftOnServer(true);
+ }
+ }
+ }
+ updateConversationUi();
+ }
+ }
+ });
+ }
+
public boolean hasInternetConnection() {
ConnectivityManager cm = (ConnectivityManager) getApplicationContext()
.getSystemService(Context.CONNECTIVITY_SERVICE);
@@ -1338,12 +1368,10 @@ public class XmppConnectionService extends Service {
if (addToConversation) {
conversation.add(message);
}
- if (message.getEncryption() == Message.ENCRYPTION_NONE || saveEncryptedMessages()) {
- if (saveInDb) {
- databaseBackend.createMessage(message);
- } else if (message.edited()) {
- databaseBackend.updateMessage(message, message.getEditedId());
- }
+ if (saveInDb) {
+ databaseBackend.createMessage(message);
+ } else if (message.edited()) {
+ databaseBackend.updateMessage(message, message.getEditedId());
}
updateConversationUi();
}
@@ -1453,6 +1481,12 @@ public class XmppConnectionService extends Service {
Runnable runnable = new Runnable() {
@Override
public void run() {
+ long deletionDate = getAutomaticMessageDeletionDate();
+ mLastExpiryRun.set(SystemClock.elapsedRealtime());
+ if (deletionDate > 0) {
+ Log.d(Config.LOGTAG, "deleting messages that are older than " + AbstractGenerator.getTimestamp(deletionDate));
+ databaseBackend.expireOldMessages(deletionDate);
+ }
Log.d(Config.LOGTAG, "restoring roster");
for (Account account : accounts) {
databaseBackend.readRoster(account.getRoster());
@@ -1624,8 +1658,10 @@ public class XmppConnectionService extends Service {
MessageArchiveService.Query query = getMessageArchiveService().query(conversation, 0, timestamp);
if (query != null) {
query.setCallback(callback);
+ callback.informUser(R.string.fetching_history_from_server);
+ } else {
+ callback.informUser(R.string.not_fetching_history_retention_period);
}
- callback.informUser(R.string.fetching_history_from_server);
}
}
}
@@ -3152,6 +3188,15 @@ public class XmppConnectionService extends Service {
.getDefaultSharedPreferences(getApplicationContext());
}
+ public long getAutomaticMessageDeletionDate() {
+ try {
+ final long timeout = Long.parseLong(getPreferences().getString(SettingsActivity.AUTOMATIC_MESSAGE_DELETION, "0")) * 1000;
+ return timeout == 0 ? timeout : System.currentTimeMillis() - timeout;
+ } catch (NumberFormatException e) {
+ return 0;
+ }
+ }
+
public boolean confirmMessages() {
return getPreferences().getBoolean("confirm_messages", true);
}
@@ -3164,10 +3209,6 @@ public class XmppConnectionService extends Service {
return getPreferences().getBoolean("chat_states", true);
}
- public boolean saveEncryptedMessages() {
- return !getPreferences().getBoolean("dont_save_encrypted", false);
- }
-
private boolean respectAutojoin() {
return getPreferences().getBoolean("autojoin", true);
}
diff --git a/src/main/java/de/pixart/messenger/ui/ConversationActivity.java b/src/main/java/de/pixart/messenger/ui/ConversationActivity.java
index bc9c7ea1b..0dfd7bc14 100644
--- a/src/main/java/de/pixart/messenger/ui/ConversationActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/ConversationActivity.java
@@ -2137,11 +2137,4 @@ public class ConversationActivity extends XmppActivity
startActivity(intent);
}
}
-
- public void setMessagesLoaded() {
- if (mConversationFragment != null) {
- mConversationFragment.setMessagesLoaded();
- mConversationFragment.updateMessages();
- }
- }
}
diff --git a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java
index c515aeb29..5b17e7179 100644
--- a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java
+++ b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java
@@ -118,7 +118,6 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
private RelativeLayout snackbar;
private TextView snackbarMessage;
private TextView snackbarAction;
- private boolean messagesLoaded = true;
private Toast messageLoaderToast;
private OnScrollListener mOnScrollListener = new OnScrollListener() {
@@ -133,14 +132,13 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
synchronized (ConversationFragment.this.messageList) {
- if (firstVisibleItem < 5 && messagesLoaded && messageList.size() > 0) {
+ if (firstVisibleItem < 5 && conversation != null && conversation.messagesLoaded.compareAndSet(true,false) && messageList.size() > 0) {
long timestamp;
if (messageList.get(0).getType() == Message.TYPE_STATUS && messageList.size() >= 2) {
timestamp = messageList.get(1).getTimeSent();
} else {
timestamp = messageList.get(0).getTimeSent();
}
- messagesLoaded = false;
activity.xmppConnectionService.loadMoreMessages(conversation, timestamp, new XmppConnectionService.OnMoreMessagesLoaded() {
@Override
public void onMoreMessagesLoaded(final int c, Conversation conversation) {
@@ -169,7 +167,6 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
messageListAdapter.notifyDataSetChanged();
int pos = Math.max(getIndexOf(uuid, messageList), 0);
messagesView.setSelectionFromTop(pos, pxOffset);
- messagesLoaded = true;
if (messageLoaderToast != null) {
messageLoaderToast.cancel();
}
@@ -387,10 +384,6 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
private ConversationActivity activity;
private Message selectedMessage;
- public void setMessagesLoaded() {
- this.messagesLoaded = true;
- }
-
private void sendMessage() {
final String body = mEditMessage.getText().toString();
if (body.length() == 0 || this.conversation == null) {
@@ -937,7 +930,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
messageListAdapter.updatePreferences();
this.messagesView.setAdapter(messageListAdapter);
updateMessages();
- this.messagesLoaded = true;
+ this.conversation.messagesLoaded.set(true);
synchronized (this.messageList) {
final Message first = conversation.getFirstUnreadMessage();
final int bottom = Math.max(0, this.messageList.size() - 1);
diff --git a/src/main/java/de/pixart/messenger/ui/SettingsActivity.java b/src/main/java/de/pixart/messenger/ui/SettingsActivity.java
index 7c3131a0f..6624266f7 100644
--- a/src/main/java/de/pixart/messenger/ui/SettingsActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/SettingsActivity.java
@@ -40,6 +40,7 @@ public class SettingsActivity extends XmppActivity implements
public static final String TREAT_VIBRATE_AS_SILENT = "treat_vibrate_as_silent";
public static final String MANUALLY_CHANGE_PRESENCE = "manually_change_presence";
public static final String BLIND_TRUST_BEFORE_VERIFICATION = "btbv";
+ public static final String AUTOMATIC_MESSAGE_DELETION = "automatic_message_deletion";
public static final int REQUEST_WRITE_LOGS = 0xbf8701;
private SettingsFragment mSettingsFragment;
@@ -263,6 +264,8 @@ public class SettingsActivity extends XmppActivity implements
reconnectAccounts();
} else if (name.equals("use_tor")) {
reconnectAccounts();
+ } else if (name.equals(AUTOMATIC_MESSAGE_DELETION)) {
+ xmppConnectionService.expireOldMessages(true);
}
}
diff --git a/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java b/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java
index 2f99b6b99..385fa184b 100644
--- a/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java
+++ b/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java
@@ -62,6 +62,7 @@ import de.pixart.messenger.entities.Message;
import de.pixart.messenger.entities.Message.FileParams;
import de.pixart.messenger.entities.Transferable;
import de.pixart.messenger.persistance.FileBackend;
+import de.pixart.messenger.services.MessageArchiveService;
import de.pixart.messenger.services.NotificationService;
import de.pixart.messenger.ui.ConversationActivity;
import de.pixart.messenger.ui.ShowFullscreenMessageActivity;
@@ -679,9 +680,13 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
if (timestamp == 0) {
timestamp = System.currentTimeMillis();
}
- activity.setMessagesLoaded();
- activity.xmppConnectionService.getMessageArchiveService().query(conversation, 0, timestamp);
- Toast.makeText(activity, R.string.fetching_history_from_server, Toast.LENGTH_LONG).show();
+ conversation.messagesLoaded.set(true);
+ MessageArchiveService.Query query = activity.xmppConnectionService.getMessageArchiveService().query(conversation, 0, timestamp);
+ if (query != null) {
+ Toast.makeText(activity, R.string.fetching_history_from_server, Toast.LENGTH_LONG).show();
+ } else {
+ Toast.makeText(activity, R.string.not_fetching_history_retention_period, Toast.LENGTH_SHORT).show();
+ }
}
@Override
diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml
index f3af24fa5..b3f808120 100644
--- a/src/main/res/values-de/strings.xml
+++ b/src/main/res/values-de/strings.xml
@@ -681,5 +681,12 @@
<string name="distrust_omemo_key">Gerät misstrauen</string>
<string name="distrust_omemo_key_text">Bist du sicher, dass du die Verifizierung dieses Gerätes misstrauen möchtest? Dieses Gerät und Nachrichten von dem Gerät werden als unverifiziert markiert.</string>
<string name="transcoding_video_progress">Video wird komprimiert (%s%% fertiggestellt)</string>
+ <string name="encrypting_message">Nachricht wird verschlüsselt</string>
+ <string name="pref_automatically_delete_messages">Nachrichten automatisch löschen</string>
+ <string name="pref_automatically_delete_messages_description">Nachrichten von diesel Gerät nach dem eingestellten Zeitfenster automatisch löschen.</string>
+ <string name="timeout_24_hours">24 Studnen</string>
+ <string name="timeout_30_days">30 Tage</string>
+ <string name="timeout_6_months">6 Monate</string>
+ <string name="timeout_7_days">7 Tage</string>
</resources>
diff --git a/src/main/res/values/arrays.xml b/src/main/res/values/arrays.xml
index 821fd7068..a4b20e3ab 100644
--- a/src/main/res/values/arrays.xml
+++ b/src/main/res/values/arrays.xml
@@ -84,4 +84,24 @@
<item>@string/presence_dnd</item>
</string-array>
+ <string-array name="automatic_message_deletion_values">
+ <item>0</item>
+ <item>86400</item>
+ <item>604800</item>
+ <item>2592000</item>
+ <item>15811200</item>
+ </string-array>
+
+ <string-array name="automatic_message_deletion">
+ <item>@string/never</item>
+ <item>@string/timeout_24_hours</item>
+ <item>@string/timeout_7_days</item>
+ <item>@string/timeout_30_days</item>
+ <item>@string/timeout_6_months</item>
+ </string-array>
+
+ <string name="timeout_24_hours">24 hours</string>
+ <string name="timeout_7_days">7 days</string>
+ <string name="timeout_30_days">30 days</string>
+ <string name="timeout_6_months">6 months</string>
</resources>
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 9b40b97c3..738b2a441 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -727,4 +727,7 @@
<string name="reply">Reply</string>
<string name="encrypting_message">Encrypting message</string>
<string name="transcoding_video_progress">Compressing video (%s%% completed)</string>
+ <string name="pref_automatically_delete_messages_description">Automatically delete messages from this device that are older than the configured time frame.</string>
+ <string name="pref_automatically_delete_messages">Automatic message deletion</string>
+ <string name="not_fetching_history_retention_period">Overstepping local retention period.</string>
</resources>
diff --git a/src/main/res/xml/preferences.xml b/src/main/res/xml/preferences.xml
index 92078afc0..05d4551fb 100644
--- a/src/main/res/xml/preferences.xml
+++ b/src/main/res/xml/preferences.xml
@@ -225,11 +225,13 @@
android:key="btbv"
android:title="@string/pref_blind_trust_before_verification"
android:summary="@string/pref_blind_trust_before_verification_summary" />
- <CheckBoxPreference
- android:defaultValue="false"
- android:key="dont_save_encrypted"
- android:summary="@string/pref_dont_save_encrypted_summary"
- android:title="@string/pref_dont_save_encrypted" />
+ <ListPreference
+ android:defaultValue="0"
+ android:entries="@array/automatic_message_deletion"
+ android:entryValues="@array/automatic_message_deletion_values"
+ android:key="automatic_message_deletion"
+ android:summary="@string/pref_automatically_delete_messages_description"
+ android:title="@string/pref_automatically_delete_messages" />
<Preference
android:key="delete_omemo_identities"
android:title="@string/pref_delete_omemo_identities"