Add additional Group Calling features.

This commit is contained in:
Cody Henthorne
2020-11-20 15:42:46 -05:00
committed by GitHub
parent 8c1737e597
commit b90a74d26a
61 changed files with 1193 additions and 134 deletions

View File

@@ -713,6 +713,10 @@ public class SignalServiceMessageSender {
builder.setDelete(delete);
}
if (message.getGroupCallUpdate().isPresent()) {
builder.setGroupCallUpdate(DataMessage.GroupCallUpdate.newBuilder().setEraId(message.getGroupCallUpdate().get().getEraId()));
}
builder.setTimestamp(message.getTimestamp());
return enforceMaxContentSize(container.setDataMessage(builder).build().toByteArray());

View File

@@ -342,18 +342,19 @@ public final class SignalServiceContent {
}
List<SignalServiceAttachment> attachments = new LinkedList<>();
boolean endSession = ((content.getFlags() & SignalServiceProtos.DataMessage.Flags.END_SESSION_VALUE ) != 0);
boolean expirationUpdate = ((content.getFlags() & SignalServiceProtos.DataMessage.Flags.EXPIRATION_TIMER_UPDATE_VALUE) != 0);
boolean profileKeyUpdate = ((content.getFlags() & SignalServiceProtos.DataMessage.Flags.PROFILE_KEY_UPDATE_VALUE ) != 0);
boolean isGroupV2 = groupInfoV2 != null;
SignalServiceDataMessage.Quote quote = createQuote(content, isGroupV2);
List<SharedContact> sharedContacts = createSharedContacts(content);
List<SignalServiceDataMessage.Preview> previews = createPreviews(content);
List<SignalServiceDataMessage.Mention> mentions = createMentions(content.getBodyRangesList(), content.getBody(), isGroupV2);
SignalServiceDataMessage.Sticker sticker = createSticker(content);
SignalServiceDataMessage.Reaction reaction = createReaction(content);
SignalServiceDataMessage.RemoteDelete remoteDelete = createRemoteDelete(content);
List<SignalServiceAttachment> attachments = new LinkedList<>();
boolean endSession = ((content.getFlags() & SignalServiceProtos.DataMessage.Flags.END_SESSION_VALUE ) != 0);
boolean expirationUpdate = ((content.getFlags() & SignalServiceProtos.DataMessage.Flags.EXPIRATION_TIMER_UPDATE_VALUE) != 0);
boolean profileKeyUpdate = ((content.getFlags() & SignalServiceProtos.DataMessage.Flags.PROFILE_KEY_UPDATE_VALUE ) != 0);
boolean isGroupV2 = groupInfoV2 != null;
SignalServiceDataMessage.Quote quote = createQuote(content, isGroupV2);
List<SharedContact> sharedContacts = createSharedContacts(content);
List<SignalServiceDataMessage.Preview> previews = createPreviews(content);
List<SignalServiceDataMessage.Mention> mentions = createMentions(content.getBodyRangesList(), content.getBody(), isGroupV2);
SignalServiceDataMessage.Sticker sticker = createSticker(content);
SignalServiceDataMessage.Reaction reaction = createReaction(content);
SignalServiceDataMessage.RemoteDelete remoteDelete = createRemoteDelete(content);
SignalServiceDataMessage.GroupCallUpdate groupCallUpdate = createGroupCallUpdate(content);
if (content.getRequiredProtocolVersion() > SignalServiceProtos.DataMessage.ProtocolVersion.CURRENT_VALUE) {
throw new UnsupportedDataMessageProtocolVersionException(SignalServiceProtos.DataMessage.ProtocolVersion.CURRENT_VALUE,
@@ -389,7 +390,8 @@ public final class SignalServiceContent {
sticker,
content.getIsViewOnce(),
reaction,
remoteDelete);
remoteDelete,
groupCallUpdate);
}
private static SignalServiceSyncMessage createSynchronizeMessage(SignalServiceMetadata metadata,
@@ -787,6 +789,16 @@ public final class SignalServiceContent {
return new SignalServiceDataMessage.RemoteDelete(delete.getTargetSentTimestamp());
}
private static SignalServiceDataMessage.GroupCallUpdate createGroupCallUpdate(SignalServiceProtos.DataMessage content) {
if (!content.hasGroupCallUpdate()) {
return null;
}
SignalServiceProtos.DataMessage.GroupCallUpdate groupCallUpdate = content.getGroupCallUpdate();
return new SignalServiceDataMessage.GroupCallUpdate(groupCallUpdate.getEraId());
}
private static List<SharedContact> createSharedContacts(SignalServiceProtos.DataMessage content) throws ProtocolInvalidMessageException {
if (content.getContactCount() <= 0) return null;

View File

@@ -38,6 +38,7 @@ public class SignalServiceDataMessage {
private final boolean viewOnce;
private final Optional<Reaction> reaction;
private final Optional<RemoteDelete> remoteDelete;
private final Optional<GroupCallUpdate> groupCallUpdate;
/**
* Construct a SignalServiceDataMessage.
@@ -56,7 +57,8 @@ public class SignalServiceDataMessage {
String body, boolean endSession, int expiresInSeconds,
boolean expirationUpdate, byte[] profileKey, boolean profileKeyUpdate,
Quote quote, List<SharedContact> sharedContacts, List<Preview> previews,
List<Mention> mentions, Sticker sticker, boolean viewOnce, Reaction reaction, RemoteDelete remoteDelete)
List<Mention> mentions, Sticker sticker, boolean viewOnce, Reaction reaction, RemoteDelete remoteDelete,
GroupCallUpdate groupCallUpdate)
{
try {
this.group = SignalServiceGroupContext.createOptional(group, groupV2);
@@ -64,18 +66,19 @@ public class SignalServiceDataMessage {
throw new AssertionError(e);
}
this.timestamp = timestamp;
this.body = OptionalUtil.absentIfEmpty(body);
this.endSession = endSession;
this.expiresInSeconds = expiresInSeconds;
this.expirationUpdate = expirationUpdate;
this.profileKey = Optional.fromNullable(profileKey);
this.profileKeyUpdate = profileKeyUpdate;
this.quote = Optional.fromNullable(quote);
this.sticker = Optional.fromNullable(sticker);
this.viewOnce = viewOnce;
this.reaction = Optional.fromNullable(reaction);
this.remoteDelete = Optional.fromNullable(remoteDelete);
this.timestamp = timestamp;
this.body = OptionalUtil.absentIfEmpty(body);
this.endSession = endSession;
this.expiresInSeconds = expiresInSeconds;
this.expirationUpdate = expirationUpdate;
this.profileKey = Optional.fromNullable(profileKey);
this.profileKeyUpdate = profileKeyUpdate;
this.quote = Optional.fromNullable(quote);
this.sticker = Optional.fromNullable(sticker);
this.viewOnce = viewOnce;
this.reaction = Optional.fromNullable(reaction);
this.remoteDelete = Optional.fromNullable(remoteDelete);
this.groupCallUpdate = Optional.fromNullable(groupCallUpdate);
if (attachments != null && !attachments.isEmpty()) {
this.attachments = Optional.of(attachments);
@@ -220,6 +223,10 @@ public class SignalServiceDataMessage {
return remoteDelete;
}
public Optional<GroupCallUpdate> getGroupCallUpdate() {
return groupCallUpdate;
}
public static class Builder {
private List<SignalServiceAttachment> attachments = new LinkedList<>();
@@ -241,6 +248,7 @@ public class SignalServiceDataMessage {
private boolean viewOnce;
private Reaction reaction;
private RemoteDelete remoteDelete;
private GroupCallUpdate groupCallUpdate;
private Builder() {}
@@ -358,12 +366,18 @@ public class SignalServiceDataMessage {
return this;
}
public Builder withGroupCallUpdate(GroupCallUpdate groupCallUpdate) {
this.groupCallUpdate = groupCallUpdate;
return this;
}
public SignalServiceDataMessage build() {
if (timestamp == 0) timestamp = System.currentTimeMillis();
return new SignalServiceDataMessage(timestamp, group, groupV2, attachments, body, endSession,
expiresInSeconds, expirationUpdate, profileKey,
profileKeyUpdate, quote, sharedContacts, previews,
mentions, sticker, viewOnce, reaction, remoteDelete);
mentions, sticker, viewOnce, reaction, remoteDelete,
groupCallUpdate);
}
}
@@ -564,4 +578,16 @@ public class SignalServiceDataMessage {
return length;
}
}
public static class GroupCallUpdate {
private final String eraId;
public GroupCallUpdate(String eraId) {
this.eraId = eraId;
}
public String getEraId() {
return eraId;
}
}
}

View File

@@ -215,6 +215,8 @@ public class PushServiceSocket {
private static final long CDN2_RESUMABLE_LINK_LIFETIME_MILLIS = TimeUnit.DAYS.toMillis(7);
private static final int MAX_FOLLOW_UPS = 20;
private long soTimeoutMillis = TimeUnit.SECONDS.toMillis(30);
private final Set<Call> connections = new HashSet<>();
@@ -1672,7 +1674,7 @@ public class PushServiceSocket {
ConnectionHolder connectionHolder = getRandom(serviceClients, random);
OkHttpClient okHttpClient = connectionHolder.getClient()
.newBuilder()
.followRedirects(true)
.followRedirects(false)
.connectTimeout(soTimeoutMillis, TimeUnit.MILLISECONDS)
.readTimeout(soTimeoutMillis, TimeUnit.MILLISECONDS)
.build();
@@ -1688,22 +1690,36 @@ public class PushServiceSocket {
}
}
Call call = okHttpClient.newCall(builder.build());
Request request = builder.build();
try {
Response response = call.execute();
int responseStatus = response.code();
byte[] responseBody = response.body() != null ? response.body().bytes() : new byte[0];
for (int i = 0; i < MAX_FOLLOW_UPS; i++) {
try (Response response = okHttpClient.newCall(request).execute()) {
int responseStatus = response.code();
return new CallingResponse.Success(requestId, responseStatus, responseBody);
} catch (IOException e) {
Log.w(TAG, "Exception during ringrtc http call.", e);
return new CallingResponse.Error(requestId, e);
if (responseStatus != 307) {
return new CallingResponse.Success(requestId,
responseStatus,
response.body() != null ? response.body().bytes() : new byte[0]);
}
String location = response.header("Location");
HttpUrl newUrl = location != null ? request.url().resolve(location) : null;
if (newUrl != null) {
request = request.newBuilder().url(newUrl).build();
} else {
return new CallingResponse.Error(requestId, new IOException("Received redirect without a valid Location header"));
}
} catch (IOException e) {
Log.w(TAG, "Exception during ringrtc http call.", e);
return new CallingResponse.Error(requestId, e);
}
}
Log.w(TAG, "Calling request max redirects exceeded");
return new CallingResponse.Error(requestId, new IOException("Redirect limit exceeded"));
}
private ServiceConnectionHolder[] createServiceConnectionHolders(SignalUrl[] urls,
List<Interceptor> interceptors,
Optional<Dns> dns)

View File

@@ -234,6 +234,10 @@ message DataMessage {
optional uint64 targetSentTimestamp = 1;
}
message GroupCallUpdate {
optional string eraId = 1;
}
enum ProtocolVersion {
option allow_alias = true;
@@ -264,6 +268,7 @@ message DataMessage {
optional Reaction reaction = 16;
optional Delete delete = 17;
repeated BodyRange bodyRanges = 18;
optional GroupCallUpdate groupCallUpdate = 19;
}
message NullMessage {