diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt index f8adcb84d2..61bdd8ef86 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt @@ -9,6 +9,7 @@ import android.text.SpannableStringBuilder import android.text.style.ForegroundColorSpan import net.osmand.PlatformUtil import net.osmand.telegram.helpers.OsmandAidlHelper +import net.osmand.telegram.helpers.ShareLocationHelper.Companion.MAX_MESSAGES_IN_TDLIB_PER_CHAT import net.osmand.telegram.helpers.ShowLocationHelper import net.osmand.telegram.helpers.TelegramHelper import net.osmand.telegram.utils.* @@ -22,6 +23,7 @@ import java.util.* import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentLinkedQueue import kotlin.collections.ArrayList +import kotlin.math.max val ADDITIONAL_ACTIVE_TIME_VALUES_SEC = listOf(15 * 60L, 30 * 60L, 60 * 60L, 180 * 60L) @@ -529,6 +531,7 @@ class TelegramSettings(private val app: TelegramApplication) { var initializing = false var sendChatsErrors = false + val chatsCount = shareChatsInfo.size shareChatsInfo.forEach { (_, shareInfo) -> val initTime = (currentTime - shareInfo.start) < SHARING_INITIALIZATION_TIME var initSending = false @@ -537,15 +540,16 @@ class TelegramSettings(private val app: TelegramApplication) { if (initTime && initSending) { initializing = true } else { - val textSharingError = !shareInfo.lastTextMessageHandled && currentTime - shareInfo.lastSendTextMessageTime > WAITING_TDLIB_TIME - val mapSharingError = !shareInfo.lastMapMessageHandled && currentTime - shareInfo.lastSendMapMessageTime > WAITING_TDLIB_TIME + val maxWaitingTime = WAITING_TDLIB_TIME * MAX_MESSAGES_IN_TDLIB_PER_CHAT * max(1, chatsCount) + val textSharingError = !shareInfo.lastTextMessageHandled && currentTime - shareInfo.lastSendTextMessageTime > maxWaitingTime + val mapSharingError = !shareInfo.lastMapMessageHandled && currentTime - shareInfo.lastSendMapMessageTime > maxWaitingTime if (shareInfo.hasSharingError || (shareTypeValue == SHARE_TYPE_MAP_AND_TEXT && (textSharingError || mapSharingError)) || textSharingError && (shareTypeValue == SHARE_TYPE_TEXT) || mapSharingError && (shareTypeValue == SHARE_TYPE_MAP) ) { sendChatsErrors = true - locationTime = Math.max(shareInfo.lastTextSuccessfulSendTime, shareInfo.lastMapSuccessfulSendTime) + locationTime = max(shareInfo.lastTextSuccessfulSendTime, shareInfo.lastMapSuccessfulSendTime) chatsIds.add(shareInfo.chatId) } } @@ -1455,6 +1459,7 @@ class TelegramSettings(private val app: TelegramApplication) { var additionalActiveTime = ADDITIONAL_ACTIVE_TIME_VALUES_SEC[0] var lastMapMessageHandled = false var lastTextMessageHandled = false + var lastBufferCheckTime = -1L fun getNextAdditionalActiveTime(): Long { var index = ADDITIONAL_ACTIVE_TIME_VALUES_SEC.indexOf(additionalActiveTime) @@ -1469,6 +1474,13 @@ class TelegramSettings(private val app: TelegramApplication) { return userSetLivePeriod - ((System.currentTimeMillis() / 1000) - start) } + fun isPendingMessagesLimitReached() = + pendingTdLibText >= MAX_MESSAGES_IN_TDLIB_PER_CHAT || pendingTdLibMap >= MAX_MESSAGES_IN_TDLIB_PER_CHAT + + fun isPendingTextMessagesLimitReached() = pendingTdLibText >= MAX_MESSAGES_IN_TDLIB_PER_CHAT + + fun isPendingMapMessagesLimitReached() = pendingTdLibMap >= MAX_MESSAGES_IN_TDLIB_PER_CHAT + companion object { internal const val CHAT_ID_KEY = "chatId" diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt index 7fbb026399..83ffda291b 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt @@ -15,24 +15,25 @@ import org.json.JSONObject private const val USER_SET_LIVE_PERIOD_DELAY_MS = 5000 // 5 sec -private const val SENT_LOCATIONS_INTERVAL_TIME_MS = 4000 // 4 sec +private const val MIN_MESSAGE_SENDING_INTERVAL_MS = 1000 // 1 sec +private const val MIN_MESSAGES_BUFFER_CHECK_INTERVAL_MS = 800 // 0.8 sec class ShareLocationHelper(private val app: TelegramApplication) { private val log = PlatformUtil.getLog(ShareLocationHelper::class.java) - var sharingLocation: Boolean = false + var sharingLocation = false private set - var duration: Long = 0 + var duration = 0L private set - var distance: Int = 0 + var distance = 0 private set - var lastLocationUpdateTime: Long = 0 + var lastLocationUpdateTime = 0L - var lastLocationSentTime: Long = 0 + private var lastShareLocationMessageTime = 0L var lastLocation: Location? = null set(value) { @@ -121,29 +122,32 @@ class ShareLocationHelper(private val app: TelegramApplication) { fun checkAndSendBufferMessages() { log.debug("checkAndSendBufferMessages") - var bufferedMessagesFull = false + var pendingMessagesLimitReached = false app.settings.getChatsShareInfo().forEach { (chatId, shareInfo) -> - checkAndSendBufferMessagesToChat(chatId) - if (shareInfo.pendingTdLibText >= MAX_MESSAGES_IN_TDLIB_PER_CHAT || shareInfo.pendingTdLibMap >= MAX_MESSAGES_IN_TDLIB_PER_CHAT) { - bufferedMessagesFull = true + checkAndSendBufferMessagesToChat(chatId, true) + if (shareInfo.isPendingMessagesLimitReached()) { + pendingMessagesLimitReached = true } } - if (bufferedMessagesFull) { + if (pendingMessagesLimitReached) { checkNetworkType() } } - fun checkAndSendBufferMessagesToChat(chatId: Long) { + fun checkAndSendBufferMessagesToChat(chatId: Long, forced: Boolean = false): Int { val shareChatsInfo = app.settings.getChatsShareInfo() val shareInfo = shareChatsInfo[chatId] - val chatsCounts = shareChatsInfo.size - val currentTime = System.currentTimeMillis() - if (shareInfo != null && currentTime - lastLocationSentTime > chatsCounts * SENT_LOCATIONS_INTERVAL_TIME_MS) { + if (shareInfo != null) { + val currentTime = System.currentTimeMillis() + if (currentTime - shareInfo.lastBufferCheckTime < MIN_MESSAGES_BUFFER_CHECK_INTERVAL_MS && !forced) { + return app.locationMessages.getBufferedMessagesCountForChat(chatId) + } + shareInfo.lastBufferCheckTime = currentTime + app.locationMessages.getBufferedTextMessagesForChat(chatId).take(MAX_MESSAGES_IN_TDLIB_PER_CHAT).forEach { - if (shareInfo.pendingTdLibText < MAX_MESSAGES_IN_TDLIB_PER_CHAT) { + if (!shareInfo.isPendingTextMessagesLimitReached()) { if (it.deviceName.isEmpty()) { if (!shareInfo.pendingTextMessage && shareInfo.currentTextMessageId != -1L) { - lastLocationSentTime = System.currentTimeMillis() val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, it, app) app.telegramHelper.editTextLocation(shareInfo, content) app.locationMessages.removeBufferedMessage(it) @@ -154,10 +158,9 @@ class ShareLocationHelper(private val app: TelegramApplication) { } } app.locationMessages.getBufferedMapMessagesForChat(chatId).take(MAX_MESSAGES_IN_TDLIB_PER_CHAT).forEach { - if (shareInfo.pendingTdLibMap < MAX_MESSAGES_IN_TDLIB_PER_CHAT) { + if (!shareInfo.isPendingMapMessagesLimitReached()) { if (it.deviceName.isEmpty()) { if (!shareInfo.pendingMapMessage && shareInfo.currentMapMessageId != -1L) { - lastLocationSentTime = System.currentTimeMillis() app.telegramHelper.editMapLocation(shareInfo, it) app.locationMessages.removeBufferedMessage(it) } @@ -166,7 +169,9 @@ class ShareLocationHelper(private val app: TelegramApplication) { } } } + return app.locationMessages.getBufferedMessagesCountForChat(chatId) } + return 0 } fun startSharingLocation() { @@ -219,44 +224,44 @@ class ShareLocationHelper(private val app: TelegramApplication) { val time = location.time val isBot = app.settings.currentSharingMode != userId.toString() val deviceName = if (isBot) app.settings.currentSharingMode else "" - var bufferedMessagesFull = false - val chatsCounts = chatsShareInfo.size + var pendingMessagesLimitReached = false val currentTime = System.currentTimeMillis() app.locationMessages.addMyLocationMessage(location) - if (currentTime - lastLocationSentTime <= chatsCounts * SENT_LOCATIONS_INTERVAL_TIME_MS) { + if (currentTime - lastShareLocationMessageTime < MIN_MESSAGE_SENDING_INTERVAL_MS) { return } + lastShareLocationMessageTime = currentTime chatsShareInfo.values.forEach { shareInfo -> - if (shareInfo.pendingTdLibText >= MAX_MESSAGES_IN_TDLIB_PER_CHAT || shareInfo.pendingTdLibMap >= MAX_MESSAGES_IN_TDLIB_PER_CHAT) { - bufferedMessagesFull = true + val hasBufferedMessages = checkAndSendBufferMessagesToChat(shareInfo.chatId) > 0 + if (shareInfo.isPendingMessagesLimitReached()) { + pendingMessagesLimitReached = true } - checkAndSendBufferMessagesToChat(shareInfo.chatId) when (app.settings.shareTypeValue) { SHARE_TYPE_MAP -> { val message = BufferMessage(shareInfo.chatId, latitude, longitude, altitude, speed, accuracy, bearing, time, LocationMessages.TYPE_MAP, deviceName) - prepareMapMessage(shareInfo, message, isBot) + prepareMapMessage(shareInfo, message, isBot, hasBufferedMessages) } SHARE_TYPE_TEXT -> { val message = BufferMessage(shareInfo.chatId, latitude, longitude, altitude, speed, accuracy, bearing, time, LocationMessages.TYPE_TEXT, deviceName) - prepareTextMessage(shareInfo, message, isBot) + prepareTextMessage(shareInfo, message, isBot, hasBufferedMessages) } SHARE_TYPE_MAP_AND_TEXT -> { val messageMap = BufferMessage(shareInfo.chatId, latitude, longitude, altitude, speed, accuracy, bearing, time, LocationMessages.TYPE_MAP, deviceName) val messageText = BufferMessage(shareInfo.chatId, latitude, longitude, altitude, speed, accuracy, bearing, time, LocationMessages.TYPE_TEXT, deviceName) - prepareMapMessage(shareInfo, messageMap, isBot) - prepareTextMessage(shareInfo, messageText, isBot) + prepareMapMessage(shareInfo, messageMap, isBot, hasBufferedMessages) + prepareTextMessage(shareInfo, messageText, isBot, hasBufferedMessages) } } } - if (bufferedMessagesFull) { + if (pendingMessagesLimitReached) { checkNetworkType() } } - private fun prepareTextMessage(shareInfo: TelegramSettings.ShareChatInfo, message: BufferMessage, isBot: Boolean) { + private fun prepareTextMessage(shareInfo: TelegramSettings.ShareChatInfo, message: BufferMessage, isBot: Boolean, hasBufferedMessages: Boolean) { log.debug("prepareTextMessage $message") if (shareInfo.currentTextMessageId == -1L) { if (shareInfo.pendingTextMessage) { @@ -265,7 +270,6 @@ class ShareLocationHelper(private val app: TelegramApplication) { if (isBot) { sendLocationToBot(message, shareInfo, SHARE_TYPE_TEXT) } else { - lastLocationSentTime = System.currentTimeMillis() val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, message, app) app.telegramHelper.sendNewTextLocation(shareInfo, content) } @@ -278,8 +282,7 @@ class ShareLocationHelper(private val app: TelegramApplication) { app.locationMessages.addBufferedMessage(message) } } else { - if (shareInfo.pendingTdLibText < MAX_MESSAGES_IN_TDLIB_PER_CHAT) { - lastLocationSentTime = System.currentTimeMillis() + if (!shareInfo.isPendingTextMessagesLimitReached() && !hasBufferedMessages) { val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, message, app) app.telegramHelper.editTextLocation(shareInfo, content) } else { @@ -289,7 +292,7 @@ class ShareLocationHelper(private val app: TelegramApplication) { } } - private fun prepareMapMessage(shareInfo: TelegramSettings.ShareChatInfo, message: BufferMessage, isBot: Boolean) { + private fun prepareMapMessage(shareInfo: TelegramSettings.ShareChatInfo, message: BufferMessage, isBot: Boolean, hasBufferedMessages: Boolean) { log.debug("prepareMapMessage $message") if (shareInfo.currentMapMessageId == -1L) { if (shareInfo.pendingMapMessage) { @@ -302,7 +305,6 @@ class ShareLocationHelper(private val app: TelegramApplication) { app.locationMessages.addBufferedMessage(message) } } else { - lastLocationSentTime = System.currentTimeMillis() app.telegramHelper.sendNewMapLocation(shareInfo, message) } } @@ -314,8 +316,7 @@ class ShareLocationHelper(private val app: TelegramApplication) { app.locationMessages.addBufferedMessage(message) } } else { - if (shareInfo.pendingTdLibMap < MAX_MESSAGES_IN_TDLIB_PER_CHAT) { - lastLocationSentTime = System.currentTimeMillis() + if (!shareInfo.isPendingMapMessagesLimitReached() && !hasBufferedMessages) { app.telegramHelper.editMapLocation(shareInfo, message) } else { app.locationMessages.addBufferedMessage(message) @@ -344,7 +345,6 @@ class ShareLocationHelper(private val app: TelegramApplication) { } else if (shareType == SHARE_TYPE_MAP) { shareInfo.lastSendMapMessageTime = (System.currentTimeMillis() / 1000).toInt() } - lastLocationSentTime = System.currentTimeMillis() AndroidNetworkUtils.sendRequestAsync(app, url, null, "Send Location", false, false, object : AndroidNetworkUtils.OnRequestResultListener { override fun onResult(result: String?) { @@ -408,7 +408,7 @@ class ShareLocationHelper(private val app: TelegramApplication) { companion object { - const val MAX_MESSAGES_IN_TDLIB_PER_CHAT = 10 + const val MAX_MESSAGES_IN_TDLIB_PER_CHAT = 5 // min and max values for the UI const val MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC = TelegramHelper.MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC - 1