Skip to content

always allow programmatic unmute#119

Draft
jerry2013 wants to merge 1 commit into
developfrom
jerry_hu/allow-host-to-force-unmute
Draft

always allow programmatic unmute#119
jerry2013 wants to merge 1 commit into
developfrom
jerry_hu/allow-host-to-force-unmute

Conversation

@jerry2013

@jerry2013 jerry2013 commented Jun 8, 2026

Copy link
Copy Markdown

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)

Screenshot 2026-06-08 174458

@jerry2013 jerry2013 requested review from WesUnwin and rex-iotum June 8, 2026 22:10
@jerry2013 jerry2013 self-assigned this Jun 8, 2026
Copilot AI review requested due to automatic review settings June 8, 2026 22:10

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 allowUnmute for duplicate CallKit unmute actions.
  • Add pendingProgrammaticUnmute to the per-call active call state.
  • Bump plugin version from 2.2.3 to 2.2.4 in plugin.xml and package.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

  • pendingProgrammaticUnmute is set to @YES when 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 secondary performSetMutedCallAction, this flag stays YES and later unmute actions (including UI-initiated ones) will bypass the allowUnmute guard 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.

Comment thread src/ios/CordovaCall.m
[action fulfill];
[self logMessage:@"performSetMutedCallAction: secondary programmatic unmute action fulfilled"];
return;
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

L1145 is the end of if so the rest is else - i don't know what you mean here.

@rex-iotum rex-iotum Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@jerry2013 jerry2013 marked this pull request as draft June 10, 2026 12:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants