Merge pull request #1012 from session-foundation/merge-1.21.0

Merge 1.21.0 to dev
pull/1710/head
SessionHero01 4 weeks ago committed by GitHub
commit 0445ebeb57
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -15,7 +15,7 @@ configurations.configureEach {
exclude module: "commons-logging"
}
def canonicalVersionCode = 395
def canonicalVersionCode = 396
def canonicalVersionName = "1.21.0"
def postFixSize = 10

@ -44,7 +44,7 @@ import org.session.libsignal.utilities.Log
import org.session.libsignal.utilities.Namespace
import org.session.libsignal.utilities.Snode
import org.session.libsignal.utilities.retryWithUniformInterval
import org.thoughtcrime.securesms.util.InternetConnectivity
import org.thoughtcrime.securesms.util.NetworkConnectivity
import javax.inject.Inject
private const val TAG = "ConfigUploader"
@ -64,7 +64,7 @@ class ConfigUploader @Inject constructor(
private val configFactory: ConfigFactoryProtocol,
private val storageProtocol: StorageProtocol,
private val clock: SnodeClock,
private val internetConnectivity: InternetConnectivity,
private val networkConnectivity: NetworkConnectivity,
private val textSecurePreferences: TextSecurePreferences,
) {
private var job: Job? = null
@ -77,7 +77,7 @@ class ConfigUploader @Inject constructor(
* The value pushed doesn't matter as nothing is emitted when the conditions are not met.
*/
@OptIn(ExperimentalCoroutinesApi::class)
private fun pathBecomesAvailable(): Flow<*> = internetConnectivity.networkAvailable
private fun pathBecomesAvailable(): Flow<*> = networkConnectivity.networkAvailable
.flatMapLatest { hasNetwork ->
if (hasNetwork) {
OnionRequestAPI.hasPath.filter { it }

@ -1,6 +1,5 @@
package org.thoughtcrime.securesms.groups
import dagger.Lazy
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
@ -12,6 +11,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
@ -24,8 +24,6 @@ import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.scan
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.supervisorScope
import org.session.libsession.database.StorageProtocol
import org.session.libsession.messaging.groups.GroupManagerV2
import org.session.libsession.snode.SnodeClock
import org.session.libsession.utilities.ConfigUpdateNotification
import org.session.libsession.utilities.TextSecurePreferences
@ -34,7 +32,7 @@ import org.session.libsignal.utilities.AccountId
import org.session.libsignal.utilities.Log
import org.thoughtcrime.securesms.dependencies.ConfigFactory
import org.thoughtcrime.securesms.util.AppVisibilityManager
import org.thoughtcrime.securesms.util.InternetConnectivity
import org.thoughtcrime.securesms.util.NetworkConnectivity
import javax.inject.Inject
import javax.inject.Singleton
@ -58,15 +56,18 @@ class GroupPollerManager @Inject constructor(
clock: SnodeClock,
preferences: TextSecurePreferences,
appVisibilityManager: AppVisibilityManager,
connectivity: InternetConnectivity,
connectivity: NetworkConnectivity,
groupRevokedMessageHandler: GroupRevokedMessageHandler,
) {
@Suppress("OPT_IN_USAGE")
private val groupPollers: StateFlow<Map<AccountId, GroupPollerHandle>> =
combine(
connectivity.networkAvailable,
connectivity.networkAvailable.debounce(200L),
preferences.watchLocalNumber()
) { networkAvailable, localNumber -> networkAvailable && localNumber != null }
) { networkAvailable, localNumber ->
Log.v(TAG, "Network available: $networkAvailable, hasLocalNumber: ${localNumber != null}")
networkAvailable && localNumber != null
}
// This flatMap produces a flow of groups that should be polled now
.flatMapLatest { shouldPoll ->
if (shouldPoll) {

@ -129,25 +129,37 @@ class LogFile {
String readEntry() throws IOException {
try {
// Read the IV and length
Util.readFully(inputStream, ivBuffer);
Util.readFully(inputStream, intBuffer);
} catch (EOFException e) {
// End of file reached before a full header could be read.
return null;
}
int length = Conversions.byteArrayToInt(intBuffer);
byte[] ciphertext = ciphertextBuffer.get(length);
int length = Conversions.byteArrayToInt(intBuffer);
byte[] ciphertext = ciphertextBuffer.get(length);
try {
Util.readFully(inputStream, ciphertext, length);
} catch (EOFException e) {
// Incomplete ciphertext likely due to a partially written record.
return null;
}
try {
synchronized (CIPHER_LOCK) {
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(secret, "AES"), new IvParameterSpec(ivBuffer));
byte[] plaintext = cipher.doFinal(ciphertext, 0, length);
return new String(plaintext);
}
} catch (InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) {
throw new AssertionError(e);
try {
synchronized (CIPHER_LOCK) {
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(secret, "AES"), new IvParameterSpec(ivBuffer));
byte[] plaintext = cipher.doFinal(ciphertext, 0, length);
return new String(plaintext);
}
} catch (EOFException e) {
} catch (BadPaddingException e) {
// Bad padding likely indicates a corrupted or incomplete entry.
// Instead of throwing an error, treat this as the end of the log.
return null;
} catch (InvalidKeyException | InvalidAlgorithmParameterException
| IllegalBlockSizeException e) {
throw new AssertionError(e);
}
}
}

@ -1,6 +1,7 @@
package org.thoughtcrime.securesms.preferences
import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.graphics.BitmapFactory

@ -36,7 +36,7 @@ import org.thoughtcrime.securesms.preferences.SettingsViewModel.AvatarDialogStat
import org.thoughtcrime.securesms.profiles.ProfileMediaConstraints
import org.thoughtcrime.securesms.util.BitmapDecodingException
import org.thoughtcrime.securesms.util.BitmapUtil
import org.thoughtcrime.securesms.util.InternetConnectivity
import org.thoughtcrime.securesms.util.NetworkConnectivity
import java.io.File
import java.io.IOException
import javax.inject.Inject
@ -46,7 +46,7 @@ class SettingsViewModel @Inject constructor(
@ApplicationContext private val context: Context,
private val prefs: TextSecurePreferences,
private val configFactory: ConfigFactory,
private val connectivity: InternetConnectivity,
private val connectivity: NetworkConnectivity,
private val usernameUtils: UsernameUtils
) : ViewModel() {
private val TAG = "SettingsViewModel"

@ -6,49 +6,41 @@ import android.content.Context.CONNECTIVITY_SERVICE
import android.net.ConnectivityManager
import android.net.ConnectivityManager.NetworkCallback
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.flow.stateIn
import org.session.libsignal.utilities.Log
import javax.inject.Inject
import javax.inject.Singleton
/**
* Provides a flow that emits `true` when the device has internet connectivity and `false` otherwise.
* Provides a flow that emits `true` when the device has network connectivity. We won't be sure
* if there's internet or not, it's by designed so that we don't get false negatives in censorship
* countries.
*/
@Singleton
class InternetConnectivity @Inject constructor(application: Application) {
class NetworkConnectivity @Inject constructor(application: Application) {
val networkAvailable = callbackFlow {
val connectivityManager = application.getSystemService(ConnectivityManager::class.java)
val callback = object : NetworkCallback() {
override fun onCapabilitiesChanged(
network: Network,
networkCapabilities: NetworkCapabilities
) {
trySend(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET))
}
override fun onAvailable(network: Network) {
super.onAvailable(network)
Log.v("NetworkConnectivity", "Network become available")
trySend(true)
}
override fun onLost(network: Network) {
super.onLost(network)
Log.v("NetworkConnectivity", "Network become lost")
trySend(false)
}
}
connectivityManager.registerNetworkCallback(
NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build(),
callback
)
connectivityManager.registerDefaultNetworkCallback(callback)
awaitClose {
connectivityManager.unregisterNetworkCallback(callback)
@ -65,15 +57,7 @@ class InternetConnectivity @Inject constructor(application: Application) {
private fun haveValidNetworkConnection(context: Context): Boolean {
val cm = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
// Early exit if we have no active network..
val activeNetwork = cm.activeNetwork ?: return false
// ..otherwise determine what capabilities are available to the active network.
val networkCapabilities = cm.getNetworkCapabilities(activeNetwork)
val internetConnectionValid = networkCapabilities != null &&
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
return internetConnectionValid
return cm.activeNetwork != null
}
}

@ -11,7 +11,6 @@ import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat
import androidx.core.content.IntentCompat
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.GlobalScope
@ -27,7 +26,7 @@ import org.session.libsession.utilities.recipients.Recipient
import org.session.libsignal.utilities.Log
import org.thoughtcrime.securesms.notifications.BackgroundPollWorker
import org.thoughtcrime.securesms.service.CallForegroundService
import org.thoughtcrime.securesms.util.InternetConnectivity
import org.thoughtcrime.securesms.util.NetworkConnectivity
import org.thoughtcrime.securesms.webrtc.CallNotificationBuilder.Companion.TYPE_ESTABLISHED
import org.thoughtcrime.securesms.webrtc.CallNotificationBuilder.Companion.TYPE_INCOMING_CONNECTING
import org.thoughtcrime.securesms.webrtc.CallNotificationBuilder.Companion.TYPE_INCOMING_PRE_OFFER
@ -64,7 +63,7 @@ import org.thoughtcrime.securesms.webrtc.data.State as CallState
class WebRtcCallBridge @Inject constructor(
@ApplicationContext private val context: Context,
private val callManager: CallManager,
private val internetConnectivity: InternetConnectivity
private val networkConnectivity: NetworkConnectivity
): CallManager.WebRtcListener {
companion object {
@ -105,7 +104,7 @@ class WebRtcCallBridge @Inject constructor(
registerWiredHeadsetStateReceiver()
GlobalScope.launch {
internetConnectivity.networkAvailable.collectLatest(::networkChange)
networkConnectivity.networkAvailable.collectLatest(::networkChange)
}
}

@ -24,7 +24,7 @@ class LegacyGroupDeprecationManager(private val prefs: TextSecurePreferences) {
// The time all legacy groups will cease working. This value can be overridden by a debug
// facility.
private val defaultDeprecatedTime = ZonedDateTime.of(2025, 7, 1, 0, 0, 0, 0, ZoneId.of("UTC"))
private val defaultDeprecatedTime = ZonedDateTime.of(2025, 4, 2, 22, 0, 0, 0, ZoneId.of("UTC"))
private val mutableDeprecatedTime = MutableStateFlow<ZonedDateTime>(
prefs.deprecatedTimeOverride ?: defaultDeprecatedTime
@ -33,7 +33,7 @@ class LegacyGroupDeprecationManager(private val prefs: TextSecurePreferences) {
val deprecatedTime: StateFlow<ZonedDateTime> get() = mutableDeprecatedTime
// The time a warning will be shown to users that legacy groups are being deprecated.
private val defaultDeprecatingStartTime = ZonedDateTime.of(2025, 2, 24, 0, 0, 0, 0, ZoneId.of("UTC"))
private val defaultDeprecatingStartTime = ZonedDateTime.of(2025, 3, 19, 22, 0, 0, 0, ZoneId.of("UTC"))
private val mutableDeprecatingStartTime: MutableStateFlow<ZonedDateTime> = MutableStateFlow(
prefs.deprecatingStartTimeOverride ?: defaultDeprecatingStartTime

Loading…
Cancel
Save