From dbaa51bd9a21223ade9f307b08b7cb930f8364b6 Mon Sep 17 00:00:00 2001 From: Brice-W Date: Mon, 24 May 2021 12:00:17 +1000 Subject: [PATCH 1/4] implementation of polling limit on open groups --- .../securesms/database/Storage.kt | 5 +++++ .../securesms/loki/activities/HomeActivity.kt | 12 ++++++++++ .../pollers/OpenGroupPollerV2.kt | 1 + .../utilities/TextSecurePreferences.kt | 22 +++++++++++++++++++ 4 files changed, 40 insertions(+) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index 3b5b424ad0..6422930682 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -4,6 +4,7 @@ import android.content.Context import android.net.Uri import okhttp3.HttpUrl import org.session.libsession.database.StorageProtocol +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.jobs.AttachmentUploadJob import org.session.libsession.messaging.jobs.Job import org.session.libsession.messaging.jobs.JobQueue @@ -301,6 +302,8 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, } override fun getLastMessageServerId(room: String, server: String): Long? { + // return null if limit is set on open groups polling + if (TextSecurePreferences.isOpenGroupPollingLimit(context)) return null return DatabaseFactory.getLokiAPIDatabase(context).getLastMessageServerID(room, server) } @@ -325,6 +328,8 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, } override fun getLastDeletionServerId(room: String, server: String): Long? { + // return null if limit is set on open groups polling + if (TextSecurePreferences.isOpenGroupPollingLimit(context)) return null return DatabaseFactory.getLokiAPIDatabase(context).getLastDeletionServerID(room, server) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt index 1b54c5010f..3140b1aaaa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt @@ -32,6 +32,7 @@ import org.session.libsession.messaging.jobs.JobQueue import org.session.libsession.messaging.mentions.MentionsManager import org.session.libsession.messaging.open_groups.OpenGroupAPI import org.session.libsession.messaging.sending_receiving.MessageSender +import org.session.libsession.messaging.sending_receiving.pollers.OpenGroupPollerV2 import org.session.libsession.utilities.* import org.session.libsignal.utilities.toHexString import org.session.libsignal.utilities.ThreadUtils @@ -66,6 +67,8 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), // region Lifecycle override fun onCreate(savedInstanceState: Bundle?, isReady: Boolean) { super.onCreate(savedInstanceState, isReady) + // Check when Session was last opened + setPollingLimit(); // Double check that the long poller is up (applicationContext as ApplicationContext).startPollingIfNeeded() // Set content view @@ -194,6 +197,15 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), super.onDestroy() EventBus.getDefault().unregister(this) } + + fun setPollingLimit() { + val lastTimeSessionOpened = TextSecurePreferences.getLastTimeSessionOpened(this) + val timeSinceLastTimeOpen = System.currentTimeMillis() - lastTimeSessionOpened + + // activate polling limit on open groups if the app hasn't been opened for more than the duration set in MAX_INACTIVITY_PERIOD + TextSecurePreferences.setOpenGroupPollingLimit(this, timeSinceLastTimeOpen > OpenGroupPollerV2.maxInactivityPeriod) + TextSecurePreferences.setLastTimeSessionOpened(this) + } // endregion // region Updating diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/OpenGroupPollerV2.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/OpenGroupPollerV2.kt index 320c3afd97..5df6f3e3d0 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/OpenGroupPollerV2.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/OpenGroupPollerV2.kt @@ -22,6 +22,7 @@ class OpenGroupPollerV2(private val server: String, private val executorService: companion object { private val pollInterval: Long = 4 * 1000 + const val maxInactivityPeriod = 14 * 24 * 60 * 60 * 1000 } fun startIfNeeded() { diff --git a/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt b/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt index 37f2bacd0c..c835816659 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt +++ b/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt @@ -99,6 +99,11 @@ object TextSecurePreferences { private const val GIF_GRID_LAYOUT = "pref_gif_grid_layout" + // region Limit open group polling + + private const val LAST_TIME_SESSION_OPENED = "pref_last_time_session_open" + private const val OPEN_GROUP_POLLING_LIMIT = "pref_Open_group_polling_limit" + // region FCM const val IS_USING_FCM = "pref_is_using_fcm" private const val FCM_TOKEN = "pref_fcm_token" @@ -771,5 +776,22 @@ object TextSecurePreferences { fun setHasSeenFileServerInstabilityNotification(context: Context) { setBooleanPreference(context, "has_seen_file_server_instability_notification", true) } + + fun getLastTimeSessionOpened(context: Context): Long { + return getLongPreference(context!!, LAST_TIME_SESSION_OPENED, 0) + } + + fun setLastTimeSessionOpened(context: Context) { + setLongPreference(context, LAST_TIME_SESSION_OPENED, System.currentTimeMillis()) + } + + fun isOpenGroupPollingLimit(context: Context): Boolean { + return getBooleanPreference(context, OPEN_GROUP_POLLING_LIMIT, false) + } + + fun setOpenGroupPollingLimit(context: Context, limit: Boolean) { + setBooleanPreference(context, OPEN_GROUP_POLLING_LIMIT, limit) + } + // endregion } \ No newline at end of file From 6c37e7a93f95e4dc8cc750cfe23c19f0d62fe19f Mon Sep 17 00:00:00 2001 From: Brice-W Date: Mon, 24 May 2021 13:13:07 +1000 Subject: [PATCH 2/4] move logic from Storage to OpenGroupAPIV2 --- .../java/org/thoughtcrime/securesms/database/Storage.kt | 4 ---- .../libsession/messaging/open_groups/OpenGroupAPIV2.kt | 6 ++++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index 56a4b367f9..185944df95 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -233,8 +233,6 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, } override fun getLastMessageServerID(room: String, server: String): Long? { - // return null if limit is set on open groups polling - if (TextSecurePreferences.isOpenGroupPollingLimit(context)) return null return DatabaseFactory.getLokiAPIDatabase(context).getLastMessageServerID(room, server) } @@ -247,8 +245,6 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, } override fun getLastDeletionServerID(room: String, server: String): Long? { - // return null if limit is set on open groups polling - if (TextSecurePreferences.isOpenGroupPollingLimit(context)) return null return DatabaseFactory.getLokiAPIDatabase(context).getLastDeletionServerID(room, server) } diff --git a/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPIV2.kt b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPIV2.kt index 12e5fc1364..32925bdfe1 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPIV2.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPIV2.kt @@ -15,6 +15,7 @@ import okhttp3.RequestBody import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.snode.OnionRequestAPI import org.session.libsession.utilities.AESGCM +import org.session.libsession.utilities.TextSecurePreferences import org.session.libsignal.utilities.HTTP import org.session.libsignal.utilities.HTTP.Verb.* import org.session.libsignal.utilities.removing05PrefixIfNeeded @@ -349,6 +350,7 @@ object OpenGroupAPIV2 { fun compactPoll(rooms: List, server: String): Promise, Exception> { val authTokenRequests = rooms.associateWith { room -> getAuthToken(room, server) } val storage = MessagingModuleConfiguration.shared.storage + val context = MessagingModuleConfiguration.shared.context val requests = rooms.mapNotNull { room -> val authToken = try { authTokenRequests[room]?.get() @@ -359,8 +361,8 @@ object OpenGroupAPIV2 { CompactPollRequest( roomID = room, authToken = authToken, - fromDeletionServerID = storage.getLastDeletionServerID(room, server), - fromMessageServerID = storage.getLastMessageServerID(room, server) + fromDeletionServerID = if (TextSecurePreferences.isOpenGroupPollingLimit(context)) null else storage.getLastDeletionServerID(room, server), + fromMessageServerID = if (TextSecurePreferences.isOpenGroupPollingLimit(context)) null else storage.getLastMessageServerID(room, server) ) } val request = Request(verb = POST, room = null, server = server, endpoint = "compact_poll", isAuthRequired = false, parameters = mapOf( "requests" to requests )) From 2969d4b1619efd38c6e54a35e2bdbf674d187f23 Mon Sep 17 00:00:00 2001 From: Brice-W Date: Mon, 24 May 2021 13:14:37 +1000 Subject: [PATCH 3/4] clean --- .../main/java/org/thoughtcrime/securesms/database/Storage.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index 185944df95..f57318cd5b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -243,7 +243,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, override fun removeLastMessageServerID(room: String, server: String) { DatabaseFactory.getLokiAPIDatabase(context).removeLastMessageServerID(room, server) } - + override fun getLastDeletionServerID(room: String, server: String): Long? { return DatabaseFactory.getLokiAPIDatabase(context).getLastDeletionServerID(room, server) } From 639146cc0a611e2a06402932a4b43db6e3acb244 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Mon, 24 May 2021 13:48:01 +1000 Subject: [PATCH 4/4] Simplify & fix `from_server_id` usage --- .../securesms/ApplicationContext.java | 2 +- .../securesms/loki/activities/HomeActivity.kt | 11 -------- .../messaging/open_groups/OpenGroupAPIV2.kt | 21 +++++++++++++-- .../utilities/TextSecurePreferences.kt | 27 +++++-------------- 4 files changed, 26 insertions(+), 35 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index 85895cc9be..5106278b6b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -205,11 +205,11 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc contactDB.setContact(contact); } } - if (poller != null) { poller.setCaughtUp(false); } startPollingIfNeeded(); + OpenGroupManager.INSTANCE.setAllCaughtUp(false); OpenGroupManager.INSTANCE.startPolling(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt index 7433d7a34f..0e5ccd6fde 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt @@ -66,8 +66,6 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), // region Lifecycle override fun onCreate(savedInstanceState: Bundle?, isReady: Boolean) { super.onCreate(savedInstanceState, isReady) - // Check when Session was last opened - setPollingLimit(); // Double check that the long poller is up (applicationContext as ApplicationContext).startPollingIfNeeded() // Set content view @@ -192,15 +190,6 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), super.onDestroy() EventBus.getDefault().unregister(this) } - - fun setPollingLimit() { - val lastTimeSessionOpened = TextSecurePreferences.getLastTimeSessionOpened(this) - val timeSinceLastTimeOpen = System.currentTimeMillis() - lastTimeSessionOpened - - // activate polling limit on open groups if the app hasn't been opened for more than the duration set in MAX_INACTIVITY_PERIOD - TextSecurePreferences.setOpenGroupPollingLimit(this, timeSinceLastTimeOpen > OpenGroupPollerV2.maxInactivityPeriod) - TextSecurePreferences.setLastTimeSessionOpened(this) - } // endregion // region Updating diff --git a/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPIV2.kt b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPIV2.kt index 32925bdfe1..68f8d3d8d8 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPIV2.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPIV2.kt @@ -13,6 +13,7 @@ import okhttp3.HttpUrl import okhttp3.MediaType import okhttp3.RequestBody import org.session.libsession.messaging.MessagingModuleConfiguration +import org.session.libsession.messaging.sending_receiving.pollers.OpenGroupPollerV2 import org.session.libsession.snode.OnionRequestAPI import org.session.libsession.utilities.AESGCM import org.session.libsession.utilities.TextSecurePreferences @@ -31,6 +32,15 @@ object OpenGroupAPIV2 { private val moderators: HashMap> = hashMapOf() // Server URL to (channel ID to set of moderator IDs) private val curve = Curve25519.getInstance(Curve25519.BEST) val defaultRooms = MutableSharedFlow>(replay = 1) + private val hasPerformedInitialPoll = mutableMapOf() + private var hasUpdatedLastOpenDate = false + + private val timeSinceLastOpen by lazy { + val context = MessagingModuleConfiguration.shared.context + val lastOpenDate = TextSecurePreferences.getLastOpenTimeDate(context) + val now = System.currentTimeMillis() + now - lastOpenDate + } private const val defaultServerPublicKey = "a03c383cf63c3c4efe67acc52112a6dd734b3a946b9545f488aaa93da7991238" const val defaultServer = "http://116.203.70.33" @@ -351,6 +361,13 @@ object OpenGroupAPIV2 { val authTokenRequests = rooms.associateWith { room -> getAuthToken(room, server) } val storage = MessagingModuleConfiguration.shared.storage val context = MessagingModuleConfiguration.shared.context + val timeSinceLastOpen = this.timeSinceLastOpen + val useMessageLimit = (hasPerformedInitialPoll[server] != true + && timeSinceLastOpen > OpenGroupPollerV2.maxInactivityPeriod) + hasPerformedInitialPoll[server] = true + if (!hasUpdatedLastOpenDate) { + TextSecurePreferences.setLastOpenDate(context) + } val requests = rooms.mapNotNull { room -> val authToken = try { authTokenRequests[room]?.get() @@ -361,8 +378,8 @@ object OpenGroupAPIV2 { CompactPollRequest( roomID = room, authToken = authToken, - fromDeletionServerID = if (TextSecurePreferences.isOpenGroupPollingLimit(context)) null else storage.getLastDeletionServerID(room, server), - fromMessageServerID = if (TextSecurePreferences.isOpenGroupPollingLimit(context)) null else storage.getLastMessageServerID(room, server) + fromDeletionServerID = if (useMessageLimit) null else storage.getLastDeletionServerID(room, server), + fromMessageServerID = if (useMessageLimit) null else storage.getLastMessageServerID(room, server) ) } val request = Request(verb = POST, room = null, server = server, endpoint = "compact_poll", isAuthRequired = false, parameters = mapOf( "requests" to requests )) diff --git a/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt b/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt index e3f192e454..263771aa6e 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt +++ b/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt @@ -99,21 +99,16 @@ object TextSecurePreferences { private const val GIF_GRID_LAYOUT = "pref_gif_grid_layout" - // region Limit open group polling - - private const val LAST_TIME_SESSION_OPENED = "pref_last_time_session_open" - private const val OPEN_GROUP_POLLING_LIMIT = "pref_Open_group_polling_limit" - - // region FCM const val IS_USING_FCM = "pref_is_using_fcm" private const val FCM_TOKEN = "pref_fcm_token" private const val LAST_FCM_TOKEN_UPLOAD_TIME = "pref_last_fcm_token_upload_time_2" - // region Multi Device private const val LAST_CONFIGURATION_SYNC_TIME = "pref_last_configuration_sync_time" const val CONFIGURATION_SYNCED = "pref_configuration_synced" private const val LAST_PROFILE_UPDATE_TIME = "pref_last_profile_update_time" + private const val LAST_OPEN_DATE = "pref_last_open_date" + @JvmStatic fun getLastConfigurationSyncTime(context: Context): Long { return getLongPreference(context, LAST_CONFIGURATION_SYNC_TIME, 0) @@ -777,21 +772,11 @@ object TextSecurePreferences { setBooleanPreference(context, "has_performed_contact_migration", true) } - fun getLastTimeSessionOpened(context: Context): Long { - return getLongPreference(context!!, LAST_TIME_SESSION_OPENED, 0) + fun getLastOpenTimeDate(context: Context): Long { + return getLongPreference(context, LAST_OPEN_DATE, 0) } - fun setLastTimeSessionOpened(context: Context) { - setLongPreference(context, LAST_TIME_SESSION_OPENED, System.currentTimeMillis()) + fun setLastOpenDate(context: Context) { + setLongPreference(context, LAST_OPEN_DATE, System.currentTimeMillis()) } - - fun isOpenGroupPollingLimit(context: Context): Boolean { - return getBooleanPreference(context, OPEN_GROUP_POLLING_LIMIT, false) - } - - fun setOpenGroupPollingLimit(context: Context, limit: Boolean) { - setBooleanPreference(context, OPEN_GROUP_POLLING_LIMIT, limit) - } - - // endregion } \ No newline at end of file