diff --git a/graalvm-config-dir/jni-config.json b/graalvm-config-dir/jni-config.json index 523a6c03..bf24fb8a 100644 --- a/graalvm-config-dir/jni-config.json +++ b/graalvm-config-dir/jni-config.json @@ -2,6 +2,9 @@ { "name":"[B" }, +{ + "name":"[Ljava.lang.String;" +}, { "name":"[Z" }, @@ -76,12 +79,18 @@ "name":"java.util.UUID", "methods":[{"name":"","parameterTypes":["long","long"] }, {"name":"getLeastSignificantBits","parameterTypes":[] }, {"name":"getMostSignificantBits","parameterTypes":[] }] }, +{ + "name":"java.util.concurrent.ForkJoinWorkerThread" +}, { "name":"jdk.internal.loader.ClassLoaders$AppClassLoader" }, { "name":"jdk.internal.loader.ClassLoaders$PlatformClassLoader" }, +{ + "name":"org.asamk.signal.manager.internal.SignalWebSocketHealthMonitor$KeepAliveSender" +}, { "name":"org.asamk.signal.manager.storage.protocol.SignalProtocolStore", "methods":[{"name":"getIdentity","parameterTypes":["org.signal.libsignal.protocol.SignalProtocolAddress"] }, {"name":"getIdentityKeyPair","parameterTypes":[] }, {"name":"getLocalRegistrationId","parameterTypes":[] }, {"name":"isTrustedIdentity","parameterTypes":["org.signal.libsignal.protocol.SignalProtocolAddress","org.signal.libsignal.protocol.IdentityKey","org.signal.libsignal.protocol.state.IdentityKeyStore$Direction"] }, {"name":"loadKyberPreKey","parameterTypes":["int"] }, {"name":"loadPreKey","parameterTypes":["int"] }, {"name":"loadSenderKey","parameterTypes":["org.signal.libsignal.protocol.SignalProtocolAddress","java.util.UUID"] }, {"name":"loadSession","parameterTypes":["org.signal.libsignal.protocol.SignalProtocolAddress"] }, {"name":"loadSignedPreKey","parameterTypes":["int"] }, {"name":"markKyberPreKeyUsed","parameterTypes":["int"] }, {"name":"removePreKey","parameterTypes":["int"] }, {"name":"saveIdentity","parameterTypes":["org.signal.libsignal.protocol.SignalProtocolAddress","org.signal.libsignal.protocol.IdentityKey"] }, {"name":"storeSenderKey","parameterTypes":["org.signal.libsignal.protocol.SignalProtocolAddress","java.util.UUID","org.signal.libsignal.protocol.groups.state.SenderKeyRecord"] }, {"name":"storeSession","parameterTypes":["org.signal.libsignal.protocol.SignalProtocolAddress","org.signal.libsignal.protocol.state.SessionRecord"] }] @@ -110,6 +119,14 @@ "name":"org.signal.libsignal.net.CdsiLookupResponse$Entry", "methods":[{"name":"","parameterTypes":["byte[]","byte[]"] }] }, +{ + "name":"org.signal.libsignal.net.ChatConnection$ListenerBridge", + "methods":[{"name":"onConnectionInterrupted","parameterTypes":["java.lang.Throwable"] }, {"name":"onIncomingMessage","parameterTypes":["byte[]","long","long"] }, {"name":"onQueueEmpty","parameterTypes":[] }, {"name":"onReceivedAlerts","parameterTypes":["java.lang.String[]"] }] +}, +{ + "name":"org.signal.libsignal.net.ChatConnection$Response", + "methods":[{"name":"","parameterTypes":["int","java.lang.String","java.util.Map","byte[]"] }] +}, { "name":"org.signal.libsignal.net.ChatService" }, @@ -130,6 +147,9 @@ "name":"org.signal.libsignal.net.RetryLaterException", "methods":[{"name":"","parameterTypes":["long"] }] }, +{ + "name":"org.signal.libsignal.net.internal.BridgeChatListener" +}, { "name":"org.signal.libsignal.protocol.DuplicateMessageException", "methods":[{"name":"","parameterTypes":["java.lang.String"] }] @@ -308,5 +328,8 @@ "name":"org.sqlite.core.NativeDB", "fields":[{"name":"busyHandler"}, {"name":"commitListener"}, {"name":"pointer"}, {"name":"progressHandler"}, {"name":"updateListener"}], "methods":[{"name":"stringToUtf8ByteArray","parameterTypes":["java.lang.String"] }, {"name":"throwex","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"org.whispersystems.signalservice.api.websocket.SignalWebSocket$DelayedDisconnectThread" } ] diff --git a/graalvm-config-dir/reflect-config.json b/graalvm-config-dir/reflect-config.json index 187cab9d..8baabd33 100644 --- a/graalvm-config-dir/reflect-config.json +++ b/graalvm-config-dir/reflect-config.json @@ -660,6 +660,46 @@ "name":"kotlin.reflect.jvm.internal.impl.resolve.scopes.DescriptorKindFilter", "allPublicFields":true }, +{ + "name":"kotlinx.coroutines.CancellableContinuationImpl", + "fields":[{"name":"_decisionAndIndex$volatile"}, {"name":"_parentHandle$volatile"}, {"name":"_state$volatile"}] +}, +{ + "name":"kotlinx.coroutines.CompletedExceptionally", + "fields":[{"name":"_handled$volatile"}] +}, +{ + "name":"kotlinx.coroutines.EventLoopImplBase", + "fields":[{"name":"_delayed$volatile"}, {"name":"_isCompleted$volatile"}, {"name":"_queue$volatile"}] +}, +{ + "name":"kotlinx.coroutines.JobSupport", + "fields":[{"name":"_parentHandle$volatile"}, {"name":"_state$volatile"}] +}, +{ + "name":"kotlinx.coroutines.JobSupport$Finishing", + "fields":[{"name":"_exceptionsHolder$volatile"}, {"name":"_isCompleting$volatile"}, {"name":"_rootCause$volatile"}] +}, +{ + "name":"kotlinx.coroutines.internal.DispatchedContinuation", + "fields":[{"name":"_reusableCancellableContinuation$volatile"}] +}, +{ + "name":"kotlinx.coroutines.internal.LockFreeLinkedListNode", + "fields":[{"name":"_next$volatile"}, {"name":"_prev$volatile"}, {"name":"_removedRef$volatile"}] +}, +{ + "name":"kotlinx.coroutines.internal.LockFreeTaskQueue", + "fields":[{"name":"_cur$volatile"}] +}, +{ + "name":"kotlinx.coroutines.internal.LockFreeTaskQueueCore", + "fields":[{"name":"_next$volatile"}, {"name":"_state$volatile"}] +}, +{ + "name":"kotlinx.coroutines.scheduling.CoroutineScheduler", + "fields":[{"name":"_isTerminated$volatile"}, {"name":"controlState$volatile"}, {"name":"parkedWorkersStack$volatile"}] +}, { "name":"libcore.io.Memory" }, @@ -3002,7 +3042,6 @@ { "name":"org.whispersystems.signalservice.internal.storage.protos.AccountRecord", "allDeclaredFields":true, - "fields":[{"name":"avatarColor"}, {"name":"avatarUrlPath"}, {"name":"backupSubscriberData"}, {"name":"backupTier"}, {"name":"backupTierHistory"}, {"name":"displayBadgesOnProfile"}, {"name":"familyName"}, {"name":"givenName"}, {"name":"hasBackup"}, {"name":"hasCompletedUsernameOnboarding"}, {"name":"hasSeenGroupStoryEducationSheet"}, {"name":"hasSetMyStoriesPrivacy"}, {"name":"hasViewedOnboardingStory"}, {"name":"keepMutedChatsArchived"}, {"name":"linkPreviews"}, {"name":"noteToSelfArchived"}, {"name":"noteToSelfMarkedUnread"}, {"name":"notificationProfileManualOverride"}, {"name":"payments"}, {"name":"phoneNumberSharingMode"}, {"name":"pinnedConversations"}, {"name":"preferContactAvatars"}, {"name":"preferredReactionEmoji"}, {"name":"primarySendsSms"}, {"name":"profileKey"}, {"name":"readReceipts"}, {"name":"sealedSenderIndicators"}, {"name":"storiesDisabled"}, {"name":"storyViewReceiptsEnabled"}, {"name":"subscriberCurrencyCode"}, {"name":"subscriberId"}, {"name":"subscriptionManuallyCancelled"}, {"name":"typingIndicators"}, {"name":"universalExpireTimer"}, {"name":"unlistedPhoneNumber"}, {"name":"username"}, {"name":"usernameLink"}], "methods":[{"name":"adapter","parameterTypes":[] }, {"name":"unknownFields","parameterTypes":[] }] }, { @@ -3041,7 +3080,6 @@ { "name":"org.whispersystems.signalservice.internal.storage.protos.ContactRecord", "allDeclaredFields":true, - "fields":[{"name":"aci"}, {"name":"archived"}, {"name":"avatarColor"}, {"name":"blocked"}, {"name":"e164"}, {"name":"familyName"}, {"name":"givenName"}, {"name":"hidden"}, {"name":"hideStory"}, {"name":"identityKey"}, {"name":"identityState"}, {"name":"markedUnread"}, {"name":"mutedUntilTimestamp"}, {"name":"nickname"}, {"name":"note"}, {"name":"pni"}, {"name":"pniSignatureVerified"}, {"name":"profileKey"}, {"name":"systemFamilyName"}, {"name":"systemGivenName"}, {"name":"systemNickname"}, {"name":"unregisteredAtTimestamp"}, {"name":"username"}, {"name":"whitelisted"}], "methods":[{"name":"adapter","parameterTypes":[] }, {"name":"unknownFields","parameterTypes":[] }] }, { @@ -3072,7 +3110,6 @@ { "name":"org.whispersystems.signalservice.internal.storage.protos.GroupV2Record", "allDeclaredFields":true, - "fields":[{"name":"archived"}, {"name":"avatarColor"}, {"name":"blocked"}, {"name":"dontNotifyForMentionsIfMuted"}, {"name":"hideStory"}, {"name":"markedUnread"}, {"name":"masterKey"}, {"name":"mutedUntilTimestamp"}, {"name":"storySendMode"}, {"name":"whitelisted"}], "methods":[{"name":"adapter","parameterTypes":[] }, {"name":"unknownFields","parameterTypes":[] }] }, { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9b38c6e1..ba570c12 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -10,7 +10,7 @@ slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" } slf4j-jul = { module = "org.slf4j:jul-to-slf4j", version.ref = "slf4j" } logback = "ch.qos.logback:logback-classic:1.5.18" -signalservice = "com.github.turasa:signal-service-java:2.15.3_unofficial_128" +signalservice = "com.github.turasa:signal-service-java:2.15.3_unofficial_129" sqlite = "org.xerial:sqlite-jdbc:3.50.3.0" hikari = "com.zaxxer:HikariCP:7.0.2" junit-jupiter = "org.junit.jupiter:junit-jupiter:5.13.4" diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/RecipientHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/RecipientHelper.java index 5934ae59..301430e4 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/RecipientHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/RecipientHelper.java @@ -116,7 +116,8 @@ public class RecipientHelper { } if (forceRefresh) { try { - final var aci = handleResponseException(dependencies.getUsernameApi().getAciByUsername(finalUsername)); + final var aci = (ACI) handleResponseException(dependencies.getUsernameApi() + .getAciByUsername(finalUsername)); return account.getRecipientStore().resolveRecipientTrusted(aci, finalUsername.getUsername()); } catch (NonSuccessfulResponseCodeException e) { if (e.code == 404) { @@ -131,7 +132,7 @@ public class RecipientHelper { } return account.getRecipientStore().resolveRecipientByUsername(finalUsername.getUsername(), () -> { try { - return handleResponseException(dependencies.getUsernameApi().getAciByUsername(finalUsername)); + return (ACI) handleResponseException(dependencies.getUsernameApi().getAciByUsername(finalUsername)); } catch (Exception e) { return null; } diff --git a/lib/src/main/java/org/asamk/signal/manager/internal/SignalDependencies.java b/lib/src/main/java/org/asamk/signal/manager/internal/SignalDependencies.java index c2cfebcf..787abf7a 100644 --- a/lib/src/main/java/org/asamk/signal/manager/internal/SignalDependencies.java +++ b/lib/src/main/java/org/asamk/signal/manager/internal/SignalDependencies.java @@ -39,7 +39,7 @@ import org.whispersystems.signalservice.api.util.CredentialsProvider; import org.whispersystems.signalservice.api.util.UptimeSleepTimer; import org.whispersystems.signalservice.api.websocket.SignalWebSocket; import org.whispersystems.signalservice.internal.push.PushServiceSocket; -import org.whispersystems.signalservice.internal.websocket.OkHttpWebSocketConnection; +import org.whispersystems.signalservice.internal.websocket.LibSignalChatConnection; import java.io.IOException; import java.net.InetSocketAddress; @@ -284,13 +284,12 @@ public class SignalDependencies { final var timer = new UptimeSleepTimer(); final var healthMonitor = new SignalWebSocketHealthMonitor(timer); - authenticatedSignalWebSocket = new SignalWebSocket.AuthenticatedWebSocket(() -> new OkHttpWebSocketConnection( + authenticatedSignalWebSocket = new SignalWebSocket.AuthenticatedWebSocket(() -> new LibSignalChatConnection( "normal", - serviceEnvironmentConfig.signalServiceConfiguration(), - Optional.of(credentialsProvider), - userAgent, - healthMonitor, - allowStories), () -> true, timer, TimeUnit.SECONDS.toMillis(10)); + getLibSignalNetwork(), + credentialsProvider, + allowStories, + healthMonitor), () -> true, timer, TimeUnit.SECONDS.toMillis(10)); healthMonitor.monitor(authenticatedSignalWebSocket); }); } @@ -300,13 +299,12 @@ public class SignalDependencies { final var timer = new UptimeSleepTimer(); final var healthMonitor = new SignalWebSocketHealthMonitor(timer); - unauthenticatedSignalWebSocket = new SignalWebSocket.UnauthenticatedWebSocket(() -> new OkHttpWebSocketConnection( + unauthenticatedSignalWebSocket = new SignalWebSocket.UnauthenticatedWebSocket(() -> new LibSignalChatConnection( "unidentified", - serviceEnvironmentConfig.signalServiceConfiguration(), - Optional.empty(), - userAgent, - healthMonitor, - allowStories), () -> true, timer, TimeUnit.SECONDS.toMillis(10)); + getLibSignalNetwork(), + null, + allowStories, + healthMonitor), () -> true, timer, TimeUnit.SECONDS.toMillis(10)); healthMonitor.monitor(unauthenticatedSignalWebSocket); }); } @@ -328,8 +326,7 @@ public class SignalDependencies { executor, ServiceConfig.MAX_ENVELOPE_SIZE, () -> true, - UsePqRatchet.NO, - Optional.empty())); + UsePqRatchet.NO)); } public List getSecureValueRecovery() { diff --git a/lib/src/main/java/org/asamk/signal/manager/internal/SignalWebSocketHealthMonitor.java b/lib/src/main/java/org/asamk/signal/manager/internal/SignalWebSocketHealthMonitor.java index 7d927ddd..39a447ac 100644 --- a/lib/src/main/java/org/asamk/signal/manager/internal/SignalWebSocketHealthMonitor.java +++ b/lib/src/main/java/org/asamk/signal/manager/internal/SignalWebSocketHealthMonitor.java @@ -7,7 +7,6 @@ import org.whispersystems.signalservice.api.util.SleepTimer; import org.whispersystems.signalservice.api.websocket.HealthMonitor; import org.whispersystems.signalservice.api.websocket.SignalWebSocket; import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState; -import org.whispersystems.signalservice.internal.websocket.OkHttpWebSocketConnection; import java.util.concurrent.Executor; import java.util.concurrent.Executors; @@ -23,7 +22,7 @@ final class SignalWebSocketHealthMonitor implements HealthMonitor { /** * This is the amount of time in between sent keep alives. Must be greater than [KEEP_ALIVE_TIMEOUT] */ - private static final long KEEP_ALIVE_SEND_CADENCE = TimeUnit.SECONDS.toMillis(OkHttpWebSocketConnection.KEEPALIVE_FREQUENCY_SECONDS); + private static final long KEEP_ALIVE_SEND_CADENCE = TimeUnit.SECONDS.toMillis(30); /** * This is the amount of time we will wait for a response to the keep alive before we consider the websockets dead. diff --git a/lib/src/main/java/org/asamk/signal/manager/util/Utils.java b/lib/src/main/java/org/asamk/signal/manager/util/Utils.java index daee1d77..cb6a0b01 100644 --- a/lib/src/main/java/org/asamk/signal/manager/util/Utils.java +++ b/lib/src/main/java/org/asamk/signal/manager/util/Utils.java @@ -1,6 +1,8 @@ package org.asamk.signal.manager.util; import org.asamk.signal.manager.api.Pair; +import org.signal.libsignal.net.BadRequestError; +import org.signal.libsignal.net.RequestResult; import org.signal.libsignal.protocol.IdentityKey; import org.signal.libsignal.protocol.fingerprint.Fingerprint; import org.signal.libsignal.protocol.fingerprint.NumericFingerprintGenerator; @@ -158,6 +160,24 @@ public class Utils { return NetworkResultUtil.toBasicLegacy(response); } + public static T handleResponseException(final RequestResult result) throws IOException { + if (result instanceof RequestResult.Success) { + return ((RequestResult.Success) result).getResult(); + } else if (result instanceof RequestResult.ApplicationError e) { + final var cause = e.getCause(); + switch (cause) { + case IOException io -> throw io; + case RuntimeException rt -> throw rt; + default -> throw new RuntimeException(cause); + } + } else if (result instanceof RequestResult.RetryableNetworkError e) { + throw e.getNetworkError(); + } else if (result instanceof RequestResult.NonSuccess) { + throw new AssertionError(); + } + throw new IllegalStateException("Unexpected value: " + result); + } + public static ByteString firstNonEmpty(ByteString... strings) { for (final var s : strings) { if (s.size() > 0) { diff --git a/src/main/java/org/asamk/signal/BaseConfig.java b/src/main/java/org/asamk/signal/BaseConfig.java index 7ff5612f..bbce12a9 100644 --- a/src/main/java/org/asamk/signal/BaseConfig.java +++ b/src/main/java/org/asamk/signal/BaseConfig.java @@ -8,7 +8,7 @@ public class BaseConfig { public static final String PROJECT_VERSION = BaseConfig.class.getPackage().getImplementationVersion(); static final String USER_AGENT_SIGNAL_ANDROID = Optional.ofNullable(System.getenv("SIGNAL_CLI_USER_AGENT")) - .orElse("Signal-Android/7.56.6"); + .orElse("Signal-Android/7.57.1"); static final String USER_AGENT_SIGNAL_CLI = PROJECT_NAME == null ? "signal-cli" : PROJECT_NAME + "/" + PROJECT_VERSION;