import { NativeModules } from 'react-native'; import { addListener, removeListener } from './EventEmitter'; import Logger from './Logger'; import { Event, EventTarget, getEventAttributeValue, setEventAttributeValue } from './vendor/event-target-shim'; const { WebRTCModule } = NativeModules; const log = new Logger('pc'); type FRAME_CRYPTOR_EVENTS = 'framecryptorstatechanged'; interface IRTCDataChannelEventInitDict extends Event.EventInit { frameCryptor: RTCFrameCryptor; state: RTCFrameCryptorState; } /** * @eventClass * This event is fired whenever the RTCDataChannel has changed in any way. * @param {FRAME_CRYPTOR_EVENTS} type - The type of event. * @param {IRTCDataChannelEventInitDict} eventInitDict - The event init properties. * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel#events MDN} for details. */ export class RTCFrameCryptorStateEvent< TEventType extends FRAME_CRYPTOR_EVENTS > extends Event { /** @eventProperty */ frameCryptor: RTCFrameCryptor; /** @eventProperty */ state: RTCFrameCryptorState; constructor(type: TEventType, eventInitDict: IRTCDataChannelEventInitDict) { super(type, eventInitDict); this.frameCryptor = eventInitDict.frameCryptor; this.state = eventInitDict.state; } } type RTCFrameCryptorEventMap = { framecryptorstatechanged: RTCFrameCryptorStateEvent<'framecryptorstatechanged'>; } export enum RTCFrameCryptorState { FrameCryptorStateNew, FrameCryptorStateOk, FrameCryptorStateEncryptionFailed, FrameCryptorStateDecryptionFailed, FrameCryptorStateMissingKey, FrameCryptorStateKeyRatcheted, FrameCryptorStateInternalError, } export default class RTCFrameCryptor extends EventTarget { private _frameCryptorId: string; private _participantId: string; get onframecryptorstatechanged() { return getEventAttributeValue(this, 'framecryptorstatechanged'); } set onframecryptorstatechanged(value) { setEventAttributeValue(this, 'framecryptorstatechanged', value); } constructor(frameCryptorId: string, participantId: string) { super(); this._frameCryptorId = frameCryptorId; this._participantId = participantId; this._registerEvents(); } get id() { return this._frameCryptorId; } get participantId() { return this._participantId; } _cryptorStateFromString(str: string): RTCFrameCryptorState { switch (str) { case 'new': return RTCFrameCryptorState.FrameCryptorStateNew; case 'ok': return RTCFrameCryptorState.FrameCryptorStateOk; case 'decryptionFailed': return RTCFrameCryptorState.FrameCryptorStateDecryptionFailed; case 'encryptionFailed': return RTCFrameCryptorState.FrameCryptorStateEncryptionFailed; case 'internalError': return RTCFrameCryptorState.FrameCryptorStateInternalError; case 'keyRatcheted': return RTCFrameCryptorState.FrameCryptorStateKeyRatcheted; case 'missingKey': return RTCFrameCryptorState.FrameCryptorStateMissingKey; default: throw 'Unknown FrameCryptorState: $str'; } } async setKeyIndex(keyIndex: number): Promise { const params = { frameCryptorId: this._frameCryptorId, keyIndex, }; return WebRTCModule.frameCryptorSetKeyIndex(params) .then(data => data['result']); } async getKeyIndex(): Promise { const params = { frameCryptorId: this._frameCryptorId, }; return WebRTCModule.frameCryptorGetKeyIndex(params) .then(data => data['keyIndex']); } async setEnabled(enabled: boolean): Promise { const params = { frameCryptorId: this._frameCryptorId, enabled, }; return WebRTCModule.frameCryptorSetEnabled(params) .then(data => data['result']); } async getEnabled(): Promise { const params = { frameCryptorId: this._frameCryptorId, }; return WebRTCModule.frameCryptorGetEnabled(params) .then(data => data['enabled']); } async dispose(): Promise { const params = { frameCryptorId: this._frameCryptorId, }; await WebRTCModule.frameCryptorDispose(params); removeListener(this); } _registerEvents(): void { addListener(this, 'frameCryptionStateChanged', (ev: any) => { if (ev.participantId !== this._participantId || ev.frameCryptorId !== this._frameCryptorId) { return; } log.debug(`${this.id} frameCryptionStateChanged ${ev.state}`); const initDict = { frameCryptor: this, state: ev.state, }; this.dispatchEvent(new RTCFrameCryptorStateEvent('framecryptorstatechanged', initDict)); }); } }