diff --git a/src/room/InCallView.tsx b/src/room/InCallView.tsx index fef390f2..b754c696 100644 --- a/src/room/InCallView.tsx +++ b/src/room/InCallView.tsx @@ -115,7 +115,7 @@ export const ActiveCall: FC = (props) => { const vm = new CallViewModel( props.rtcSession.room, livekitRoom, - props.e2eeSystem.kind !== E2eeType.NONE, + props.e2eeSystem, connStateObservable, ); setVm(vm); @@ -124,7 +124,7 @@ export const ActiveCall: FC = (props) => { }, [ props.rtcSession.room, livekitRoom, - props.e2eeSystem.kind, + props.e2eeSystem, connStateObservable, ]); diff --git a/src/state/CallViewModel.test.ts b/src/state/CallViewModel.test.ts index 89f95b92..14214407 100644 --- a/src/state/CallViewModel.test.ts +++ b/src/state/CallViewModel.test.ts @@ -29,6 +29,7 @@ import { ECAddonConnectionState, ECConnectionState, } from "../livekit/useECConnectionState"; +import { E2eeType } from "../e2ee/e2eeType"; vi.mock("@livekit/components-core"); @@ -158,7 +159,9 @@ function withCallViewModel( getMember: (userId) => members.get(userId) ?? null, }), mockLivekitRoom({ localParticipant }), - true, + { + kind: E2eeType.PER_PARTICIPANT, + }, connectionState, ); diff --git a/src/state/CallViewModel.ts b/src/state/CallViewModel.ts index 6064e611..db2833b8 100644 --- a/src/state/CallViewModel.ts +++ b/src/state/CallViewModel.ts @@ -70,6 +70,7 @@ import { ObservableScope } from "./ObservableScope"; import { duplicateTiles } from "../settings/settings"; import { isFirefox } from "../Platform"; import { setPipEnabled } from "../controls"; +import { EncryptionSystem } from "../e2ee/sharedKeyManagement"; // How long we wait after a focus switch before showing the real participant // list again @@ -170,20 +171,20 @@ class UserMedia { public readonly id: string, member: RoomMember | undefined, participant: LocalParticipant | RemoteParticipant, - callEncrypted: boolean, + encryptionSystem: EncryptionSystem, ) { this.vm = participant.isLocal ? new LocalUserMediaViewModel( id, member, participant as LocalParticipant, - callEncrypted, + encryptionSystem, ) : new RemoteUserMediaViewModel( id, member, participant as RemoteParticipant, - callEncrypted, + encryptionSystem, ); this.speaker = this.vm.speaking.pipe( @@ -226,9 +227,14 @@ class ScreenShare { id: string, member: RoomMember | undefined, participant: LocalParticipant | RemoteParticipant, - callEncrypted: boolean, + encryptionSystem: EncryptionSystem, ) { - this.vm = new ScreenShareViewModel(id, member, participant, callEncrypted); + this.vm = new ScreenShareViewModel( + id, + member, + participant, + encryptionSystem, + ); } public destroy(): void { @@ -363,7 +369,12 @@ export class CallViewModel extends ViewModel { yield [ userMediaId, prevItems.get(userMediaId) ?? - new UserMedia(userMediaId, member, p, this.encrypted), + new UserMedia( + userMediaId, + member, + p, + this.encryptionSystem, + ), ]; if (p.isScreenShareEnabled) { @@ -371,7 +382,12 @@ export class CallViewModel extends ViewModel { yield [ screenShareId, prevItems.get(screenShareId) ?? - new ScreenShare(screenShareId, member, p, this.encrypted), + new ScreenShare( + screenShareId, + member, + p, + this.encryptionSystem, + ), ]; } } @@ -829,7 +845,7 @@ export class CallViewModel extends ViewModel { // A call is permanently tied to a single Matrix room and LiveKit room private readonly matrixRoom: MatrixRoom, private readonly livekitRoom: LivekitRoom, - private readonly encrypted: boolean, + private readonly encryptionSystem: EncryptionSystem, private readonly connectionState: Observable, ) { super(); diff --git a/src/state/MediaViewModel.ts b/src/state/MediaViewModel.ts index 50d8613a..51a821af 100644 --- a/src/state/MediaViewModel.ts +++ b/src/state/MediaViewModel.ts @@ -42,6 +42,8 @@ import { ViewModel } from "./ViewModel"; import { useReactiveState } from "../useReactiveState"; import { alwaysShowSelf } from "../settings/settings"; import { accumulate } from "../utils/observable"; +import { EncryptionSystem } from "../e2ee/sharedKeyManagement"; +import { E2eeType } from "../e2ee/e2eeType"; // TODO: Move this naming logic into the view model export function useDisplayName(vm: MediaViewModel): string { @@ -105,7 +107,7 @@ abstract class BaseMediaViewModel extends ViewModel { // member object internal public readonly member: RoomMember | undefined, protected readonly participant: LocalParticipant | RemoteParticipant, - callEncrypted: boolean, + encryptionSystem: EncryptionSystem, audioSource: AudioSource, videoSource: VideoSource, ) { @@ -119,7 +121,7 @@ abstract class BaseMediaViewModel extends ViewModel { this.unencryptedWarning = combineLatest( [audio, this.video], (a, v) => - callEncrypted && + encryptionSystem.kind !== E2eeType.NONE && (a.publication?.isEncrypted === false || v.publication?.isEncrypted === false), ).pipe(this.scope.state()); @@ -168,13 +170,13 @@ abstract class BaseUserMediaViewModel extends BaseMediaViewModel { id: string, member: RoomMember | undefined, participant: LocalParticipant | RemoteParticipant, - callEncrypted: boolean, + encryptionSystem: EncryptionSystem, ) { super( id, member, participant, - callEncrypted, + encryptionSystem, Track.Source.Microphone, Track.Source.Camera, ); @@ -225,9 +227,9 @@ export class LocalUserMediaViewModel extends BaseUserMediaViewModel { id: string, member: RoomMember | undefined, participant: LocalParticipant, - callEncrypted: boolean, + encryptionSystem: EncryptionSystem, ) { - super(id, member, participant, callEncrypted); + super(id, member, participant, encryptionSystem); } } @@ -285,9 +287,9 @@ export class RemoteUserMediaViewModel extends BaseUserMediaViewModel { id: string, member: RoomMember | undefined, participant: RemoteParticipant, - callEncrypted: boolean, + encryptionSystem: EncryptionSystem, ) { - super(id, member, participant, callEncrypted); + super(id, member, participant, encryptionSystem); // Sync the local volume with LiveKit this.localVolume @@ -318,13 +320,13 @@ export class ScreenShareViewModel extends BaseMediaViewModel { id: string, member: RoomMember | undefined, participant: LocalParticipant | RemoteParticipant, - callEncrypted: boolean, + encryptionSystem: EncryptionSystem, ) { super( id, member, participant, - callEncrypted, + encryptionSystem, Track.Source.ScreenShareAudio, Track.Source.ScreenShare, ); diff --git a/src/utils/test.ts b/src/utils/test.ts index f06bcd30..85e72d38 100644 --- a/src/utils/test.ts +++ b/src/utils/test.ts @@ -20,6 +20,7 @@ import { LocalUserMediaViewModel, RemoteUserMediaViewModel, } from "../state/MediaViewModel"; +import { E2eeType } from "../e2ee/e2eeType"; export function withFakeTimers(continuation: () => void): void { vi.useFakeTimers(); @@ -122,7 +123,9 @@ export async function withLocalMedia( "local", mockMember(member), mockLocalParticipant({}), - true, + { + kind: E2eeType.PER_PARTICIPANT, + }, ); try { await continuation(vm); @@ -153,7 +156,9 @@ export async function withRemoteMedia( "remote", mockMember(member), mockRemoteParticipant(participant), - true, + { + kind: E2eeType.PER_PARTICIPANT, + }, ); try { await continuation(vm);