diff --git a/android/src/main/java/io/wazo/callkeep/RNCallKeepBackgroundMessagingService.java b/android/src/main/java/io/wazo/callkeep/RNCallKeepBackgroundMessagingService.java index 8770342f..9ca417dd 100644 --- a/android/src/main/java/io/wazo/callkeep/RNCallKeepBackgroundMessagingService.java +++ b/android/src/main/java/io/wazo/callkeep/RNCallKeepBackgroundMessagingService.java @@ -27,7 +27,7 @@ import com.facebook.react.jstasks.HeadlessJsTaskConfig; import static io.wazo.callkeep.RNCallKeepModule.EXTRA_CALLER_NAME; -import static io.wazo.callkeep.RNCallKeepModule.EXTRA_CALL_NUMBER; +import static io.wazo.callkeep.RNCallKeepModule.EXTRA_CALL_IDENTIFIER; import static io.wazo.callkeep.RNCallKeepModule.EXTRA_CALL_UUID; import javax.annotation.Nullable; diff --git a/android/src/main/java/io/wazo/callkeep/RNCallKeepModule.java b/android/src/main/java/io/wazo/callkeep/RNCallKeepModule.java index 124de3ba..ef477cce 100644 --- a/android/src/main/java/io/wazo/callkeep/RNCallKeepModule.java +++ b/android/src/main/java/io/wazo/callkeep/RNCallKeepModule.java @@ -43,6 +43,7 @@ import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; +import android.telecom.VideoProfile; import android.telephony.TelephonyManager; import android.util.Log; @@ -75,7 +76,7 @@ public class RNCallKeepModule extends ReactContextBaseJavaModule { public static final String CHECKING_PERMS = "CHECKING_PERMS"; public static final String EXTRA_CALLER_NAME = "EXTRA_CALLER_NAME"; public static final String EXTRA_CALL_UUID = "EXTRA_CALL_UUID"; - public static final String EXTRA_CALL_NUMBER = "EXTRA_CALL_NUMBER"; + public static final String EXTRA_CALL_IDENTIFIER = "EXTRA_CALL_IDENTIFIER"; public static final String ACTION_END_CALL = "ACTION_END_CALL"; public static final String ACTION_ANSWER_CALL = "ACTION_ANSWER_CALL"; public static final String ACTION_MUTE_CALL = "ACTION_MUTE_CALL"; @@ -127,20 +128,24 @@ public void setup(ReadableMap options) { } @ReactMethod - public void displayIncomingCall(String uuid, String number, String callerName) { + public void displayIncomingCall(String uuid, String identifier, String callerType, boolean callHasVideo, String callerName) { if (!isConnectionServiceAvailable() || !hasPhoneAccount()) { return; } - Log.d(TAG, "displayIncomingCall number: " + number + ", callerName: " + callerName); + Log.d(TAG, "displayIncomingCall identifier: " + identifier + ", callerName: " + callerName + ", callerType: " + callerType + ", callHasVideo: " + callHasVideo); Bundle extras = new Bundle(); - Uri uri = Uri.fromParts(PhoneAccount.SCHEME_TEL, number, null); + Uri uri = Uri.fromParts((callerType.equals("sip") ? PhoneAccount.SCHEME_SIP : PhoneAccount.SCHEME_TEL), identifier, null); extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, uri); extras.putString(EXTRA_CALLER_NAME, callerName); extras.putString(EXTRA_CALL_UUID, uuid); + if (callHasVideo) { + extras.putInt(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, VideoProfile.STATE_BIDIRECTIONAL); + } + telecomManager.addNewIncomingCall(handle, extras); } @@ -159,24 +164,28 @@ public void answerIncomingCall(String uuid) { } @ReactMethod - public void startCall(String uuid, String number, String callerName) { - if (!isConnectionServiceAvailable() || !hasPhoneAccount() || !hasPermissions() || number == null) { + public void startCall(String uuid, String identifer, String callerName, String callerType, boolean callHasVideo) { + if (!isConnectionServiceAvailable() || !hasPhoneAccount() || !hasPermissions() || identifer == null) { return; } - Log.d(TAG, "startCall number: " + number + ", callerName: " + callerName); + Log.d(TAG, "startCall identifer: " + identifer + ", callerName: " + callerName + ", callerType: " + callerType + ", callHasVideo: " + callHasVideo); Bundle extras = new Bundle(); - Uri uri = Uri.fromParts(PhoneAccount.SCHEME_TEL, number, null); + Uri uri = Uri.fromParts((callerType.equals("sip") ? PhoneAccount.SCHEME_SIP : PhoneAccount.SCHEME_TEL), identifer, null); Bundle callExtras = new Bundle(); callExtras.putString(EXTRA_CALLER_NAME, callerName); callExtras.putString(EXTRA_CALL_UUID, uuid); - callExtras.putString(EXTRA_CALL_NUMBER, number); + callExtras.putString(EXTRA_CALL_IDENTIFIER, identifer); extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, handle); extras.putParcelable(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, callExtras); + if (callHasVideo) { + extras.putInt(TelecomManager.EXTRA_INCOMING_VIDEO_STATE, VideoProfile.STATE_BIDIRECTIONAL); + } + telecomManager.placeCall(uri, extras); } @@ -373,7 +382,7 @@ public void setCurrentCallActive(String uuid) { return; } - conn.setConnectionCapabilities(conn.getConnectionCapabilities() | Connection.CAPABILITY_HOLD); + conn.setConnectionCapabilities(conn.getConnectionCapabilities()); conn.setActive(); } @@ -436,7 +445,8 @@ private void registerPhoneAccount(Context appContext) { handle = new PhoneAccountHandle(cName, appName); PhoneAccount.Builder builder = new PhoneAccount.Builder(handle, appName) - .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER); + .addSupportedUriScheme(PhoneAccount.SCHEME_SIP) + .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER | PhoneAccount.CAPABILITY_VIDEO_CALLING); if (_settings != null && _settings.hasKey("imageName")) { int identifier = appContext.getResources().getIdentifier(_settings.getString("imageName"), "drawable", appContext.getPackageName()); @@ -557,7 +567,7 @@ public void onReceive(Context context, Intent intent) { sendEventToJS("RNCallKeepDidPerformDTMFAction", args); break; case ACTION_ONGOING_CALL: - args.putString("handle", attributeMap.get(EXTRA_CALL_NUMBER)); + args.putString("handle", attributeMap.get(EXTRA_CALL_IDENTIFIER)); args.putString("callUUID", attributeMap.get(EXTRA_CALL_UUID)); args.putString("name", attributeMap.get(EXTRA_CALLER_NAME)); sendEventToJS("RNCallKeepDidReceiveStartCallAction", args); diff --git a/android/src/main/java/io/wazo/callkeep/VoiceConnection.java b/android/src/main/java/io/wazo/callkeep/VoiceConnection.java index bb19b369..7c6272b0 100644 --- a/android/src/main/java/io/wazo/callkeep/VoiceConnection.java +++ b/android/src/main/java/io/wazo/callkeep/VoiceConnection.java @@ -46,7 +46,7 @@ import static io.wazo.callkeep.RNCallKeepModule.ACTION_UNHOLD_CALL; import static io.wazo.callkeep.RNCallKeepModule.ACTION_UNMUTE_CALL; import static io.wazo.callkeep.RNCallKeepModule.EXTRA_CALLER_NAME; -import static io.wazo.callkeep.RNCallKeepModule.EXTRA_CALL_NUMBER; +import static io.wazo.callkeep.RNCallKeepModule.EXTRA_CALL_IDENTIFIER; import static io.wazo.callkeep.RNCallKeepModule.EXTRA_CALL_UUID; @TargetApi(Build.VERSION_CODES.M) @@ -61,11 +61,11 @@ public class VoiceConnection extends Connection { this.handle = handle; this.context = context; - String number = handle.get(EXTRA_CALL_NUMBER); + String identifier = handle.get(EXTRA_CALL_IDENTIFIER); String name = handle.get(EXTRA_CALLER_NAME); - if (number != null) { - setAddress(Uri.parse(number), TelecomManager.PRESENTATION_ALLOWED); + if (identifier != null) { + setAddress(Uri.parse(identifier), TelecomManager.PRESENTATION_ALLOWED); } if (name != null && !name.equals("")) { setCallerDisplayName(name, TelecomManager.PRESENTATION_ALLOWED); @@ -96,7 +96,7 @@ public void onAnswer() { super.onAnswer(); Log.d(TAG, "onAnswer called"); - setConnectionCapabilities(getConnectionCapabilities() | Connection.CAPABILITY_HOLD); + setConnectionCapabilities(getConnectionCapabilities()); setAudioModeIsVoip(true); sendCallRequestToActivity(ACTION_ANSWER_CALL, handle); diff --git a/android/src/main/java/io/wazo/callkeep/VoiceConnectionService.java b/android/src/main/java/io/wazo/callkeep/VoiceConnectionService.java index f6480da7..3ab7af7e 100644 --- a/android/src/main/java/io/wazo/callkeep/VoiceConnectionService.java +++ b/android/src/main/java/io/wazo/callkeep/VoiceConnectionService.java @@ -64,7 +64,7 @@ import static io.wazo.callkeep.RNCallKeepModule.ACTION_UNMUTE_CALL; import static io.wazo.callkeep.RNCallKeepModule.ACTION_CHECK_REACHABILITY; import static io.wazo.callkeep.RNCallKeepModule.EXTRA_CALLER_NAME; -import static io.wazo.callkeep.RNCallKeepModule.EXTRA_CALL_NUMBER; +import static io.wazo.callkeep.RNCallKeepModule.EXTRA_CALL_IDENTIFIER; import static io.wazo.callkeep.RNCallKeepModule.EXTRA_CALL_UUID; import static io.wazo.callkeep.RNCallKeepModule.handle; @@ -125,7 +125,7 @@ public static void deinitConnection(String connectionId) { @Override public Connection onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) { Bundle extra = request.getExtras(); - Uri number = request.getAddress(); + Uri identifier = request.getAddress(); String name = extra.getString(EXTRA_CALLER_NAME); Connection incomingCallConnection = createConnection(request); incomingCallConnection.setRinging(); @@ -151,27 +151,27 @@ public Connection onCreateOutgoingConnection(PhoneAccountHandle connectionManage private Connection makeOutgoingCall(ConnectionRequest request, String uuid, Boolean forceWakeUp) { Bundle extras = request.getExtras(); Connection outgoingCallConnection = null; - String number = request.getAddress().getSchemeSpecificPart(); - String extrasNumber = extras.getString(EXTRA_CALL_NUMBER); + String identifier = request.getAddress().getSchemeSpecificPart(); + String extrasIdentifier = extras.getString(EXTRA_CALL_IDENTIFIER); String displayName = extras.getString(EXTRA_CALLER_NAME); Boolean isForeground = VoiceConnectionService.isRunning(this.getApplicationContext()); - Log.d(TAG, "makeOutgoingCall:" + uuid + ", number: " + number + ", displayName:" + displayName); + Log.d(TAG, "makeOutgoingCall:" + uuid + ", identifier: " + identifier + ", displayName:" + displayName); // Wakeup application if needed if (!isForeground || forceWakeUp) { Log.d(TAG, "onCreateOutgoingConnection: Waking up application"); - this.wakeUpApplication(uuid, number, displayName); + this.wakeUpApplication(uuid, identifier, displayName); } else if (!this.canMakeOutgoingCall() && isReachable) { Log.d(TAG, "onCreateOutgoingConnection: not available"); return Connection.createFailedConnection(new DisconnectCause(DisconnectCause.LOCAL)); } // TODO: Hold all other calls - if (extrasNumber == null || !extrasNumber.equals(number)) { + if (extrasIdentifier == null || !extrasIdentifier.equals(identifier)) { extras.putString(EXTRA_CALL_UUID, uuid); extras.putString(EXTRA_CALLER_NAME, displayName); - extras.putString(EXTRA_CALL_NUMBER, number); + extras.putString(EXTRA_CALL_IDENTIFIER, identifier); } outgoingCallConnection = createConnection(request); @@ -195,15 +195,15 @@ private Connection makeOutgoingCall(ConnectionRequest request, String uuid, Bool return outgoingCallConnection; } - private void wakeUpApplication(String uuid, String number, String displayName) { + private void wakeUpApplication(String uuid, String identifier, String displayName) { Intent headlessIntent = new Intent( this.getApplicationContext(), RNCallKeepBackgroundMessagingService.class ); headlessIntent.putExtra("callUUID", uuid); headlessIntent.putExtra("name", displayName); - headlessIntent.putExtra("handle", number); - Log.d(TAG, "wakeUpApplication: " + uuid + ", number : " + number + ", displayName:" + displayName); + headlessIntent.putExtra("handle", identifier); + Log.d(TAG, "wakeUpApplication: " + uuid + ", identifier : " + identifier + ", displayName:" + displayName); ComponentName name = this.getApplicationContext().startService(headlessIntent); if (name != null) { @@ -217,9 +217,9 @@ private void wakeUpAfterReachabilityTimeout(ConnectionRequest request) { } Log.d(TAG, "checkReachability timeout, force wakeup"); Bundle extras = request.getExtras(); - String number = request.getAddress().getSchemeSpecificPart(); + String identifier = request.getAddress().getSchemeSpecificPart(); String displayName = extras.getString(EXTRA_CALLER_NAME); - wakeUpApplication(this.notReachableCallUuid, number, displayName); + wakeUpApplication(this.notReachableCallUuid, identifier, displayName); VoiceConnectionService.currentConnectionRequest = null; } @@ -245,9 +245,9 @@ private Boolean canMakeOutgoingCall() { private Connection createConnection(ConnectionRequest request) { Bundle extras = request.getExtras(); HashMap extrasMap = this.bundleToMap(extras); - extrasMap.put(EXTRA_CALL_NUMBER, request.getAddress().toString()); + extrasMap.put(EXTRA_CALL_IDENTIFIER, request.getAddress().toString()); VoiceConnection connection = new VoiceConnection(this, extrasMap); - connection.setConnectionCapabilities(Connection.CAPABILITY_MUTE | Connection.CAPABILITY_SUPPORT_HOLD); + connection.setConnectionCapabilities(Connection.CAPABILITY_MUTE); connection.setInitializing(); connection.setExtras(extras); currentConnections.put(extras.getString(EXTRA_CALL_UUID), connection); diff --git a/index.js b/index.js index b09c0477..6d886998 100644 --- a/index.js +++ b/index.js @@ -58,7 +58,7 @@ class RNCallKeep { displayIncomingCall = (uuid, handle, localizedCallerName = '', handleType = 'number', hasVideo = false) => { if (!isIOS) { - RNCallKeepModule.displayIncomingCall(uuid, handle, localizedCallerName); + RNCallKeepModule.displayIncomingCall(uuid, handle, handleType, hasVideo, localizedCallerName); return; } @@ -73,7 +73,7 @@ class RNCallKeep { startCall = (uuid, handle, contactIdentifier, handleType = 'number', hasVideo = false ) => { if (!isIOS) { - RNCallKeepModule.startCall(uuid, handle, contactIdentifier); + RNCallKeepModule.startCall(uuid, handle, contactIdentifier, handleType, hasVideo); return; } diff --git a/ios/RNCallKeep/RNCallKeep.m b/ios/RNCallKeep/RNCallKeep.m index 1be3df24..f3e9114b 100644 --- a/ios/RNCallKeep/RNCallKeep.m +++ b/ios/RNCallKeep/RNCallKeep.m @@ -240,7 +240,7 @@ + (void)initCallKitProvider { NSLog(@"[RNCallKeep][updateDisplay] uuidString = %@ displayName = %@ uri = %@", uuidString, displayName, uri); #endif NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:uuidString]; - CXHandle *callHandle = [[CXHandle alloc] initWithType:CXHandleTypePhoneNumber value:uri]; + CXHandle *callHandle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:uri]; CXCallUpdate *callUpdate = [[CXCallUpdate alloc] init]; callUpdate.localizedCallerName = displayName; callUpdate.remoteHandle = callHandle; @@ -462,7 +462,7 @@ + (CXProviderConfiguration *)getProviderConfiguration:(NSDictionary*)settings int _handleType = [RNCallKeep getHandleType:settings[@"handleType"]]; providerConfiguration.supportedHandleTypes = [NSSet setWithObjects:[NSNumber numberWithInteger:_handleType], nil]; }else{ - providerConfiguration.supportedHandleTypes = [NSSet setWithObjects:[NSNumber numberWithInteger:CXHandleTypePhoneNumber], nil]; + providerConfiguration.supportedHandleTypes = [NSSet setWithObjects:[NSNumber numberWithInteger:CXHandleTypeGeneric], nil]; } if (settings[@"supportsVideo"]) { providerConfiguration.supportsVideo = [settings[@"supportsVideo"] boolValue];