always allow programmatic unmute#119
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adjusts the iOS CallKit mute/unmute handling to ensure programmatic unmute requests are not blocked by the allowUnmute guard when CallKit emits duplicate performSetMutedCallAction callbacks, and bumps the plugin version for release.
Changes:
- Track an in-flight “programmatic unmute” state to bypass
allowUnmutefor duplicate CallKit unmute actions. - Add
pendingProgrammaticUnmuteto the per-call active call state. - Bump plugin version from
2.2.3to2.2.4inplugin.xmlandpackage.json.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/ios/CordovaCall.m | Adds pendingProgrammaticUnmute tracking and bypass logic for duplicate CallKit unmute callbacks. |
| plugin.xml | Version bump to 2.2.4. |
| package.json | Version bump to 2.2.4. |
Comments suppressed due to low confidence (1)
src/ios/CordovaCall.m:574
pendingProgrammaticUnmuteis set to@YESwhen a programmatic unmute starts, but it is only cleared on transaction error or when the "secondary programmatic unmute" branch runs. If CallKit does not fire a secondaryperformSetMutedCallAction, this flag staysYESand later unmute actions (including UI-initiated ones) will bypass theallowUnmuteguard unintentionally.
// Flag that a programmatic unmute is in flight so that any secondary performSetMutedCallAction
// invocations (CallKit occasionally fires the delegate twice) also bypass the allowUnmute guard.
self.activeCalls[sessionId][@"pendingProgrammaticUnmute"] = @YES;
[self.callController requestTransaction:transaction completion:^(NSError * _Nullable error) {
if (error != nil) {
// Transaction was rejected before reaching performSetMutedCallAction — clean up.
[self.activeCalls[sessionId][@"callbackMap"] removeObjectForKey:unmuteAction.UUID.UUIDString];
self.activeCalls[sessionId][@"pendingProgrammaticUnmute"] = @NO;
[self logMessage:@"Error occurred unmuting Call"];
NSDictionary *resultDict = @{ @"message": @"An error occurred", @"sessionId": sessionId };
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:resultDict];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
}];
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| [action fulfill]; | ||
| [self logMessage:@"performSetMutedCallAction: secondary programmatic unmute action fulfilled"]; | ||
| return; | ||
| } |
There was a problem hiding this comment.
This can be greatly simplified by going back to the if/else from before this change. That way you can apply the allowUnmute logic only for callkit UI mute/unmute.
The UUID is the same for bugged duplicate mute/unmute action luckily.
if (in callback map) {
// programatic mute/unmute
} else {
// callkit UI mute/unmute
}
There was a problem hiding this comment.
L1145 is the end of if so the rest is else - i don't know what you mean here.
There was a problem hiding this comment.
Ok I see why this didn't work, the 2nd time is the same UUID but resolveCommandForSessionId removed the UUID from the callbackMap so it went into else. Callkit used to send a different UUID, but it now sends the same after we got better integration between callkit -> iosrtc via the config sync.
related to https://github.com/iotum/facetalk/issues/12798#issuecomment-4652255403
in short: a host can unmute anyone even when the meeting is in presentation.
context: native side execution, when a host remotely unmute a guest (before this PR)