Update to and integrate with libsignal v0.69.0.

This commit is contained in:
andrew-signal
2025-04-03 09:38:36 -04:00
committed by Michelle Tang
parent 7a5790a6ce
commit 5b04107447
7 changed files with 35 additions and 28 deletions

View File

@@ -97,8 +97,7 @@ object ContactDiscoveryRefreshV2 {
serviceIds = SignalDatabase.recipients.getAllServiceIdProfileKeyPairs(),
token = Optional.empty(),
timeoutMs = 10_000,
libsignalNetwork = AppDependencies.libsignalNetwork,
useLibsignalRouteBasedCDSIConnectionLogic = RemoteConfig.libsignalRouteBasedCDSILookup
libsignalNetwork = AppDependencies.libsignalNetwork
) {
Log.i(TAG, "Ignoring token for one-off lookup.")
}
@@ -176,8 +175,7 @@ object ContactDiscoveryRefreshV2 {
serviceIds = SignalDatabase.recipients.getAllServiceIdProfileKeyPairs(),
token = Optional.ofNullable(token),
timeoutMs = timeoutMs,
libsignalNetwork = AppDependencies.libsignalNetwork,
useLibsignalRouteBasedCDSIConnectionLogic = RemoteConfig.libsignalRouteBasedCDSILookup
libsignalNetwork = AppDependencies.libsignalNetwork
) { tokenToSave ->
stopwatch.split("network-pre-token")
if (!isPartialRefresh) {

View File

@@ -1109,13 +1109,6 @@ object RemoteConfig {
hotSwappable = false
)
/** Whether or not libsignal-net's CDSI lookups use the new route-based internals or the old ones */
val libsignalRouteBasedCDSILookup: Boolean by remoteBoolean(
key = "android.libsignal.libsignalRouteBasedCDSILookup",
defaultValue = true,
hotSwappable = true
)
/** Whether to allow different WindowSizeClasses to be used to determine screen layout */
val largeScreenUi: Boolean by remoteBoolean(
key = "android.largeScreenUI",

View File

@@ -13,7 +13,7 @@ androidx-window = "1.3.0"
glide = "4.15.1"
gradle = "8.9.0"
kotlin = "2.1.0"
libsignal-client = "0.68.1"
libsignal-client = "0.69.0"
mp4parser = "1.9.39"
android-gradle-plugin = "8.7.2"
accompanist = "0.28.0"

View File

@@ -7172,20 +7172,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
<sha256 value="6eb4422e8a618b3b76cb2096a3619d251f9e27989dc68307a1e5414c3710f2d1" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.signal" name="libsignal-android" version="0.68.1">
<artifact name="libsignal-android-0.68.1.aar">
<sha256 value="2cefc931a4ba19216b7f7b01cbac158fbcc8e16a3d2d8af5456dc3a3776f3e5f" origin="Generated by Gradle"/>
<component group="org.signal" name="libsignal-android" version="0.69.0">
<artifact name="libsignal-android-0.69.0.aar">
<sha256 value="a379de8431768f19aa98c2ecdba39ccaaf5a5f7480dd0a83767a65538bb8c068" origin="Generated by Gradle"/>
</artifact>
<artifact name="libsignal-android-0.68.1.module">
<sha256 value="0d3e2297f5b8d8de62b8366333a5468fc9fefec75d5bed32b88334f6eb70820b" origin="Generated by Gradle"/>
<artifact name="libsignal-android-0.69.0.module">
<sha256 value="2cbdb6c27d9348e4826850d51b0265de9da0c9d3143a5cf63b312e3570653a97" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.signal" name="libsignal-client" version="0.68.1">
<artifact name="libsignal-client-0.68.1.jar">
<sha256 value="ff70943e4f671401a5d4cfab7f95d128b0b0a4cd452da418c32233258981ec64" origin="Generated by Gradle"/>
<component group="org.signal" name="libsignal-client" version="0.69.0">
<artifact name="libsignal-client-0.69.0.jar">
<sha256 value="79e650d1765deb048be6ecef0243fc2689d66c187f23204be1bf396b25ada84b" origin="Generated by Gradle"/>
</artifact>
<artifact name="libsignal-client-0.68.1.module">
<sha256 value="10d59d34e9c1ec42aaf1b40023f167ba725519c23b9cc433f94fc781a3141841" origin="Generated by Gradle"/>
<artifact name="libsignal-client-0.69.0.module">
<sha256 value="197eb504d6815c9d28621b717a48e055b41d23f51428db7fe0a503fe6b3d1cd4" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.signal" name="ringrtc-android" version="2.50.3">

View File

@@ -51,14 +51,13 @@ class CdsApi(private val authWebSocket: SignalWebSocket.AuthenticatedWebSocket)
token: Optional<ByteArray>,
timeoutMs: Long?,
libsignalNetwork: Network,
useLibsignalRouteBasedCDSIConnectionLogic: Boolean,
tokenSaver: Consumer<ByteArray>
): NetworkResult<CdsiV2Service.Response> {
val authRequest = WebSocketRequestMessage.get("/v2/directory/auth")
return NetworkResult.fromWebSocketRequest(authWebSocket, authRequest, CdsiAuthResponse::class)
.then { auth ->
val service = CdsiV2Service(libsignalNetwork, useLibsignalRouteBasedCDSIConnectionLogic)
val service = CdsiV2Service(libsignalNetwork)
val request = CdsiV2Service.Request(previousE164s, newE164s, serviceIds, token)
val single = service.getRegisteredUsers(auth.username, auth.password, request, tokenSaver)

View File

@@ -41,10 +41,10 @@ public final class CdsiV2Service {
private final CdsiRequestHandler cdsiRequestHandler;
public CdsiV2Service(@Nonnull Network network, boolean useLibsignalRouteBasedCDSIConnectionLogic) {
public CdsiV2Service(@Nonnull Network network) {
this.cdsiRequestHandler = (username, password, request, tokenSaver) -> {
try {
Future<CdsiLookupResponse> cdsiRequest = network.cdsiLookup(username, password, buildLibsignalRequest(request), tokenSaver, useLibsignalRouteBasedCDSIConnectionLogic);
Future<CdsiLookupResponse> cdsiRequest = network.cdsiLookup(username, password, buildLibsignalRequest(request), tokenSaver);
return Single.fromFuture(cdsiRequest)
.onErrorResumeNext((Throwable err) -> {
if (err instanceof ExecutionException && err.getCause() != null) {

View File

@@ -30,6 +30,7 @@ import org.whispersystems.signalservice.internal.util.whenComplete
import java.io.IOException
import java.net.SocketException
import java.time.Instant
import java.util.Collections
import java.util.Optional
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.Executors
@@ -63,6 +64,7 @@ class LibSignalChatConnection(
private val healthMonitor: HealthMonitor
) : WebSocketConnection {
private val incomingRequestQueue = LinkedBlockingQueue<WebSocketRequestMessage>()
private val pendingResponses = Collections.synchronizedSet(HashSet<SingleSubject<WebsocketResponse>>())
// One of the more nasty parts of this is that libsignal-net does not expose, nor does it ever
// intend to expose, the ID of the incoming "request" to the app layer. Instead, the app layer
@@ -148,6 +150,7 @@ class LibSignalChatConnection(
// there is no ackSender for a pseudoId gracefully in sendResponse.
ackSenderForInternalPseudoId.clear()
// There's no sense in resetting nextIncomingMessageInternalPseudoId.
pendingResponses.clear()
}
init {
@@ -297,8 +300,14 @@ class LibSignalChatConnection(
// fires after the one enqueued in connect().
sendRequest(request)
.subscribe(
{ response -> single.onSuccess(response) },
{ error -> single.onError(error) }
{ response ->
pendingResponses.remove(single)
single.onSuccess(response)
},
{ error ->
pendingResponses.remove(single)
single.onError(error)
}
)
},
onFailure = { throwable ->
@@ -308,9 +317,11 @@ class LibSignalChatConnection(
is DeviceDeregisteredException -> NonSuccessfulResponseCodeException(403)
else -> SocketException("Closed unexpectedly")
}
pendingResponses.remove(single)
single.onError(downstreamThrowable)
}
)
pendingResponses.add(single)
return single.subscribeOn(Schedulers.io()).observeOn(Schedulers.io())
}
@@ -329,6 +340,7 @@ class LibSignalChatConnection(
}
// Here success means "we received the response" even if it is reporting an error.
// This is consistent with the behavior of the OkHttpWebSocketConnection.
pendingResponses.remove(single)
single.onSuccess(response.toWebsocketResponse(isUnidentified = (chatConnection is UnauthenticatedChatConnection)))
},
onFailure = { throwable ->
@@ -336,9 +348,11 @@ class LibSignalChatConnection(
// The clients of WebSocketConnection are often sensitive to the exact type of exception returned.
// This is the exception that OkHttpWebSocketConnection throws in the closest scenario to this, when
// the connection fails before the request completes.
pendingResponses.remove(single)
single.onError(SocketException("Failed to get response for request"))
}
)
pendingResponses.add(single)
return single.subscribeOn(Schedulers.io()).observeOn(Schedulers.io())
}
}
@@ -531,6 +545,9 @@ class LibSignalChatConnection(
Log.i(TAG, "$name disconnected")
} else {
Log.i(TAG, "$name connection unexpectedly closed", disconnectReason)
for (pendingResponse in pendingResponses) {
pendingResponse.onError(disconnectReason)
}
}
chatConnection = null
state.onNext(WebSocketConnectionState.DISCONNECTED)