Refactor to make encryption system available in view models (#2702)

This commit is contained in:
Hugh Nimmo-Smith
2024-11-04 09:11:44 +00:00
committed by GitHub
parent 19c4696a0d
commit f2ed07c258
5 changed files with 49 additions and 23 deletions

View File

@@ -115,7 +115,7 @@ export const ActiveCall: FC<ActiveCallProps> = (props) => {
const vm = new CallViewModel( const vm = new CallViewModel(
props.rtcSession.room, props.rtcSession.room,
livekitRoom, livekitRoom,
props.e2eeSystem.kind !== E2eeType.NONE, props.e2eeSystem,
connStateObservable, connStateObservable,
); );
setVm(vm); setVm(vm);
@@ -124,7 +124,7 @@ export const ActiveCall: FC<ActiveCallProps> = (props) => {
}, [ }, [
props.rtcSession.room, props.rtcSession.room,
livekitRoom, livekitRoom,
props.e2eeSystem.kind, props.e2eeSystem,
connStateObservable, connStateObservable,
]); ]);

View File

@@ -29,6 +29,7 @@ import {
ECAddonConnectionState, ECAddonConnectionState,
ECConnectionState, ECConnectionState,
} from "../livekit/useECConnectionState"; } from "../livekit/useECConnectionState";
import { E2eeType } from "../e2ee/e2eeType";
vi.mock("@livekit/components-core"); vi.mock("@livekit/components-core");
@@ -158,7 +159,9 @@ function withCallViewModel(
getMember: (userId) => members.get(userId) ?? null, getMember: (userId) => members.get(userId) ?? null,
}), }),
mockLivekitRoom({ localParticipant }), mockLivekitRoom({ localParticipant }),
true, {
kind: E2eeType.PER_PARTICIPANT,
},
connectionState, connectionState,
); );

View File

@@ -70,6 +70,7 @@ import { ObservableScope } from "./ObservableScope";
import { duplicateTiles } from "../settings/settings"; import { duplicateTiles } from "../settings/settings";
import { isFirefox } from "../Platform"; import { isFirefox } from "../Platform";
import { setPipEnabled } from "../controls"; import { setPipEnabled } from "../controls";
import { EncryptionSystem } from "../e2ee/sharedKeyManagement";
// How long we wait after a focus switch before showing the real participant // How long we wait after a focus switch before showing the real participant
// list again // list again
@@ -170,20 +171,20 @@ class UserMedia {
public readonly id: string, public readonly id: string,
member: RoomMember | undefined, member: RoomMember | undefined,
participant: LocalParticipant | RemoteParticipant, participant: LocalParticipant | RemoteParticipant,
callEncrypted: boolean, encryptionSystem: EncryptionSystem,
) { ) {
this.vm = participant.isLocal this.vm = participant.isLocal
? new LocalUserMediaViewModel( ? new LocalUserMediaViewModel(
id, id,
member, member,
participant as LocalParticipant, participant as LocalParticipant,
callEncrypted, encryptionSystem,
) )
: new RemoteUserMediaViewModel( : new RemoteUserMediaViewModel(
id, id,
member, member,
participant as RemoteParticipant, participant as RemoteParticipant,
callEncrypted, encryptionSystem,
); );
this.speaker = this.vm.speaking.pipe( this.speaker = this.vm.speaking.pipe(
@@ -226,9 +227,14 @@ class ScreenShare {
id: string, id: string,
member: RoomMember | undefined, member: RoomMember | undefined,
participant: LocalParticipant | RemoteParticipant, 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 { public destroy(): void {
@@ -363,7 +369,12 @@ export class CallViewModel extends ViewModel {
yield [ yield [
userMediaId, userMediaId,
prevItems.get(userMediaId) ?? prevItems.get(userMediaId) ??
new UserMedia(userMediaId, member, p, this.encrypted), new UserMedia(
userMediaId,
member,
p,
this.encryptionSystem,
),
]; ];
if (p.isScreenShareEnabled) { if (p.isScreenShareEnabled) {
@@ -371,7 +382,12 @@ export class CallViewModel extends ViewModel {
yield [ yield [
screenShareId, screenShareId,
prevItems.get(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 // A call is permanently tied to a single Matrix room and LiveKit room
private readonly matrixRoom: MatrixRoom, private readonly matrixRoom: MatrixRoom,
private readonly livekitRoom: LivekitRoom, private readonly livekitRoom: LivekitRoom,
private readonly encrypted: boolean, private readonly encryptionSystem: EncryptionSystem,
private readonly connectionState: Observable<ECConnectionState>, private readonly connectionState: Observable<ECConnectionState>,
) { ) {
super(); super();

View File

@@ -42,6 +42,8 @@ import { ViewModel } from "./ViewModel";
import { useReactiveState } from "../useReactiveState"; import { useReactiveState } from "../useReactiveState";
import { alwaysShowSelf } from "../settings/settings"; import { alwaysShowSelf } from "../settings/settings";
import { accumulate } from "../utils/observable"; import { accumulate } from "../utils/observable";
import { EncryptionSystem } from "../e2ee/sharedKeyManagement";
import { E2eeType } from "../e2ee/e2eeType";
// TODO: Move this naming logic into the view model // TODO: Move this naming logic into the view model
export function useDisplayName(vm: MediaViewModel): string { export function useDisplayName(vm: MediaViewModel): string {
@@ -105,7 +107,7 @@ abstract class BaseMediaViewModel extends ViewModel {
// member object internal // member object internal
public readonly member: RoomMember | undefined, public readonly member: RoomMember | undefined,
protected readonly participant: LocalParticipant | RemoteParticipant, protected readonly participant: LocalParticipant | RemoteParticipant,
callEncrypted: boolean, encryptionSystem: EncryptionSystem,
audioSource: AudioSource, audioSource: AudioSource,
videoSource: VideoSource, videoSource: VideoSource,
) { ) {
@@ -119,7 +121,7 @@ abstract class BaseMediaViewModel extends ViewModel {
this.unencryptedWarning = combineLatest( this.unencryptedWarning = combineLatest(
[audio, this.video], [audio, this.video],
(a, v) => (a, v) =>
callEncrypted && encryptionSystem.kind !== E2eeType.NONE &&
(a.publication?.isEncrypted === false || (a.publication?.isEncrypted === false ||
v.publication?.isEncrypted === false), v.publication?.isEncrypted === false),
).pipe(this.scope.state()); ).pipe(this.scope.state());
@@ -168,13 +170,13 @@ abstract class BaseUserMediaViewModel extends BaseMediaViewModel {
id: string, id: string,
member: RoomMember | undefined, member: RoomMember | undefined,
participant: LocalParticipant | RemoteParticipant, participant: LocalParticipant | RemoteParticipant,
callEncrypted: boolean, encryptionSystem: EncryptionSystem,
) { ) {
super( super(
id, id,
member, member,
participant, participant,
callEncrypted, encryptionSystem,
Track.Source.Microphone, Track.Source.Microphone,
Track.Source.Camera, Track.Source.Camera,
); );
@@ -225,9 +227,9 @@ export class LocalUserMediaViewModel extends BaseUserMediaViewModel {
id: string, id: string,
member: RoomMember | undefined, member: RoomMember | undefined,
participant: LocalParticipant, 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, id: string,
member: RoomMember | undefined, member: RoomMember | undefined,
participant: RemoteParticipant, participant: RemoteParticipant,
callEncrypted: boolean, encryptionSystem: EncryptionSystem,
) { ) {
super(id, member, participant, callEncrypted); super(id, member, participant, encryptionSystem);
// Sync the local volume with LiveKit // Sync the local volume with LiveKit
this.localVolume this.localVolume
@@ -318,13 +320,13 @@ export class ScreenShareViewModel extends BaseMediaViewModel {
id: string, id: string,
member: RoomMember | undefined, member: RoomMember | undefined,
participant: LocalParticipant | RemoteParticipant, participant: LocalParticipant | RemoteParticipant,
callEncrypted: boolean, encryptionSystem: EncryptionSystem,
) { ) {
super( super(
id, id,
member, member,
participant, participant,
callEncrypted, encryptionSystem,
Track.Source.ScreenShareAudio, Track.Source.ScreenShareAudio,
Track.Source.ScreenShare, Track.Source.ScreenShare,
); );

View File

@@ -20,6 +20,7 @@ import {
LocalUserMediaViewModel, LocalUserMediaViewModel,
RemoteUserMediaViewModel, RemoteUserMediaViewModel,
} from "../state/MediaViewModel"; } from "../state/MediaViewModel";
import { E2eeType } from "../e2ee/e2eeType";
export function withFakeTimers(continuation: () => void): void { export function withFakeTimers(continuation: () => void): void {
vi.useFakeTimers(); vi.useFakeTimers();
@@ -122,7 +123,9 @@ export async function withLocalMedia(
"local", "local",
mockMember(member), mockMember(member),
mockLocalParticipant({}), mockLocalParticipant({}),
true, {
kind: E2eeType.PER_PARTICIPANT,
},
); );
try { try {
await continuation(vm); await continuation(vm);
@@ -153,7 +156,9 @@ export async function withRemoteMedia(
"remote", "remote",
mockMember(member), mockMember(member),
mockRemoteParticipant(participant), mockRemoteParticipant(participant),
true, {
kind: E2eeType.PER_PARTICIPANT,
},
); );
try { try {
await continuation(vm); await continuation(vm);