Add Group Call peeking in the Conversation view.

This commit is contained in:
Cody Henthorne
2020-12-02 13:20:38 -05:00
committed by Greyson Parrelli
parent 2729eb9f5f
commit 01f143667f
18 changed files with 309 additions and 30 deletions

View File

@@ -35,6 +35,7 @@ import org.thoughtcrime.securesms.crypto.IdentityKeyParcelable;
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.events.GroupCallPeekEvent;
import org.thoughtcrime.securesms.events.WebRtcViewModel;
import org.thoughtcrime.securesms.groups.GroupId;
import org.thoughtcrime.securesms.groups.GroupManager;
@@ -52,6 +53,7 @@ import org.thoughtcrime.securesms.ringrtc.TurnServerInfoParcel;
import org.thoughtcrime.securesms.service.webrtc.IdleActionProcessor;
import org.thoughtcrime.securesms.service.webrtc.WebRtcData;
import org.thoughtcrime.securesms.service.webrtc.WebRtcInteractor;
import org.thoughtcrime.securesms.service.webrtc.WebRtcUtil;
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
import org.thoughtcrime.securesms.util.FutureTaskListener;
import org.thoughtcrime.securesms.util.ListenableFutureTask;
@@ -200,6 +202,7 @@ public class WebRtcCallService extends Service implements CallManager.Observer,
public static final String ACTION_GROUP_UPDATE_RENDERED_RESOLUTIONS = "GROUP_UPDATE_RENDERED_RESOLUTIONS";
public static final String ACTION_GROUP_CALL_ENDED = "GROUP_CALL_ENDED";
public static final String ACTION_GROUP_CALL_UPDATE_MESSAGE = "GROUP_CALL_UPDATE_MESSAGE";
public static final String ACTION_GROUP_CALL_PEEK = "GROUP_CALL_PEEK";
public static final int BUSY_TONE_LENGTH = 2000;
@@ -686,25 +689,59 @@ public class WebRtcCallService extends Service implements CallManager.Observer,
groupCallUpdateMetadata.getServerReceivedTimestamp(),
groupCallUpdateMetadata.getGroupCallEraId(),
peekInfo.getEraId(),
peekInfo.getJoinedMembers());
peekInfo.getJoinedMembers(),
WebRtcUtil.isCallFull(peekInfo));
long threadId = DatabaseFactory.getThreadDatabase(this).getThreadIdFor(group);
ApplicationDependencies.getMessageNotifier().updateNotification(this, threadId, true);
EventBus.getDefault().postSticky(new GroupCallPeekEvent(group.getId(), peekInfo.getEraId(), peekInfo.getDeviceCount(), peekInfo.getMaxDevices()));
});
} catch (IOException | VerificationFailedException | CallException e) {
Log.e(TAG, "error peeking", e);
Log.e(TAG, "error peeking from message", e);
}
});
}
public void updateGroupCallUpdateMessage(@NonNull RecipientId groupId, @Nullable String groupCallEraId, @NonNull Collection<UUID> joinedMembers) {
public void peekGroupCall(@NonNull RecipientId id) {
networkExecutor.execute(() -> {
try {
Recipient group = Recipient.resolved(id);
GroupId.V2 groupId = group.requireGroupId().requireV2();
GroupExternalCredential credential = GroupManager.getGroupExternalCredential(this, groupId);
List<GroupCall.GroupMemberInfo> members = Stream.of(GroupManager.getUuidCipherTexts(this, groupId))
.map(entry -> new GroupCall.GroupMemberInfo(entry.getKey(), entry.getValue().serialize()))
.toList();
callManager.peekGroupCall(BuildConfig.SIGNAL_SFU_URL, credential.getTokenBytes().toByteArray(), members, peekInfo -> {
long threadId = DatabaseFactory.getThreadDatabase(this).getThreadIdFor(group);
DatabaseFactory.getSmsDatabase(this).updatePreviousGroupCall(threadId,
peekInfo.getEraId(),
peekInfo.getJoinedMembers(),
WebRtcUtil.isCallFull(peekInfo));
ApplicationDependencies.getMessageNotifier().updateNotification(this, threadId, true);
EventBus.getDefault().postSticky(new GroupCallPeekEvent(id, peekInfo.getEraId(), peekInfo.getDeviceCount(), peekInfo.getMaxDevices()));
});
} catch (IOException | VerificationFailedException | CallException e) {
Log.e(TAG, "error peeking from active conversation", e);
}
});
}
public void updateGroupCallUpdateMessage(@NonNull RecipientId groupId, @Nullable String groupCallEraId, @NonNull Collection<UUID> joinedMembers, boolean isCallFull) {
DatabaseFactory.getSmsDatabase(this).insertOrUpdateGroupCall(groupId,
Recipient.self().getId(),
System.currentTimeMillis(),
null,
groupCallEraId,
joinedMembers);
joinedMembers,
isCallFull);
}
@Override

View File

@@ -125,7 +125,7 @@ public class GroupConnectedActionProcessor extends GroupActionProcessor {
if (!members.contains(Recipient.self().requireUuid())) {
members.add(Recipient.self().requireUuid());
}
webRtcInteractor.updateGroupCallUpdateMessage(currentState.getCallInfoState().getCallRecipient().getId(), eraId, members);
webRtcInteractor.updateGroupCallUpdateMessage(currentState.getCallInfoState().getCallRecipient().getId(), eraId, members, WebRtcUtil.isCallFull(peekInfo));
return currentState.builder()
.changeCallSetupState()
@@ -149,7 +149,7 @@ public class GroupConnectedActionProcessor extends GroupActionProcessor {
webRtcInteractor.sendGroupCallMessage(currentState.getCallInfoState().getCallRecipient(), eraId);
List<UUID> members = Stream.of(currentState.getCallInfoState().getRemoteCallParticipants()).map(p -> p.getRecipient().requireUuid()).toList();
webRtcInteractor.updateGroupCallUpdateMessage(currentState.getCallInfoState().getCallRecipient().getId(), eraId, members);
webRtcInteractor.updateGroupCallUpdateMessage(currentState.getCallInfoState().getCallRecipient().getId(), eraId, members, false);
currentState = currentState.builder()
.changeCallInfoState()

View File

@@ -61,6 +61,7 @@ import static org.thoughtcrime.securesms.service.WebRtcCallService.ACTION_ENDED_
import static org.thoughtcrime.securesms.service.WebRtcCallService.ACTION_ENDED_TIMEOUT;
import static org.thoughtcrime.securesms.service.WebRtcCallService.ACTION_FLIP_CAMERA;
import static org.thoughtcrime.securesms.service.WebRtcCallService.ACTION_GROUP_CALL_ENDED;
import static org.thoughtcrime.securesms.service.WebRtcCallService.ACTION_GROUP_CALL_PEEK;
import static org.thoughtcrime.securesms.service.WebRtcCallService.ACTION_GROUP_CALL_UPDATE_MESSAGE;
import static org.thoughtcrime.securesms.service.WebRtcCallService.ACTION_GROUP_JOINED_MEMBERSHIP_CHANGED;
import static org.thoughtcrime.securesms.service.WebRtcCallService.ACTION_GROUP_LOCAL_DEVICE_STATE_CHANGED;
@@ -238,6 +239,7 @@ public abstract class WebRtcActionProcessor {
case ACTION_GROUP_UPDATE_RENDERED_RESOLUTIONS: return handleUpdateRenderedResolutions(currentState);
case ACTION_GROUP_CALL_ENDED: return handleGroupCallEnded(currentState, getGroupCallHash(intent), getGroupCallEndReason(intent));
case ACTION_GROUP_CALL_UPDATE_MESSAGE: return handleGroupCallUpdateMessage(currentState, GroupCallUpdateMetadata.fromIntent(intent));
case ACTION_GROUP_CALL_PEEK: return handleGroupCallPeek(currentState, getRemotePeer(intent));
case ACTION_HTTP_SUCCESS: return handleHttpSuccess(currentState, HttpData.fromIntent(intent));
case ACTION_HTTP_FAILURE: return handleHttpFailure(currentState, HttpData.fromIntent(intent));
@@ -727,6 +729,11 @@ public abstract class WebRtcActionProcessor {
return currentState;
}
protected @NonNull WebRtcServiceState handleGroupCallPeek(@NonNull WebRtcServiceState currentState, @NonNull RemotePeer remotePeer) {
webRtcInteractor.peekGroupCall(remotePeer.getId());
return currentState;
}
//endregion
protected @NonNull WebRtcServiceState handleHttpSuccess(@NonNull WebRtcServiceState currentState, @NonNull HttpData httpData) {

View File

@@ -94,8 +94,8 @@ public class WebRtcInteractor {
webRtcCallService.sendGroupCallMessage(recipient, groupCallEraId);
}
void updateGroupCallUpdateMessage(@NonNull RecipientId groupId, @Nullable String groupCallEraId, @NonNull Collection<UUID> joinedMembers) {
webRtcCallService.updateGroupCallUpdateMessage(groupId, groupCallEraId, joinedMembers);
void updateGroupCallUpdateMessage(@NonNull RecipientId groupId, @Nullable String groupCallEraId, @NonNull Collection<UUID> joinedMembers, boolean isCallFull) {
webRtcCallService.updateGroupCallUpdateMessage(groupId, groupCallEraId, joinedMembers, isCallFull);
}
void setCallInProgressNotification(int type, @NonNull RemotePeer remotePeer) {
@@ -157,4 +157,8 @@ public class WebRtcInteractor {
void peekGroupCall(@NonNull WebRtcData.GroupCallUpdateMetadata groupCallUpdateMetadata) {
webRtcCallService.peekGroupCall(groupCallUpdateMetadata);
}
void peekGroupCall(@NonNull RecipientId recipientId) {
webRtcCallService.peekGroupCall(recipientId);
}
}

View File

@@ -77,4 +77,8 @@ public final class WebRtcUtil {
PeekInfo peekInfo = groupCall.getPeekInfo();
return peekInfo != null ? peekInfo.getEraId() : null;
}
public static boolean isCallFull(@Nullable PeekInfo peekInfo) {
return peekInfo != null && peekInfo.getMaxDevices() != null && peekInfo.getDeviceCount() >= peekInfo.getMaxDevices();
}
}