Skip to content
Open
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cordova-plugin-callkit",
"version": "2.2.2",
"version": "2.2.3",
"description": "Cordova plugin that lets you use iOS CallKit UI (with PushKit) and Android ConnectionService UI",
"cordova": {
"id": "cordova-plugin-callkit",
Expand Down
2 changes: 1 addition & 1 deletion plugin.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<plugin id="cordova-plugin-callkit" version="2.2.2" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<plugin id="cordova-plugin-callkit" version="2.2.3" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<name>Cordova CallKit</name>

<js-module name="VoIPPushNotification" src="www/VoIPPushNotification.js">
Expand Down
3 changes: 3 additions & 0 deletions src/android/CordovaCall.java
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,9 @@ public void run() {
this.unmute();
this.callbackContext.success("Unmuted Successfully");
return true;
} else if (action.equals("setAllowUnmute")) {
this.callbackContext.error("setAllowUnmute is not supported on Android");
return true;
Comment thread
jerry2013 marked this conversation as resolved.
Comment thread
jerry2013 marked this conversation as resolved.
Comment thread
jerry2013 marked this conversation as resolved.
} else if (action.equals("speakerOn")) {
this.speakerOn();
return true;
Expand Down
1 change: 1 addition & 0 deletions src/ios/CordovaCall.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
- (void)setRingtone:(CDVInvokedUrlCommand*)command;
- (void)setIncludeInRecents:(CDVInvokedUrlCommand*)command;
- (void)setDTMFState:(CDVInvokedUrlCommand*)command;
- (void)setAllowUnmute:(CDVInvokedUrlCommand*)command;
- (void)setVideo:(CDVInvokedUrlCommand*)command;

- (void)receiveCall:(CDVInvokedUrlCommand*)command;
Expand Down
51 changes: 42 additions & 9 deletions src/ios/CordovaCall.m
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,20 @@ - (void)setDTMFState:(CDVInvokedUrlCommand*)command
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}

- (void)setAllowUnmute:(CDVInvokedUrlCommand*)command
{
NSString *sessionId = [command.arguments objectAtIndex:0];
BOOL value = [[command.arguments objectAtIndex:1] boolValue];
CDVPluginResult *pluginResult = nil;
if (self.activeCalls[sessionId]) {
self.activeCalls[sessionId][@"allowUnmute"] = @(value);
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"allowUnmute Changed Successfully"];
} else {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No active call for sessionId"];
}
Comment thread
jerry2013 marked this conversation as resolved.
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}

- (void)setVideo:(CDVInvokedUrlCommand*)command
{
CDVPluginResult* pluginResult = nil;
Expand Down Expand Up @@ -512,10 +526,13 @@ - (void)mute:(CDVInvokedUrlCommand*)command
CXSetMutedCallAction *muteAction = [[CXSetMutedCallAction alloc] initWithCallUUID:call.UUID muted:YES];
CXTransaction *transaction = [[CXTransaction alloc] initWithAction:muteAction];
[self logMessage:[NSString stringWithFormat:@"Programmatically Muting Call: %@", sessionId]];
// Pre-populate callbackMap before requestTransaction: performSetMutedCallAction fires
// before the requestTransaction completion block, so the entry must already be present.
self.activeCalls[sessionId][@"callbackMap"][muteAction.UUID.UUIDString] = [@{ @"callbackId": command.callbackId, @"event": @"mute" } mutableCopy];
[self.callController requestTransaction:transaction completion:^(NSError * _Nullable error) {
if (error == nil) {
self.activeCalls[sessionId][@"callbackMap"][muteAction.UUID.UUIDString] = [@{ @"callbackId": command.callbackId, @"event": @"mute" } mutableCopy];
} else {
if (error != nil) {
// Transaction was rejected before reaching performSetMutedCallAction — clean up.
[self.activeCalls[sessionId][@"callbackMap"] removeObjectForKey:muteAction.UUID.UUIDString];
[self logMessage:@"Error occurred muting Call"];
NSDictionary *resultDict = @{ @"message": @"An error occurred", @"sessionId": sessionId };
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:resultDict];
Expand All @@ -538,10 +555,13 @@ - (void)unmute:(CDVInvokedUrlCommand*)command
CXSetMutedCallAction *unmuteAction = [[CXSetMutedCallAction alloc] initWithCallUUID:call.UUID muted:NO];
CXTransaction *transaction = [[CXTransaction alloc] initWithAction:unmuteAction];
[self logMessage:[NSString stringWithFormat:@"Programmatically Unmuting Call: %@", sessionId]];
// Pre-populate callbackMap before requestTransaction: performSetMutedCallAction fires
// before the requestTransaction completion block, so the entry must already be present.
self.activeCalls[sessionId][@"callbackMap"][unmuteAction.UUID.UUIDString] = [@{ @"callbackId": command.callbackId, @"event": @"unmute" } mutableCopy];
[self.callController requestTransaction:transaction completion:^(NSError * _Nullable error) {
if (error == nil) {
self.activeCalls[sessionId][@"callbackMap"][unmuteAction.UUID.UUIDString] = [@{ @"callbackId": command.callbackId, @"event": @"unmute" } mutableCopy];
} else {
if (error != nil) {
// Transaction was rejected before reaching performSetMutedCallAction — clean up.
[self.activeCalls[sessionId][@"callbackMap"] removeObjectForKey:unmuteAction.UUID.UUIDString];
[self logMessage:@"Error occurred unmuting Call"];
NSDictionary *resultDict = @{ @"message": @"An error occurred", @"sessionId": sessionId };
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:resultDict];
Expand Down Expand Up @@ -1113,12 +1133,24 @@ - (void)provider:(CXProvider *)provider performSetMutedCallAction:(CXSetMutedCal
}
[self logMessage:[NSString stringWithFormat:@"CallKit performSetMutedCallAction received %@ event, sessionId: %@", isMuted ? @"mute" : @"unmute", sessionId]];

[action fulfill];

if (self.activeCalls[sessionId][@"callbackMap"][action.UUID.UUIDString]) {
[action fulfill];

// Programmatic mute/unmute: resolve the JS promise only.
[self resolveCommandForSessionId:sessionId actionUUIDString:action.UUID.UUIDString];
return;
}

BOOL allowUnmute = [self.activeCalls[sessionId][@"allowUnmute"] boolValue];
if (!isMuted && !allowUnmute) {
// If this is an unmute request and allowUnmute is NO for this session, fail the action.
[action fail];

[self logMessage:@"performSetMutedCallAction: allowUnmute is NO, reject unmute action"];
return;
} else {
[action fulfill];

// UI-initiated mute/unmute: emit to event listeners only.
for (id callbackId in callbackIds[isMuted ? @"mute" : @"unmute"]) {
[self logMessage:[NSString stringWithFormat:@"Sending %@ event to JS", isMuted ? @"mute" : @"unmute"]];
Expand Down Expand Up @@ -1224,7 +1256,8 @@ - (NSMutableDictionary *)newActiveCallEntryWithUUID:(NSUUID *)callUUID {
@"callbackMap": [NSMutableDictionary dictionary],
@"pendingActivateAudioSessionEmits": [NSMutableArray array],
@"pendingDeactivateAudioSessionEmits": [NSMutableArray array],
@"pendingDismiss": @NO
@"pendingDismiss": @NO,
@"allowUnmute": @YES
} mutableCopy];
}

Expand Down
14 changes: 11 additions & 3 deletions www/CordovaCall.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,23 @@ exports.setIncludeInRecents = function (value, success, error) {
if (typeof value == "boolean") {
exec(success, error, "CordovaCall", "setIncludeInRecents", [value]);
} else {
error("Value Must Be True Or False");
if (typeof error == "function") { error("Value Must Be True Or False"); }
}
};

exports.setDTMFState = function (value, success, error) {
if (typeof value == "boolean") {
exec(success, error, "CordovaCall", "setDTMFState", [value]);
} else {
error("Value Must Be True Or False");
if (typeof error == "function") { error("Value Must Be True Or False"); }
}
};

exports.setVideo = function (value, success, error) {
if (typeof value == "boolean") {
exec(success, error, "CordovaCall", "setVideo", [value]);
} else {
error("Value Must Be True Or False");
if (typeof error == "function") { error("Value Must Be True Or False"); }
}
};

Expand Down Expand Up @@ -154,6 +154,14 @@ exports.log = function (message) {
exec(null, null, "CordovaCall", "log", [message]);
}

exports.setAllowUnmute = function (sessionId, value, success, error) {
if (typeof value == "boolean") {
exec(success, error, "CordovaCall", "setAllowUnmute", [sessionId, value]);
} else {
if (typeof error == "function") { error("Value Must Be True Or False"); }
}
};

exports.keepAlive = function (callback) {
exec(callback, null, "CordovaCall", "keepAlive", []);
}
Expand Down