Update to RingRTC v2.35.0

Co-authored-by: ayumi yu <ayumi@signal.org>
Co-authored-by: ayumi-signal <143036029+ayumi-signal@users.noreply.github.com>
This commit is contained in:
Jim Gustafson 2024-01-04 18:25:51 -08:00 committed by Scott Nonnenberg
parent a30f277276
commit 6579b1a70a
9 changed files with 40 additions and 183 deletions

View file

@ -97,7 +97,7 @@
"@react-spring/web": "9.5.5", "@react-spring/web": "9.5.5",
"@signalapp/better-sqlite3": "8.6.0", "@signalapp/better-sqlite3": "8.6.0",
"@signalapp/libsignal-client": "0.36.0", "@signalapp/libsignal-client": "0.36.0",
"@signalapp/ringrtc": "2.34.5", "@signalapp/ringrtc": "2.35.0",
"@signalapp/windows-dummy-keystroke": "1.0.0", "@signalapp/windows-dummy-keystroke": "1.0.0",
"@types/fabric": "4.5.3", "@types/fabric": "4.5.3",
"backbone": "1.4.0", "backbone": "1.4.0",

View file

@ -875,6 +875,12 @@ export async function startApp(): Promise<void> {
await window.storage.remove('remoteBuildExpiration'); await window.storage.remove('remoteBuildExpiration');
} }
if (window.isBeforeVersion(lastVersion, '6.45.0-alpha')) {
await removeStorageKeyJobQueue.add({
key: 'previousAudioDeviceModule',
});
}
if (window.isBeforeVersion(lastVersion, '6.25.0-alpha')) { if (window.isBeforeVersion(lastVersion, '6.25.0-alpha')) {
await removeStorageKeyJobQueue.add({ await removeStorageKeyJobQueue.add({
key: 'nextSignedKeyRotationTime', key: 'nextSignedKeyRotationTime',

View file

@ -2,29 +2,21 @@
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import type { AudioDevice } from '@signalapp/ringrtc'; import type { AudioDevice } from '@signalapp/ringrtc';
import { AudioDeviceModule } from './audioDeviceModule';
export function findBestMatchingAudioDeviceIndex({ export function findBestMatchingAudioDeviceIndex({
available, available,
preferred, preferred,
previousAudioDeviceModule,
currentAudioDeviceModule,
}: Readonly<{ }: Readonly<{
available: ReadonlyArray<AudioDevice>; available: ReadonlyArray<AudioDevice>;
preferred: undefined | AudioDevice; preferred: undefined | AudioDevice;
previousAudioDeviceModule: AudioDeviceModule;
currentAudioDeviceModule: AudioDeviceModule;
}>): undefined | number { }>): undefined | number {
if (!preferred) { if (!preferred) {
return available.length > 0 ? 0 : undefined; return available.length > 0 ? 0 : undefined;
} }
if ( if (
(currentAudioDeviceModule === AudioDeviceModule.WindowsAdm2 && preferred.index === 0 ||
preferred.index === 0) || (preferred.index === 1 && available.length >= 2)
(previousAudioDeviceModule === AudioDeviceModule.WindowsAdm2 &&
preferred.index === 1 &&
available.length >= 2)
) { ) {
return preferred.index; return preferred.index;
} }

View file

@ -11,6 +11,7 @@ import { jobQueueDatabaseStore } from './JobQueueDatabaseStore';
const removeStorageKeyJobDataSchema = z.object({ const removeStorageKeyJobDataSchema = z.object({
key: z.enum([ key: z.enum([
'challenge:retry-message-ids', 'challenge:retry-message-ids',
'previousAudioDeviceModule',
'nextSignedKeyRotationTime', 'nextSignedKeyRotationTime',
'senderCertificateWithUuid', 'senderCertificateWithUuid',
'signedKeyRotationRejected', 'signedKeyRotationRejected',

View file

@ -60,11 +60,6 @@ import {
GroupCallConnectionState, GroupCallConnectionState,
GroupCallJoinState, GroupCallJoinState,
} from '../types/Calling'; } from '../types/Calling';
import {
AudioDeviceModule,
getAudioDeviceModule,
parseAudioDeviceModule,
} from '../calling/audioDeviceModule';
import { import {
findBestMatchingAudioDeviceIndex, findBestMatchingAudioDeviceIndex,
findBestMatchingCameraId, findBestMatchingCameraId,
@ -316,10 +311,6 @@ export class CallingClass {
private lastMediaDeviceSettings?: MediaDeviceSettings; private lastMediaDeviceSettings?: MediaDeviceSettings;
private previousAudioDeviceModule?: AudioDeviceModule;
private currentAudioDeviceModule?: AudioDeviceModule;
private deviceReselectionTimer?: NodeJS.Timeout; private deviceReselectionTimer?: NodeJS.Timeout;
private callsByConversation: { [conversationId: string]: Call | GroupCall }; private callsByConversation: { [conversationId: string]: Call | GroupCall };
@ -345,20 +336,7 @@ export class CallingClass {
this._sfuUrl = sfuUrl; this._sfuUrl = sfuUrl;
this.previousAudioDeviceModule = parseAudioDeviceModule(
window.storage.get('previousAudioDeviceModule')
);
this.currentAudioDeviceModule = getAudioDeviceModule();
drop(
window.storage.put(
'previousAudioDeviceModule',
this.currentAudioDeviceModule
)
);
RingRTC.setConfig({ RingRTC.setConfig({
use_new_audio_device_module:
this.currentAudioDeviceModule === AudioDeviceModule.WindowsAdm2,
field_trials: undefined, field_trials: undefined,
}); });
@ -1594,13 +1572,6 @@ export class CallingClass {
} }
async getMediaDeviceSettings(): Promise<MediaDeviceSettings> { async getMediaDeviceSettings(): Promise<MediaDeviceSettings> {
const { previousAudioDeviceModule, currentAudioDeviceModule } = this;
if (!previousAudioDeviceModule || !currentAudioDeviceModule) {
throw new Error(
'Calling#getMediaDeviceSettings cannot be called before audio device settings are set'
);
}
const { availableCameras, availableMicrophones, availableSpeakers } = const { availableCameras, availableMicrophones, availableSpeakers } =
await this.getAvailableIODevices(); await this.getAvailableIODevices();
@ -1608,8 +1579,6 @@ export class CallingClass {
const selectedMicIndex = findBestMatchingAudioDeviceIndex({ const selectedMicIndex = findBestMatchingAudioDeviceIndex({
available: availableMicrophones, available: availableMicrophones,
preferred: preferredMicrophone, preferred: preferredMicrophone,
previousAudioDeviceModule,
currentAudioDeviceModule,
}); });
const selectedMicrophone = const selectedMicrophone =
selectedMicIndex !== undefined selectedMicIndex !== undefined
@ -1620,8 +1589,6 @@ export class CallingClass {
const selectedSpeakerIndex = findBestMatchingAudioDeviceIndex({ const selectedSpeakerIndex = findBestMatchingAudioDeviceIndex({
available: availableSpeakers, available: availableSpeakers,
preferred: preferredSpeaker, preferred: preferredSpeaker,
previousAudioDeviceModule,
currentAudioDeviceModule,
}); });
const selectedSpeaker = const selectedSpeaker =
selectedSpeakerIndex !== undefined selectedSpeakerIndex !== undefined

View file

@ -2,20 +2,12 @@
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import { assert } from 'chai'; import { assert } from 'chai';
import { AudioDeviceModule } from '../../calling/audioDeviceModule';
import { findBestMatchingAudioDeviceIndex } from '../../calling/findBestMatchingDevice'; import { findBestMatchingAudioDeviceIndex } from '../../calling/findBestMatchingDevice';
describe('"find best matching device" helpers', () => { describe('"find best matching device" helpers', () => {
describe('findBestMatchingAudioDeviceIndex', () => { describe('findBestMatchingAudioDeviceIndex', () => {
type AdmOptionsType = Readonly<{ const itReturnsUndefinedIfNoDevicesAreAvailable = () => {
previousAudioDeviceModule: AudioDeviceModule;
currentAudioDeviceModule: AudioDeviceModule;
}>;
const itReturnsUndefinedIfNoDevicesAreAvailable = (
admOptions: AdmOptionsType
) => {
it('returns undefined if no devices are available', () => { it('returns undefined if no devices are available', () => {
[ [
undefined, undefined,
@ -25,16 +17,13 @@ describe('"find best matching device" helpers', () => {
findBestMatchingAudioDeviceIndex({ findBestMatchingAudioDeviceIndex({
available: [], available: [],
preferred, preferred,
...admOptions,
}) })
); );
}); });
}); });
}; };
const itReturnsTheFirstAvailableDeviceIfNoneIsPreferred = ( const itReturnsTheFirstAvailableDeviceIfNoneIsPreferred = () => {
admOptions: AdmOptionsType
) => {
it('returns the first available device if none is preferred', () => { it('returns the first available device if none is preferred', () => {
assert.strictEqual( assert.strictEqual(
findBestMatchingAudioDeviceIndex({ findBestMatchingAudioDeviceIndex({
@ -44,14 +33,13 @@ describe('"find best matching device" helpers', () => {
{ name: 'C', index: 789, uniqueId: 'device-C' }, { name: 'C', index: 789, uniqueId: 'device-C' },
], ],
preferred: undefined, preferred: undefined,
...admOptions,
}), }),
0 0
); );
}); });
}; };
const testUniqueIdMatch = (admOptions: AdmOptionsType) => { const testUniqueIdMatch = () => {
assert.strictEqual( assert.strictEqual(
findBestMatchingAudioDeviceIndex({ findBestMatchingAudioDeviceIndex({
available: [ available: [
@ -60,13 +48,12 @@ describe('"find best matching device" helpers', () => {
{ name: 'C', index: 789, uniqueId: 'device-C' }, { name: 'C', index: 789, uniqueId: 'device-C' },
], ],
preferred: { name: 'Ignored', index: 99, uniqueId: 'device-C' }, preferred: { name: 'Ignored', index: 99, uniqueId: 'device-C' },
...admOptions,
}), }),
2 2
); );
}; };
const testNameMatch = (admOptions: AdmOptionsType) => { const testNameMatch = () => {
assert.strictEqual( assert.strictEqual(
findBestMatchingAudioDeviceIndex({ findBestMatchingAudioDeviceIndex({
available: [ available: [
@ -75,123 +62,32 @@ describe('"find best matching device" helpers', () => {
{ name: 'C', index: 789, uniqueId: 'device-C' }, { name: 'C', index: 789, uniqueId: 'device-C' },
], ],
preferred: { name: 'C', index: 99, uniqueId: 'ignored' }, preferred: { name: 'C', index: 99, uniqueId: 'ignored' },
...admOptions,
}), }),
2 2
); );
}; };
const itReturnsTheFirstAvailableDeviceIfThePreferredDeviceIsNotFound = ( const itReturnsTheFirstAvailableDeviceIfThePreferredDeviceIsNotFound =
admOptions: AdmOptionsType () => {
) => { it('returns the first available device if the preferred device is not found', () => {
it('returns the first available device if the preferred device is not found', () => { assert.strictEqual(
assert.strictEqual( findBestMatchingAudioDeviceIndex({
findBestMatchingAudioDeviceIndex({ available: [
available: [ { name: 'A', index: 123, uniqueId: 'device-A' },
{ name: 'A', index: 123, uniqueId: 'device-A' }, { name: 'B', index: 456, uniqueId: 'device-B' },
{ name: 'B', index: 456, uniqueId: 'device-B' }, { name: 'C', index: 789, uniqueId: 'device-C' },
{ name: 'C', index: 789, uniqueId: 'device-C' }, ],
], preferred: { name: 'X', index: 123, uniqueId: 'Y' },
preferred: { name: 'X', index: 123, uniqueId: 'Y' }, }),
...admOptions, 0
}), );
0 });
);
});
};
describe('with default audio device module', () => {
const admOptions = {
previousAudioDeviceModule: AudioDeviceModule.Default,
currentAudioDeviceModule: AudioDeviceModule.Default,
}; };
itReturnsUndefinedIfNoDevicesAreAvailable(admOptions); describe('find best matching device', () => {
itReturnsUndefinedIfNoDevicesAreAvailable();
itReturnsTheFirstAvailableDeviceIfNoneIsPreferred(admOptions); itReturnsTheFirstAvailableDeviceIfNoneIsPreferred();
it('returns a unique ID match if it exists', () => {
testUniqueIdMatch(admOptions);
});
it('returns a name match if it exists', () => {
testNameMatch(admOptions);
});
itReturnsTheFirstAvailableDeviceIfThePreferredDeviceIsNotFound(
admOptions
);
});
describe('when going from the default to Windows ADM2', () => {
const admOptions = {
previousAudioDeviceModule: AudioDeviceModule.Default,
currentAudioDeviceModule: AudioDeviceModule.WindowsAdm2,
};
itReturnsUndefinedIfNoDevicesAreAvailable(admOptions);
itReturnsTheFirstAvailableDeviceIfNoneIsPreferred(admOptions);
it('returns 0 if that was the previous preferred index (and a device is available)', () => {
assert.strictEqual(
findBestMatchingAudioDeviceIndex({
available: [
{ name: 'A', index: 123, uniqueId: 'device-A' },
{ name: 'B', index: 456, uniqueId: 'device-B' },
],
preferred: { name: 'B', index: 0, uniqueId: 'device-B' },
...admOptions,
}),
0
);
});
it('returns a unique ID match if it exists and the preferred index is not 0', () => {
testUniqueIdMatch(admOptions);
});
it('returns a name match if it exists and the preferred index is not 0', () => {
testNameMatch(admOptions);
});
itReturnsTheFirstAvailableDeviceIfThePreferredDeviceIsNotFound(
admOptions
);
});
describe('when going "backwards" from Windows ADM2 to the default', () => {
const admOptions = {
previousAudioDeviceModule: AudioDeviceModule.WindowsAdm2,
currentAudioDeviceModule: AudioDeviceModule.Default,
};
itReturnsUndefinedIfNoDevicesAreAvailable(admOptions);
itReturnsTheFirstAvailableDeviceIfNoneIsPreferred(admOptions);
it('returns a unique ID match if it exists', () => {
testUniqueIdMatch(admOptions);
});
it('returns a name match if it exists', () => {
testNameMatch(admOptions);
});
itReturnsTheFirstAvailableDeviceIfThePreferredDeviceIsNotFound(
admOptions
);
});
describe('with Windows ADM2', () => {
const admOptions = {
previousAudioDeviceModule: AudioDeviceModule.WindowsAdm2,
currentAudioDeviceModule: AudioDeviceModule.WindowsAdm2,
};
itReturnsUndefinedIfNoDevicesAreAvailable(admOptions);
itReturnsTheFirstAvailableDeviceIfNoneIsPreferred(admOptions);
[0, 1].forEach(index => { [0, 1].forEach(index => {
it(`returns ${index} if that was the previous preferred index (and a device is available)`, () => { it(`returns ${index} if that was the previous preferred index (and a device is available)`, () => {
@ -203,7 +99,6 @@ describe('"find best matching device" helpers', () => {
{ name: 'C', index: 789, uniqueId: 'device-C' }, { name: 'C', index: 789, uniqueId: 'device-C' },
], ],
preferred: { name: 'C', index, uniqueId: 'device-C' }, preferred: { name: 'C', index, uniqueId: 'device-C' },
...admOptions,
}), }),
index index
); );
@ -215,23 +110,20 @@ describe('"find best matching device" helpers', () => {
findBestMatchingAudioDeviceIndex({ findBestMatchingAudioDeviceIndex({
available: [{ name: 'A', index: 123, uniqueId: 'device-A' }], available: [{ name: 'A', index: 123, uniqueId: 'device-A' }],
preferred: { name: 'C', index: 1, uniqueId: 'device-C' }, preferred: { name: 'C', index: 1, uniqueId: 'device-C' },
...admOptions,
}), }),
0 0
); );
}); });
it('returns a unique ID match if it exists and the preferred index is not 0 or 1', () => { it('returns a unique ID match if it exists and the preferred index is not 0 or 1', () => {
testUniqueIdMatch(admOptions); testUniqueIdMatch();
}); });
it('returns a name match if it exists and the preferred index is not 0 or 1', () => { it('returns a name match if it exists and the preferred index is not 0 or 1', () => {
testNameMatch(admOptions); testNameMatch();
}); });
itReturnsTheFirstAvailableDeviceIfThePreferredDeviceIsNotFound( itReturnsTheFirstAvailableDeviceIfThePreferredDeviceIsNotFound();
admOptions
);
}); });
}); });
}); });

View file

@ -140,7 +140,6 @@ export type StorageAccessType = {
'preferred-video-input-device': string; 'preferred-video-input-device': string;
'preferred-audio-input-device': AudioDevice; 'preferred-audio-input-device': AudioDevice;
'preferred-audio-output-device': AudioDevice; 'preferred-audio-output-device': AudioDevice;
previousAudioDeviceModule: AudioDeviceModule;
remoteConfig: RemoteConfigType; remoteConfig: RemoteConfigType;
serverTimeSkew: number; serverTimeSkew: number;
unidentifiedDeliveryIndicators: boolean; unidentifiedDeliveryIndicators: boolean;
@ -177,6 +176,7 @@ export type StorageAccessType = {
// Deprecated // Deprecated
'challenge:retry-message-ids': never; 'challenge:retry-message-ids': never;
nextSignedKeyRotationTime: number; nextSignedKeyRotationTime: number;
previousAudioDeviceModule: AudioDeviceModule;
senderCertificateWithUuid: never; senderCertificateWithUuid: never;
signaling_key: never; signaling_key: never;
signedKeyRotationRejected: number; signedKeyRotationRejected: number;

View file

@ -35,7 +35,6 @@ export const STORAGE_UI_KEYS: ReadonlyArray<keyof StorageAccessType> = [
'preferred-video-input-device', 'preferred-video-input-device',
'preferredLeftPaneWidth', 'preferredLeftPaneWidth',
'preferredReactionEmoji', 'preferredReactionEmoji',
'previousAudioDeviceModule',
'sendEditWarningShown', 'sendEditWarningShown',
'sent-media-quality', 'sent-media-quality',
'showStickerPickerHint', 'showStickerPickerHint',

View file

@ -3986,10 +3986,10 @@
ws "^8.4.2" ws "^8.4.2"
zod "^3.20.2" zod "^3.20.2"
"@signalapp/ringrtc@2.34.5": "@signalapp/ringrtc@2.35.0":
version "2.34.5" version "2.35.0"
resolved "https://registry.yarnpkg.com/@signalapp/ringrtc/-/ringrtc-2.34.5.tgz#33855d02845b0e8b476d7b611774127215966512" resolved "https://registry.yarnpkg.com/@signalapp/ringrtc/-/ringrtc-2.35.0.tgz#ca9c5fd660fa370720b85f784fc287acbbc6e68f"
integrity sha512-ORR3LI8Jn4MGosxa45cqjFyoggaOnJASa3rPx8FghfymWW+VClRYgh14jEouJpNwB6u9rviKOWyz7bF19uxn7w== integrity sha512-PXy+Io24UhGJQYivayVwIwgAT4A1g88JDxvzz5PNddlpHmSSRoBnH57fcZ1ElHTkqrcNb+V4Tch6SAuYupucow==
dependencies: dependencies:
https-proxy-agent "7.0.1" https-proxy-agent "7.0.1"
tar "^6.1.0" tar "^6.1.0"