mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-29 18:40:39 +00:00
Use Java 17
This commit is contained in:
parent
9cb1409918
commit
ce70a623c2
51 changed files with 142 additions and 236 deletions
|
@ -20,22 +20,11 @@ public class LibSignalLogger implements SignalProtocolLogger {
|
|||
public void log(final int priority, final String tag, final String message) {
|
||||
final var logMessage = String.format("[%s]: %s", tag, message);
|
||||
switch (priority) {
|
||||
case SignalProtocolLogger.VERBOSE:
|
||||
logger.trace(logMessage);
|
||||
break;
|
||||
case SignalProtocolLogger.DEBUG:
|
||||
logger.debug(logMessage);
|
||||
break;
|
||||
case SignalProtocolLogger.INFO:
|
||||
logger.info(logMessage);
|
||||
break;
|
||||
case SignalProtocolLogger.WARN:
|
||||
logger.warn(logMessage);
|
||||
break;
|
||||
case SignalProtocolLogger.ERROR:
|
||||
case SignalProtocolLogger.ASSERT:
|
||||
logger.error(logMessage);
|
||||
break;
|
||||
case SignalProtocolLogger.VERBOSE -> logger.trace(logMessage);
|
||||
case SignalProtocolLogger.DEBUG -> logger.debug(logMessage);
|
||||
case SignalProtocolLogger.INFO -> logger.info(logMessage);
|
||||
case SignalProtocolLogger.WARN -> logger.warn(logMessage);
|
||||
case SignalProtocolLogger.ERROR, SignalProtocolLogger.ASSERT -> logger.error(logMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -569,16 +569,15 @@ public class ManagerImpl implements Manager {
|
|||
long timestamp = System.currentTimeMillis();
|
||||
messageBuilder.withTimestamp(timestamp);
|
||||
for (final var recipient : recipients) {
|
||||
if (recipient instanceof RecipientIdentifier.Single) {
|
||||
final var recipientId = resolveRecipient((RecipientIdentifier.Single) recipient);
|
||||
if (recipient instanceof RecipientIdentifier.Single single) {
|
||||
final var recipientId = resolveRecipient(single);
|
||||
final var result = sendHelper.sendMessage(messageBuilder, recipientId);
|
||||
results.put(recipient, List.of(result));
|
||||
} else if (recipient instanceof RecipientIdentifier.NoteToSelf) {
|
||||
final var result = sendHelper.sendSelfMessage(messageBuilder);
|
||||
results.put(recipient, List.of(result));
|
||||
} else if (recipient instanceof RecipientIdentifier.Group) {
|
||||
final var groupId = ((RecipientIdentifier.Group) recipient).groupId;
|
||||
final var result = sendHelper.sendAsGroupMessage(messageBuilder, groupId);
|
||||
} else if (recipient instanceof RecipientIdentifier.Group group) {
|
||||
final var result = sendHelper.sendAsGroupMessage(messageBuilder, group.groupId);
|
||||
results.put(recipient, result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,15 +63,9 @@ public final class SignalWebSocketHealthMonitor implements HealthMonitor {
|
|||
|
||||
private synchronized void onStateChange(WebSocketConnectionState connectionState, HealthState healthState) {
|
||||
switch (connectionState) {
|
||||
case CONNECTED:
|
||||
logger.debug("WebSocket is now connected");
|
||||
break;
|
||||
case AUTHENTICATION_FAILED:
|
||||
logger.debug("WebSocket authentication failed");
|
||||
break;
|
||||
case FAILED:
|
||||
logger.debug("WebSocket connection failed");
|
||||
break;
|
||||
case CONNECTED -> logger.debug("WebSocket is now connected");
|
||||
case AUTHENTICATION_FAILED -> logger.debug("WebSocket authentication failed");
|
||||
case FAILED -> logger.debug("WebSocket connection failed");
|
||||
}
|
||||
|
||||
healthState.needsKeepAlive = connectionState == WebSocketConnectionState.CONNECTED;
|
||||
|
|
|
@ -18,40 +18,27 @@ public enum TrustLevel {
|
|||
}
|
||||
|
||||
public static TrustLevel fromIdentityState(ContactRecord.IdentityState identityState) {
|
||||
switch (identityState) {
|
||||
case DEFAULT:
|
||||
return TRUSTED_UNVERIFIED;
|
||||
case UNVERIFIED:
|
||||
return UNTRUSTED;
|
||||
case VERIFIED:
|
||||
return TRUSTED_VERIFIED;
|
||||
case UNRECOGNIZED:
|
||||
return null;
|
||||
}
|
||||
throw new RuntimeException("Unknown identity state: " + identityState);
|
||||
return switch (identityState) {
|
||||
case DEFAULT -> TRUSTED_UNVERIFIED;
|
||||
case UNVERIFIED -> UNTRUSTED;
|
||||
case VERIFIED -> TRUSTED_VERIFIED;
|
||||
case UNRECOGNIZED -> null;
|
||||
};
|
||||
}
|
||||
|
||||
public static TrustLevel fromVerifiedState(VerifiedMessage.VerifiedState verifiedState) {
|
||||
switch (verifiedState) {
|
||||
case DEFAULT:
|
||||
return TRUSTED_UNVERIFIED;
|
||||
case UNVERIFIED:
|
||||
return UNTRUSTED;
|
||||
case VERIFIED:
|
||||
return TRUSTED_VERIFIED;
|
||||
}
|
||||
throw new RuntimeException("Unknown verified state: " + verifiedState);
|
||||
return switch (verifiedState) {
|
||||
case DEFAULT -> TRUSTED_UNVERIFIED;
|
||||
case UNVERIFIED -> UNTRUSTED;
|
||||
case VERIFIED -> TRUSTED_VERIFIED;
|
||||
};
|
||||
}
|
||||
|
||||
public VerifiedMessage.VerifiedState toVerifiedState() {
|
||||
switch (this) {
|
||||
case TRUSTED_UNVERIFIED:
|
||||
return VerifiedMessage.VerifiedState.DEFAULT;
|
||||
case UNTRUSTED:
|
||||
return VerifiedMessage.VerifiedState.UNVERIFIED;
|
||||
case TRUSTED_VERIFIED:
|
||||
return VerifiedMessage.VerifiedState.VERIFIED;
|
||||
}
|
||||
throw new RuntimeException("Unknown verified state: " + this);
|
||||
return switch (this) {
|
||||
case TRUSTED_UNVERIFIED -> VerifiedMessage.VerifiedState.DEFAULT;
|
||||
case UNTRUSTED -> VerifiedMessage.VerifiedState.UNVERIFIED;
|
||||
case TRUSTED_VERIFIED -> VerifiedMessage.VerifiedState.VERIFIED;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,17 +54,12 @@ public class SendRetryMessageRequestAction implements HandleAction {
|
|||
}
|
||||
|
||||
private static int envelopeTypeToCiphertextMessageType(int envelopeType) {
|
||||
switch (envelopeType) {
|
||||
case SignalServiceProtos.Envelope.Type.PREKEY_BUNDLE_VALUE:
|
||||
return CiphertextMessage.PREKEY_TYPE;
|
||||
case SignalServiceProtos.Envelope.Type.UNIDENTIFIED_SENDER_VALUE:
|
||||
return CiphertextMessage.SENDERKEY_TYPE;
|
||||
case SignalServiceProtos.Envelope.Type.PLAINTEXT_CONTENT_VALUE:
|
||||
return CiphertextMessage.PLAINTEXT_CONTENT_TYPE;
|
||||
case SignalServiceProtos.Envelope.Type.CIPHERTEXT_VALUE:
|
||||
default:
|
||||
return CiphertextMessage.WHISPER_TYPE;
|
||||
}
|
||||
return switch (envelopeType) {
|
||||
case SignalServiceProtos.Envelope.Type.PREKEY_BUNDLE_VALUE -> CiphertextMessage.PREKEY_TYPE;
|
||||
case SignalServiceProtos.Envelope.Type.UNIDENTIFIED_SENDER_VALUE -> CiphertextMessage.SENDERKEY_TYPE;
|
||||
case SignalServiceProtos.Envelope.Type.PLAINTEXT_CONTENT_VALUE -> CiphertextMessage.PLAINTEXT_CONTENT_TYPE;
|
||||
default -> CiphertextMessage.WHISPER_TYPE;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -9,9 +9,9 @@ import org.whispersystems.signalservice.api.util.UuidUtil;
|
|||
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class RecipientIdentifier {
|
||||
public sealed abstract class RecipientIdentifier {
|
||||
|
||||
public static class NoteToSelf extends RecipientIdentifier {
|
||||
public static final class NoteToSelf extends RecipientIdentifier {
|
||||
|
||||
public static NoteToSelf INSTANCE = new NoteToSelf();
|
||||
|
||||
|
@ -19,7 +19,7 @@ public abstract class RecipientIdentifier {
|
|||
}
|
||||
}
|
||||
|
||||
public abstract static class Single extends RecipientIdentifier {
|
||||
public sealed static abstract class Single extends RecipientIdentifier {
|
||||
|
||||
public static Single fromString(String identifier, String localNumber) throws InvalidNumberException {
|
||||
return UuidUtil.isUuid(identifier)
|
||||
|
@ -43,7 +43,7 @@ public abstract class RecipientIdentifier {
|
|||
public abstract String getIdentifier();
|
||||
}
|
||||
|
||||
public static class Uuid extends Single {
|
||||
public static final class Uuid extends Single {
|
||||
|
||||
public final UUID uuid;
|
||||
|
||||
|
@ -72,7 +72,7 @@ public abstract class RecipientIdentifier {
|
|||
}
|
||||
}
|
||||
|
||||
public static class Number extends Single {
|
||||
public static final class Number extends Single {
|
||||
|
||||
public final String number;
|
||||
|
||||
|
@ -101,7 +101,7 @@ public abstract class RecipientIdentifier {
|
|||
}
|
||||
}
|
||||
|
||||
public static class Group extends RecipientIdentifier {
|
||||
public static final class Group extends RecipientIdentifier {
|
||||
|
||||
public final GroupId groupId;
|
||||
|
||||
|
|
|
@ -7,13 +7,9 @@ public enum TypingAction {
|
|||
STOP;
|
||||
|
||||
public SignalServiceTypingMessage.Action toSignalService() {
|
||||
switch (this) {
|
||||
case START:
|
||||
return SignalServiceTypingMessage.Action.STARTED;
|
||||
case STOP:
|
||||
return SignalServiceTypingMessage.Action.STOPPED;
|
||||
default:
|
||||
throw new IllegalStateException("Invalid typing action " + this);
|
||||
}
|
||||
return switch (this) {
|
||||
case START -> SignalServiceTypingMessage.Action.STARTED;
|
||||
case STOP -> SignalServiceTypingMessage.Action.STOPPED;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,19 +88,15 @@ public class ServiceConfig {
|
|||
|
||||
final var interceptors = List.of(userAgentInterceptor);
|
||||
|
||||
switch (serviceEnvironment) {
|
||||
case LIVE:
|
||||
return new ServiceEnvironmentConfig(LiveConfig.createDefaultServiceConfiguration(interceptors),
|
||||
LiveConfig.getUnidentifiedSenderTrustRoot(),
|
||||
LiveConfig.createKeyBackupConfig(),
|
||||
LiveConfig.getCdsMrenclave());
|
||||
case SANDBOX:
|
||||
return new ServiceEnvironmentConfig(SandboxConfig.createDefaultServiceConfiguration(interceptors),
|
||||
SandboxConfig.getUnidentifiedSenderTrustRoot(),
|
||||
SandboxConfig.createKeyBackupConfig(),
|
||||
SandboxConfig.getCdsMrenclave());
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported environment");
|
||||
}
|
||||
return switch (serviceEnvironment) {
|
||||
case LIVE -> new ServiceEnvironmentConfig(LiveConfig.createDefaultServiceConfiguration(interceptors),
|
||||
LiveConfig.getUnidentifiedSenderTrustRoot(),
|
||||
LiveConfig.createKeyBackupConfig(),
|
||||
LiveConfig.getCdsMrenclave());
|
||||
case SANDBOX -> new ServiceEnvironmentConfig(SandboxConfig.createDefaultServiceConfiguration(interceptors),
|
||||
SandboxConfig.getUnidentifiedSenderTrustRoot(),
|
||||
SandboxConfig.createKeyBackupConfig(),
|
||||
SandboxConfig.getCdsMrenclave());
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package org.asamk.signal.manager.groups;
|
|||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
|
||||
public abstract class GroupId {
|
||||
public abstract sealed class GroupId permits GroupIdV1, GroupIdV2 {
|
||||
|
||||
private final byte[] id;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import java.util.Base64;
|
|||
|
||||
import static org.asamk.signal.manager.util.KeyUtils.getSecretBytes;
|
||||
|
||||
public class GroupIdV1 extends GroupId {
|
||||
public final class GroupIdV1 extends GroupId {
|
||||
|
||||
public static GroupIdV1 createRandom() {
|
||||
return new GroupIdV1(getSecretBytes(16));
|
||||
|
|
|
@ -2,7 +2,7 @@ package org.asamk.signal.manager.groups;
|
|||
|
||||
import java.util.Base64;
|
||||
|
||||
public class GroupIdV2 extends GroupId {
|
||||
public final class GroupIdV2 extends GroupId {
|
||||
|
||||
public static GroupIdV2 fromBase64(String groupId) {
|
||||
return new GroupIdV2(Base64.getDecoder().decode(groupId));
|
||||
|
|
|
@ -56,7 +56,7 @@ public final class GroupInviteLinkUrl {
|
|||
var groupInviteLink = GroupInviteLink.parseFrom(bytes);
|
||||
|
||||
switch (groupInviteLink.getContentsCase()) {
|
||||
case V1CONTENTS: {
|
||||
case V1CONTENTS -> {
|
||||
var groupInviteLinkContentsV1 = groupInviteLink.getV1Contents();
|
||||
var groupMasterKey = new GroupMasterKey(groupInviteLinkContentsV1.getGroupMasterKey()
|
||||
.toByteArray());
|
||||
|
@ -65,8 +65,7 @@ public final class GroupInviteLinkUrl {
|
|||
|
||||
return new GroupInviteLinkUrl(groupMasterKey, password);
|
||||
}
|
||||
default:
|
||||
throw new UnknownGroupLinkVersionException("Url contains no known group link content");
|
||||
default -> throw new UnknownGroupLinkVersionException("Url contains no known group link content");
|
||||
}
|
||||
} catch (InvalidInputException | IOException e) {
|
||||
throw new InvalidGroupLinkException(e);
|
||||
|
|
|
@ -351,8 +351,7 @@ public class GroupHelper {
|
|||
|
||||
private GroupInfo getGroup(GroupId groupId, boolean forceUpdate) {
|
||||
final var group = account.getGroupStore().getGroup(groupId);
|
||||
if (group instanceof GroupInfoV2) {
|
||||
final var groupInfoV2 = (GroupInfoV2) group;
|
||||
if (group instanceof GroupInfoV2 groupInfoV2) {
|
||||
if (forceUpdate || (!groupInfoV2.isPermissionDenied() && groupInfoV2.getGroup() == null)) {
|
||||
final var groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupInfoV2.getMasterKey());
|
||||
DecryptedGroup decryptedGroup;
|
||||
|
|
|
@ -391,27 +391,18 @@ public class GroupV2Helper {
|
|||
}
|
||||
|
||||
private AccessControl.AccessRequired toAccessControl(final GroupLinkState state) {
|
||||
switch (state) {
|
||||
case DISABLED:
|
||||
return AccessControl.AccessRequired.UNSATISFIABLE;
|
||||
case ENABLED:
|
||||
return AccessControl.AccessRequired.ANY;
|
||||
case ENABLED_WITH_APPROVAL:
|
||||
return AccessControl.AccessRequired.ADMINISTRATOR;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
return switch (state) {
|
||||
case DISABLED -> AccessControl.AccessRequired.UNSATISFIABLE;
|
||||
case ENABLED -> AccessControl.AccessRequired.ANY;
|
||||
case ENABLED_WITH_APPROVAL -> AccessControl.AccessRequired.ADMINISTRATOR;
|
||||
};
|
||||
}
|
||||
|
||||
private AccessControl.AccessRequired toAccessControl(final GroupPermission permission) {
|
||||
switch (permission) {
|
||||
case EVERY_MEMBER:
|
||||
return AccessControl.AccessRequired.MEMBER;
|
||||
case ONLY_ADMINS:
|
||||
return AccessControl.AccessRequired.ADMINISTRATOR;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
return switch (permission) {
|
||||
case EVERY_MEMBER -> AccessControl.AccessRequired.MEMBER;
|
||||
case ONLY_ADMINS -> AccessControl.AccessRequired.ADMINISTRATOR;
|
||||
};
|
||||
}
|
||||
|
||||
private GroupsV2Operations.GroupOperations getGroupOperations(final GroupInfoV2 groupInfoV2) {
|
||||
|
|
|
@ -83,8 +83,7 @@ public class SyncHelper {
|
|||
try (OutputStream fos = new FileOutputStream(groupsFile)) {
|
||||
var out = new DeviceGroupsOutputStream(fos);
|
||||
for (var record : account.getGroupStore().getGroups()) {
|
||||
if (record instanceof GroupInfoV1) {
|
||||
var groupInfo = (GroupInfoV1) record;
|
||||
if (record instanceof GroupInfoV1 groupInfo) {
|
||||
out.write(new DeviceGroup(groupInfo.getGroupId().serialize(),
|
||||
Optional.fromNullable(groupInfo.name),
|
||||
groupInfo.getMembers()
|
||||
|
|
|
@ -9,7 +9,7 @@ import java.util.Set;
|
|||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public abstract class GroupInfo {
|
||||
public sealed abstract class GroupInfo permits GroupInfoV1, GroupInfoV2 {
|
||||
|
||||
public abstract GroupId getGroupId();
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import java.util.Collection;
|
|||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class GroupInfoV1 extends GroupInfo {
|
||||
public final class GroupInfoV1 extends GroupInfo {
|
||||
|
||||
private final GroupIdV1 groupId;
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import org.whispersystems.signalservice.api.util.UuidUtil;
|
|||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class GroupInfoV2 extends GroupInfo {
|
||||
public final class GroupInfoV2 extends GroupInfo {
|
||||
|
||||
private final GroupIdV2 groupId;
|
||||
private final GroupMasterKey masterKey;
|
||||
|
@ -197,12 +197,9 @@ public class GroupInfoV2 extends GroupInfo {
|
|||
}
|
||||
|
||||
private static GroupPermission toGroupPermission(final AccessControl.AccessRequired permission) {
|
||||
switch (permission) {
|
||||
case ADMINISTRATOR:
|
||||
return GroupPermission.ONLY_ADMINS;
|
||||
case MEMBER:
|
||||
default:
|
||||
return GroupPermission.EVERY_MEMBER;
|
||||
}
|
||||
return switch (permission) {
|
||||
case ADMINISTRATOR -> GroupPermission.ONLY_ADMINS;
|
||||
default -> GroupPermission.EVERY_MEMBER;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,8 +75,7 @@ public class GroupStore {
|
|||
final Saver saver
|
||||
) {
|
||||
final var groups = storage.groups.stream().map(g -> {
|
||||
if (g instanceof Storage.GroupV1) {
|
||||
final var g1 = (Storage.GroupV1) g;
|
||||
if (g instanceof Storage.GroupV1 g1) {
|
||||
final var members = g1.members.stream().map(m -> {
|
||||
if (m.recipientId == null) {
|
||||
return recipientResolver.resolveRecipient(new RecipientAddress(UuidUtil.parseOrNull(m.uuid),
|
||||
|
@ -186,8 +185,7 @@ public class GroupStore {
|
|||
synchronized (groups) {
|
||||
var modified = false;
|
||||
for (var group : this.groups.values()) {
|
||||
if (group instanceof GroupInfoV1) {
|
||||
var groupV1 = (GroupInfoV1) group;
|
||||
if (group instanceof GroupInfoV1 groupV1) {
|
||||
if (groupV1.isMember(toBeMergedRecipientId)) {
|
||||
groupV1.removeMember(toBeMergedRecipientId);
|
||||
groupV1.addMembers(List.of(recipientId));
|
||||
|
@ -220,8 +218,7 @@ public class GroupStore {
|
|||
|
||||
private GroupInfoV1 getGroupV1ByV2IdLocked(GroupIdV2 groupIdV2) {
|
||||
for (var g : groups.values()) {
|
||||
if (g instanceof GroupInfoV1) {
|
||||
final var gv1 = (GroupInfoV1) g;
|
||||
if (g instanceof GroupInfoV1 gv1) {
|
||||
if (groupIdV2.equals(gv1.getExpectedV2Id())) {
|
||||
return gv1;
|
||||
}
|
||||
|
@ -256,8 +253,7 @@ public class GroupStore {
|
|||
|
||||
private Storage toStorageLocked() {
|
||||
return new Storage(groups.values().stream().map(g -> {
|
||||
if (g instanceof GroupInfoV1) {
|
||||
final var g1 = (GroupInfoV1) g;
|
||||
if (g instanceof GroupInfoV1 g1) {
|
||||
return new Storage.GroupV1(g1.getGroupId().toBase64(),
|
||||
g1.getExpectedV2Id().toBase64(),
|
||||
g1.name,
|
||||
|
|
|
@ -19,7 +19,7 @@ public class RecipientAddress {
|
|||
*/
|
||||
public RecipientAddress(Optional<UUID> uuid, Optional<String> e164) {
|
||||
uuid = uuid.isPresent() && uuid.get().equals(UuidUtil.UNKNOWN_UUID) ? Optional.empty() : uuid;
|
||||
if (!uuid.isPresent() && !e164.isPresent()) {
|
||||
if (uuid.isEmpty() && e164.isEmpty()) {
|
||||
throw new AssertionError("Must have either a UUID or E164 number!");
|
||||
}
|
||||
|
||||
|
|
|
@ -91,14 +91,11 @@ public class ProfileUtils {
|
|||
}
|
||||
String[] parts = name.split("\0");
|
||||
|
||||
switch (parts.length) {
|
||||
case 0:
|
||||
return new Pair<>(null, null);
|
||||
case 1:
|
||||
return new Pair<>(parts[0], null);
|
||||
default:
|
||||
return new Pair<>(parts[0], parts[1]);
|
||||
}
|
||||
return switch (parts.length) {
|
||||
case 0 -> new Pair<>(null, null);
|
||||
case 1 -> new Pair<>(parts[0], null);
|
||||
default -> new Pair<>(parts[0], parts[1]);
|
||||
};
|
||||
}
|
||||
|
||||
static String trimZeros(String str) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue