Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -292,34 +292,46 @@ private class EventObserver implements EncryptionManager.Observer {
@Override
public void onE2eeEvent(EncryptionManager.E2eeEvent event) {
WritableMap params = Arguments.createMap();
params.putString("managerId", handle);
params.putString("type", event.type.name);
params.putString("userId", event.userId);

if (event.trackType != null) {
params.putInt("trackType", event.trackType.getValue());
}
if (event.keyIndex != null) {
params.putInt("keyIndex", event.keyIndex);
}
if (event.version != null) {
params.putInt("version", event.version);
}
if (event.reason != null) {
params.putString("reason", event.reason);
}
if (event.keyState != null) {
params.putMap("keyState", keyStateToMap(event.keyState));
}
if (event.encode != null) {
params.putArray("encode", trackPerfToArray(event.encode));
}
if (event.decode != null) {
params.putArray("decode", trackPerfToArray(event.decode));
try {
params.putString("managerId", handle);
params.putString("type", event.type.name);
params.putString("userId", event.userId);

if (event.trackType != null) {
params.putInt("trackType", event.trackType.getValue());
}
if (event.keyIndex != null) {
params.putInt("keyIndex", event.keyIndex);
}
if (event.version != null) {
params.putInt("version", event.version);
}
if (event.reason != null) {
params.putString("reason", event.reason);
}
if (event.keyState != null) {
params.putMap("keyState", keyStateToMap(event.keyState));
}
if (event.encode != null) {
params.putArray("encode", trackPerfToArray(event.encode));
}
if (event.decode != null) {
params.putArray("decode", trackPerfToArray(event.decode));
}
} catch (RuntimeException e) {
// A broken event is dropped; keys and transforms are not affected.
Log.w(TAG, "onE2eeEvent(): dropping event", e);
return;
}

// This callback runs on the crypto worker; events must be emitted off it.
ThreadUtils.runOnExecutor(() -> webRTCModule.sendEvent("encryptionManagerEvent", params));
ThreadUtils.runOnExecutor(() -> {
try {
webRTCModule.sendEvent("encryptionManagerEvent", params);
} catch (RuntimeException e) {
Log.w(TAG, "onE2eeEvent(): dropping event", e);
}
});
}
}

Expand Down
19 changes: 8 additions & 11 deletions android/src/main/java/com/oney/WebRTCModule/WebRTCModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,9 @@ public void invalidate() {
try {
ThreadUtils
.submitToExecutor(() -> {
// 0. Dispose E2EE managers: their frame transforms are held by the senders and
// receivers of the PeerConnections disposed next.
// 0. Dispose E2EE managers. JS is gone after a reload, so nothing else can
// release them. The order relative to the PeerConnections does not matter
// for safety; on a normal leave the PeerConnections go first.
encryptionManagerBridge.disposeAll();

// 1. Dispose PeerConnections (dispose() calls close() internally)
Expand Down Expand Up @@ -725,17 +726,13 @@ public MediaStreamTrack getTrackById(String trackId) {
if (local != null) {
return local;
}
// Use the track wrapper the observer keeps. Do not use pc.getReceivers() here:
// it disposes the wrappers from its previous call, which detaches their sinks.
for (int i = 0, size = mPeerConnectionObservers.size(); i < size; i++) {
PeerConnectionObserver pco = mPeerConnectionObservers.valueAt(i);
PeerConnection pc = pco.getPeerConnection();
if (pc == null) {
continue;
}
for (RtpReceiver receiver : pc.getReceivers()) {
MediaStreamTrack track = receiver.track();
if (track != null && trackId.equals(track.id())) {
return track;
}
MediaStreamTrack track = pco.remoteTracks.get(trackId);
if (track != null) {
return track;
}
}
return null;
Expand Down
4 changes: 2 additions & 2 deletions ios/RCTWebRTC/WebRTCModule.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ + (BOOL)requiresMainQueueSetup {
}

- (void)dealloc {
// E2EE managers first: their frame transforms are held by the senders and receivers of the peer
// connections closed below, and nothing in JS survives to dispose them.
// Dispose E2EE managers. JS is gone, so nothing else can release them. The order
// relative to the peer connections does not matter for safety.
for (NSString *handle in _encryptionManagers) {
RTC_OBJC_TYPE(RTCEncryptionManager) *manager = _encryptionManagers[handle];
manager.delegate = nil;
Expand Down
3 changes: 3 additions & 0 deletions src/RTCEncryptionManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ export default class RTCEncryptionManager {
* `codec` is an exact lowercase pin (`opus`/`vp8`/`vp9`/`h264`); anything else fails closed.
* Omitting it reads the codec from the frame. Omitting `trackType` defaults to audio vs video
* from the sender, so screen-share types must be passed explicitly.
*
* Call this before the sender has a track or is negotiated to send. Frames sent
* before the transform is attached go out unencrypted.
*/
encrypt(sender: RTCRtpSender, codec?: string, trackType?: RTCEncryptionTrackType): void {
this._invoke('encryptionManagerEncrypt', {
Expand Down
Loading