mirror of
https://github.com/oxen-io/session-android.git
synced 2025-01-11 16:33:39 +00:00
Make the message trimming behaviour consistent across platform (#936)
* refactor: remove old trim behaviour and create new defaults * refactor: add in trimming by before time * refactor: remove old trim thread job, remove message processor scheduling trim thread * refactor: remove spacing * refactor: enable trimming by default * refactor: remove trim now option in chat preference
This commit is contained in:
parent
7d186c198e
commit
919bb01d58
@ -162,8 +162,8 @@ public class MmsSmsDatabase extends Database {
|
||||
}
|
||||
}
|
||||
|
||||
public int getConversationCount(long threadId) {
|
||||
int count = DatabaseComponent.get(context).smsDatabase().getMessageCountForThread(threadId);
|
||||
public long getConversationCount(long threadId) {
|
||||
long count = DatabaseComponent.get(context).smsDatabase().getMessageCountForThread(threadId);
|
||||
count += DatabaseComponent.get(context).mmsDatabase().getMessageCountForThread(threadId);
|
||||
|
||||
return count;
|
||||
|
@ -201,11 +201,6 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
||||
messageID = result.messageId
|
||||
}
|
||||
}
|
||||
val threadID = message.threadID
|
||||
// open group trim thread job is scheduled after processing in OpenGroupPollerV2
|
||||
if (openGroupID.isNullOrEmpty() && threadID != null && threadID >= 0 && TextSecurePreferences.isThreadLengthTrimmingEnabled(context)) {
|
||||
JobQueue.shared.queueThreadForTrim(threadID)
|
||||
}
|
||||
message.serverHash?.let { serverHash ->
|
||||
messageID?.let { id ->
|
||||
DatabaseComponent.get(context).lokiMessageDatabase().setMessageServerHash(id, serverHash)
|
||||
@ -701,6 +696,18 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
||||
threadDB.trimThread(threadID, threadLimit)
|
||||
}
|
||||
|
||||
override fun trimThreadBefore(threadID: Long, timestamp: Long) {
|
||||
val threadDB = DatabaseComponent.get(context).threadDatabase()
|
||||
threadDB.trimThreadBefore(threadID, timestamp)
|
||||
}
|
||||
|
||||
override fun getMessageCount(threadID: Long): Long {
|
||||
val mmsSmsDb = DatabaseComponent.get(context).mmsSmsDatabase()
|
||||
return mmsSmsDb.getConversationCount(threadID)
|
||||
}
|
||||
|
||||
|
||||
|
||||
override fun getAttachmentDataUri(attachmentId: AttachmentId): Uri {
|
||||
return PartAuthority.getAttachmentDataUri(attachmentId)
|
||||
}
|
||||
|
@ -281,6 +281,14 @@ public class ThreadDatabase extends Database {
|
||||
}
|
||||
}
|
||||
|
||||
public void trimThreadBefore(long threadId, long timestamp) {
|
||||
Log.i("ThreadDatabase", "Trimming thread: " + threadId + " before :"+timestamp);
|
||||
DatabaseComponent.get(context).smsDatabase().deleteMessagesInThreadBeforeDate(threadId, timestamp);
|
||||
DatabaseComponent.get(context).mmsDatabase().deleteMessagesInThreadBeforeDate(threadId, timestamp);
|
||||
update(threadId, false);
|
||||
notifyConversationListeners(threadId);
|
||||
}
|
||||
|
||||
public List<MarkedMessageInfo> setRead(long threadId, boolean lastSeen) {
|
||||
ContentValues contentValues = new ContentValues(1);
|
||||
contentValues.put(READ, 1);
|
||||
|
@ -31,7 +31,6 @@ public final class JobManagerFactories {
|
||||
put(AvatarDownloadJob.KEY, new AvatarDownloadJob.Factory());
|
||||
put(LocalBackupJob.KEY, new LocalBackupJob.Factory());
|
||||
put(RetrieveProfileAvatarJob.KEY, new RetrieveProfileAvatarJob.Factory(application));
|
||||
put(TrimThreadJob.KEY, new TrimThreadJob.Factory());
|
||||
put(UpdateApkJob.KEY, new UpdateApkJob.Factory());
|
||||
put(PrepareAttachmentAudioExtrasJob.KEY, new PrepareAttachmentAudioExtrasJob.Factory());
|
||||
}};
|
||||
|
@ -1,84 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2014 Open Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.thoughtcrime.securesms.jobs;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.session.libsession.messaging.utilities.Data;
|
||||
import org.session.libsession.utilities.TextSecurePreferences;
|
||||
import org.session.libsignal.utilities.Log;
|
||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
|
||||
public class TrimThreadJob extends BaseJob {
|
||||
|
||||
public static final String KEY = "TrimThreadJob";
|
||||
|
||||
private static final String TAG = TrimThreadJob.class.getSimpleName();
|
||||
|
||||
private static final String KEY_THREAD_ID = "thread_id";
|
||||
|
||||
private long threadId;
|
||||
|
||||
public TrimThreadJob(long threadId) {
|
||||
this(new Job.Parameters.Builder().setQueue("TrimThreadJob").build(), threadId);
|
||||
}
|
||||
|
||||
private TrimThreadJob(@NonNull Job.Parameters parameters, long threadId) {
|
||||
super(parameters);
|
||||
this.threadId = threadId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull
|
||||
Data serialize() {
|
||||
return new Data.Builder().putLong(KEY_THREAD_ID, threadId).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull String getFactoryKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRun() {
|
||||
boolean trimmingEnabled = TextSecurePreferences.isThreadLengthTrimmingEnabled(context);
|
||||
int threadLengthLimit = TextSecurePreferences.getThreadTrimLength(context);
|
||||
|
||||
if (!trimmingEnabled)
|
||||
return;
|
||||
|
||||
DatabaseComponent.get(context).threadDatabase().trimThread(threadId, threadLengthLimit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onShouldRetry(@NonNull Exception exception) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCanceled() {
|
||||
Log.w(TAG, "Canceling trim attempt: " + threadId);
|
||||
}
|
||||
|
||||
public static final class Factory implements Job.Factory<TrimThreadJob> {
|
||||
@Override
|
||||
public @NonNull TrimThreadJob create(@NonNull Parameters parameters, @NonNull Data data) {
|
||||
return new TrimThreadJob(parameters, data.getLong(KEY_THREAD_ID));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +1,11 @@
|
||||
package org.thoughtcrime.securesms.preferences;
|
||||
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.preference.EditTextPreference;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import org.session.libsession.utilities.TextSecurePreferences;
|
||||
import org.session.libsignal.utilities.Log;
|
||||
import org.thoughtcrime.securesms.permissions.Permissions;
|
||||
import org.thoughtcrime.securesms.util.Trimmer;
|
||||
|
||||
import network.loki.messenger.R;
|
||||
|
||||
@ -22,12 +15,6 @@ public class ChatsPreferenceFragment extends ListSummaryPreferenceFragment {
|
||||
@Override
|
||||
public void onCreate(Bundle paramBundle) {
|
||||
super.onCreate(paramBundle);
|
||||
|
||||
findPreference(TextSecurePreferences.THREAD_TRIM_NOW)
|
||||
.setOnPreferenceClickListener(new TrimNowClickListener());
|
||||
findPreference(TextSecurePreferences.THREAD_TRIM_LENGTH)
|
||||
.setOnPreferenceChangeListener(new TrimLengthValidationListener());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -50,57 +37,4 @@ public class ChatsPreferenceFragment extends ListSummaryPreferenceFragment {
|
||||
Permissions.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
|
||||
}
|
||||
|
||||
private class TrimNowClickListener implements Preference.OnPreferenceClickListener {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
final int threadLengthLimit = TextSecurePreferences.getThreadTrimLength(getActivity());
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
builder.setTitle(R.string.ApplicationPreferencesActivity_delete_all_old_messages_now);
|
||||
builder.setMessage(getResources().getQuantityString(R.plurals.ApplicationPreferencesActivity_this_will_immediately_trim_all_conversations_to_the_d_most_recent_messages,
|
||||
threadLengthLimit, threadLengthLimit));
|
||||
builder.setPositiveButton(R.string.ApplicationPreferencesActivity_delete,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Trimmer.trimAllThreads(getActivity(), threadLengthLimit);
|
||||
}
|
||||
});
|
||||
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
builder.show();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class TrimLengthValidationListener implements Preference.OnPreferenceChangeListener {
|
||||
|
||||
public TrimLengthValidationListener() {
|
||||
EditTextPreference preference = findPreference(TextSecurePreferences.THREAD_TRIM_LENGTH);
|
||||
onPreferenceChange(preference, preference.getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
if (newValue == null || ((String)newValue).trim().length() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int value;
|
||||
try {
|
||||
value = Integer.parseInt((String)newValue);
|
||||
} catch (NumberFormatException nfe) {
|
||||
Log.w(TAG, nfe);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (value < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
preference.setSummary(getResources().getQuantityString(R.plurals.ApplicationPreferencesActivity_messages_per_conversation, value, value));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!-- <PreferenceCategory android:key="media_download" android:title="@string/preferences_chats__media_auto_download">
|
||||
|
||||
@ -73,19 +71,6 @@
|
||||
android:summary="@string/preferences__automatically_delete_older_messages_once_a_conversation_exceeds_a_specified_length"
|
||||
android:title="@string/preferences__delete_old_messages" />
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="500"
|
||||
android:key="pref_trim_length"
|
||||
android:title="@string/preferences__conversation_length_limit"
|
||||
android:inputType="number"
|
||||
android:dependency="pref_trim_threads" />
|
||||
|
||||
<Preference
|
||||
android:key="pref_trim_now"
|
||||
android:title="@string/preferences__trim_all_conversations_now"
|
||||
android:summary="@string/preferences__scan_through_all_conversations_and_enforce_conversation_length_limits"
|
||||
android:dependency="pref_trim_threads" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<!-- <PreferenceCategory android:layout="@layout/preference_divider" />
|
||||
|
@ -151,6 +151,8 @@ interface StorageProtocol {
|
||||
fun getThreadIdForMms(mmsId: Long): Long
|
||||
fun getLastUpdated(threadID: Long): Long
|
||||
fun trimThread(threadID: Long, threadLimit: Int)
|
||||
fun trimThreadBefore(threadID: Long, timestamp: Long)
|
||||
fun getMessageCount(threadID: Long): Long
|
||||
|
||||
// Contacts
|
||||
fun getContactWithSessionID(sessionID: String): Contact?
|
||||
|
@ -31,7 +31,6 @@ class JobQueue : JobDelegate {
|
||||
private val scope = CoroutineScope(Dispatchers.Default) + SupervisorJob()
|
||||
private val queue = Channel<Job>(UNLIMITED)
|
||||
private val pendingJobIds = mutableSetOf<String>()
|
||||
private val pendingTrimThreadIds = mutableSetOf<Long>()
|
||||
|
||||
private val openGroupChannels = mutableMapOf<String, Channel<Job>>()
|
||||
|
||||
@ -115,15 +114,6 @@ class JobQueue : JobDelegate {
|
||||
val openGroupJob = processWithOpenGroupDispatcher(openGroupQueue, openGroupDispatcher, "openGroup")
|
||||
|
||||
while (isActive) {
|
||||
if (queue.isEmpty && pendingTrimThreadIds.isNotEmpty()) {
|
||||
// process trim thread jobs
|
||||
val pendingThreads = pendingTrimThreadIds.toList()
|
||||
pendingTrimThreadIds.clear()
|
||||
for (thread in pendingThreads) {
|
||||
Log.d("Loki", "Trimming thread $thread")
|
||||
queue.trySend(TrimThreadJob(thread, null))
|
||||
}
|
||||
}
|
||||
when (val job = queue.receive()) {
|
||||
is NotifyPNServerJob, is AttachmentUploadJob, is MessageSendJob -> {
|
||||
txQueue.send(job)
|
||||
@ -165,10 +155,6 @@ class JobQueue : JobDelegate {
|
||||
val shared: JobQueue by lazy { JobQueue() }
|
||||
}
|
||||
|
||||
fun queueThreadForTrim(threadId: Long) {
|
||||
pendingTrimThreadIds += threadId
|
||||
}
|
||||
|
||||
fun add(job: Job) {
|
||||
addWithoutExecuting(job)
|
||||
queue.trySend(job) // offer always called on unlimited capacity
|
||||
|
@ -15,14 +15,19 @@ class TrimThreadJob(val threadId: Long, val openGroupId: String?) : Job {
|
||||
const val KEY: String = "TrimThreadJob"
|
||||
const val THREAD_ID = "thread_id"
|
||||
const val OPEN_GROUP_ID = "open_group"
|
||||
|
||||
const val TRIM_TIME_LIMIT = 15552000000L // trim messages older than this
|
||||
const val THREAD_LENGTH_TRIGGER_SIZE = 2000
|
||||
}
|
||||
|
||||
override fun execute() {
|
||||
val context = MessagingModuleConfiguration.shared.context
|
||||
val trimmingEnabled = TextSecurePreferences.isThreadLengthTrimmingEnabled(context)
|
||||
val threadLengthLimit = TextSecurePreferences.getThreadTrimLength(context)
|
||||
if (trimmingEnabled) {
|
||||
MessagingModuleConfiguration.shared.storage.trimThread(threadId, threadLengthLimit)
|
||||
val storage = MessagingModuleConfiguration.shared.storage
|
||||
val messageCount = storage.getMessageCount(threadId)
|
||||
if (trimmingEnabled && !openGroupId.isNullOrEmpty() && messageCount >= THREAD_LENGTH_TRIGGER_SIZE) {
|
||||
val oldestMessageTime = System.currentTimeMillis() - TRIM_TIME_LIMIT
|
||||
storage.trimThreadBefore(threadId, oldestMessageTime)
|
||||
}
|
||||
delegate?.handleJobSucceeded(this)
|
||||
}
|
||||
|
@ -117,7 +117,6 @@ interface TextSecurePreferences {
|
||||
fun getNotificationLedPattern(): String?
|
||||
fun getNotificationLedPatternCustom(): String?
|
||||
fun isThreadLengthTrimmingEnabled(): Boolean
|
||||
fun getThreadTrimLength(): Int
|
||||
fun isSystemEmojiPreferred(): Boolean
|
||||
fun getMobileMediaDownloadAllowed(): Set<String>?
|
||||
fun getWifiMediaDownloadAllowed(): Set<String>?
|
||||
@ -175,7 +174,6 @@ interface TextSecurePreferences {
|
||||
|
||||
const val DISABLE_PASSPHRASE_PREF = "pref_disable_passphrase"
|
||||
const val LANGUAGE_PREF = "pref_language"
|
||||
const val THREAD_TRIM_LENGTH = "pref_trim_length"
|
||||
const val THREAD_TRIM_NOW = "pref_trim_now"
|
||||
const val LAST_VERSION_CODE_PREF = "last_version_code"
|
||||
const val RINGTONE_PREF = "pref_key_ringtone"
|
||||
@ -705,12 +703,7 @@ interface TextSecurePreferences {
|
||||
|
||||
@JvmStatic
|
||||
fun isThreadLengthTrimmingEnabled(context: Context): Boolean {
|
||||
return getBooleanPreference(context, THREAD_TRIM_ENABLED, false)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getThreadTrimLength(context: Context): Int {
|
||||
return getStringPreference(context, THREAD_TRIM_LENGTH, "500")!!.toInt()
|
||||
return getBooleanPreference(context, THREAD_TRIM_ENABLED, true)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@ -1329,11 +1322,7 @@ class AppTextSecurePreferences @Inject constructor(
|
||||
}
|
||||
|
||||
override fun isThreadLengthTrimmingEnabled(): Boolean {
|
||||
return getBooleanPreference(TextSecurePreferences.THREAD_TRIM_ENABLED, false)
|
||||
}
|
||||
|
||||
override fun getThreadTrimLength(): Int {
|
||||
return getStringPreference(TextSecurePreferences.THREAD_TRIM_LENGTH, "500")!!.toInt()
|
||||
return getBooleanPreference(TextSecurePreferences.THREAD_TRIM_ENABLED, true)
|
||||
}
|
||||
|
||||
override fun isSystemEmojiPreferred(): Boolean {
|
||||
|
Loading…
x
Reference in New Issue
Block a user