Add eventTimestamp and deviceId for members for host election

This commit is contained in:
Robert Long 2022-04-20 16:35:11 -07:00
parent 239d075084
commit 9f4743e1ce
3 changed files with 39 additions and 6 deletions

View File

@ -201,11 +201,12 @@ export class CallHandler {
private handleCallMemberEvent(event: StateEvent, log: ILogItem) { private handleCallMemberEvent(event: StateEvent, log: ILogItem) {
const userId = event.state_key; const userId = event.state_key;
const calls = event.content["m.calls"] ?? []; const calls = event.content["m.calls"] ?? [];
const eventTimestamp = event.origin_server_ts;
for (const call of calls) { for (const call of calls) {
const callId = call["m.call_id"]; const callId = call["m.call_id"];
const groupCall = this._calls.get(callId); const groupCall = this._calls.get(callId);
// TODO: also check the member when receiving the m.call event // TODO: also check the member when receiving the m.call event
groupCall?.updateMembership(userId, call, log); groupCall?.updateMembership(userId, call, eventTimestamp, log);
}; };
const newCallIdsMemberOf = new Set<string>(calls.map(call => call["m.call_id"])); const newCallIdsMemberOf = new Set<string>(calls.map(call => call["m.call_id"]));
let previousCallIdsMemberOf = this.memberToCallIds.get(userId); let previousCallIdsMemberOf = this.memberToCallIds.get(userId);

View File

@ -64,6 +64,9 @@ export class GroupCall extends EventEmitter<{change: never}> {
private _memberOptions: MemberOptions; private _memberOptions: MemberOptions;
private _state: GroupCallState; private _state: GroupCallState;
private _deviceIndex?: number;
private _eventTimestamp?: number;
constructor( constructor(
public readonly id: string, public readonly id: string,
newCall: boolean, newCall: boolean,
@ -103,6 +106,14 @@ export class GroupCall extends EventEmitter<{change: never}> {
return this.callContent?.["m.intent"]; return this.callContent?.["m.intent"];
} }
get deviceIndex(): number | undefined {
return this._deviceIndex;
}
get eventTimestamp(): number | undefined {
return this._eventTimestamp;
}
join(localMedia: LocalMedia): Promise<void> { join(localMedia: LocalMedia): Promise<void> {
return this.logItem.wrap("join", async log => { return this.logItem.wrap("join", async log => {
if (this._state !== GroupCallState.Created) { if (this._state !== GroupCallState.Created) {
@ -188,16 +199,21 @@ export class GroupCall extends EventEmitter<{change: never}> {
} }
/** @internal */ /** @internal */
updateMembership(userId: string, callMembership: CallMembership, syncLog: ILogItem) { updateMembership(userId: string, callMembership: CallMembership, eventTimestamp: number, syncLog: ILogItem) {
this.logItem.wrap({l: "updateMember", id: userId}, log => { this.logItem.wrap({l: "updateMember", id: userId}, log => {
syncLog.refDetached(log); syncLog.refDetached(log);
const devices = callMembership["m.devices"]; const devices = callMembership["m.devices"];
const previousDeviceIds = this.getDeviceIdsForUserId(userId); const previousDeviceIds = this.getDeviceIdsForUserId(userId);
for (const device of devices) { for (let deviceIndex = 0; deviceIndex < devices.length; deviceIndex++) {
const device = devices[deviceIndex];
const deviceId = device.device_id; const deviceId = device.device_id;
const memberKey = getMemberKey(userId, deviceId); const memberKey = getMemberKey(userId, deviceId);
log.wrap({l: "update device member", id: memberKey}, log => { log.wrap({l: "update device member", id: memberKey}, log => {
if (userId === this.options.ownUserId && deviceId === this.options.ownDeviceId) { if (userId === this.options.ownUserId && deviceId === this.options.ownDeviceId) {
this._deviceIndex = deviceIndex;
this._eventTimestamp = eventTimestamp;
if (this._state === GroupCallState.Joining) { if (this._state === GroupCallState.Joining) {
log.set("update_own", true); log.set("update_own", true);
this._state = GroupCallState.Joined; this._state = GroupCallState.Joined;
@ -207,14 +223,14 @@ export class GroupCall extends EventEmitter<{change: never}> {
let member = this._members.get(memberKey); let member = this._members.get(memberKey);
if (member) { if (member) {
log.set("update", true); log.set("update", true);
member!.updateCallInfo(device); member!.updateCallInfo(device, deviceIndex, eventTimestamp);
} else { } else {
const logItem = this.logItem.child({l: "member", id: memberKey}); const logItem = this.logItem.child({l: "member", id: memberKey});
log.set("add", true); log.set("add", true);
log.refDetached(logItem); log.refDetached(logItem);
member = new Member( member = new Member(
RoomMember.fromUserId(this.roomId, userId, "join"), RoomMember.fromUserId(this.roomId, userId, "join"),
device, this._memberOptions, logItem device, deviceIndex, eventTimestamp, this._memberOptions, logItem
); );
this._members.add(memberKey, member); this._members.add(memberKey, member);
if (this._state === GroupCallState.Joining || this._state === GroupCallState.Joined) { if (this._state === GroupCallState.Joining || this._state === GroupCallState.Joined) {
@ -332,6 +348,10 @@ export class GroupCall extends EventEmitter<{change: never}> {
["session_id"]: this.options.sessionId, ["session_id"]: this.options.sessionId,
feeds: [{purpose: "m.usermedia"}] feeds: [{purpose: "m.usermedia"}]
}); });
this._deviceIndex = callInfo["m.devices"].length;
this._eventTimestamp = Date.now();
return stateContent; return stateContent;
} }

View File

@ -55,6 +55,8 @@ export class Member {
constructor( constructor(
public readonly member: RoomMember, public readonly member: RoomMember,
private callDeviceMembership: CallDeviceMembership, private callDeviceMembership: CallDeviceMembership,
private _deviceIndex: number,
private _eventTimestamp: number,
private readonly options: Options, private readonly options: Options,
private readonly logItem: ILogItem, private readonly logItem: ILogItem,
) {} ) {}
@ -79,6 +81,14 @@ export class Member {
return this.peerCall?.dataChannel; return this.peerCall?.dataChannel;
} }
get deviceIndex(): number {
return this._deviceIndex;
}
get eventTimestamp(): number {
return this._eventTimestamp;
}
/** @internal */ /** @internal */
connect(localMedia: LocalMedia) { connect(localMedia: LocalMedia) {
this.logItem.wrap("connect", () => { this.logItem.wrap("connect", () => {
@ -114,8 +124,10 @@ export class Member {
} }
/** @internal */ /** @internal */
updateCallInfo(callDeviceMembership: CallDeviceMembership) { updateCallInfo(callDeviceMembership: CallDeviceMembership, deviceIndex: number, eventTimestamp: number) {
this.callDeviceMembership = callDeviceMembership; this.callDeviceMembership = callDeviceMembership;
this._deviceIndex = deviceIndex;
this._eventTimestamp = eventTimestamp;
} }
/** @internal */ /** @internal */