voice-react-native-sdk 1.6.2-fork.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +206 -0
- package/README.md +179 -0
- package/android/build.gradle +113 -0
- package/android/gradle.properties +29 -0
- package/android/src/main/AndroidManifest.xml +30 -0
- package/android/src/main/java/com/twiliovoicereactnative/AudioSwitchManager.java +141 -0
- package/android/src/main/java/com/twiliovoicereactnative/CallListenerProxy.java +186 -0
- package/android/src/main/java/com/twiliovoicereactnative/CallMessageListenerProxy.java +103 -0
- package/android/src/main/java/com/twiliovoicereactnative/CallRecordDatabase.java +183 -0
- package/android/src/main/java/com/twiliovoicereactnative/CommonConstants.java +195 -0
- package/android/src/main/java/com/twiliovoicereactnative/ConfigurationProperties.java +41 -0
- package/android/src/main/java/com/twiliovoicereactnative/Constants.java +23 -0
- package/android/src/main/java/com/twiliovoicereactnative/ExpoActivityLifecycleListener.java +27 -0
- package/android/src/main/java/com/twiliovoicereactnative/ExpoApplicationLifecycleListener.java +14 -0
- package/android/src/main/java/com/twiliovoicereactnative/ExpoModule.kt +36 -0
- package/android/src/main/java/com/twiliovoicereactnative/ExpoPackage.java +20 -0
- package/android/src/main/java/com/twiliovoicereactnative/JSEventEmitter.java +98 -0
- package/android/src/main/java/com/twiliovoicereactnative/MediaPlayerManager.java +58 -0
- package/android/src/main/java/com/twiliovoicereactnative/NotificationUtility.java +363 -0
- package/android/src/main/java/com/twiliovoicereactnative/ReactNativeArgumentsSerializer.java +276 -0
- package/android/src/main/java/com/twiliovoicereactnative/SDKLog.java +74 -0
- package/android/src/main/java/com/twiliovoicereactnative/StatsListenerProxy.java +178 -0
- package/android/src/main/java/com/twiliovoicereactnative/TwilioVoiceReactNativeModule.java +778 -0
- package/android/src/main/java/com/twiliovoicereactnative/TwilioVoiceReactNativePackage.java +28 -0
- package/android/src/main/java/com/twiliovoicereactnative/VoiceActivityProxy.java +101 -0
- package/android/src/main/java/com/twiliovoicereactnative/VoiceApplicationProxy.java +133 -0
- package/android/src/main/java/com/twiliovoicereactnative/VoiceFirebaseMessagingService.java +88 -0
- package/android/src/main/java/com/twiliovoicereactnative/VoiceService.java +403 -0
- package/android/src/main/res/drawable/answered_call_small_icon.png +0 -0
- package/android/src/main/res/drawable/ic_launcher_round.png +0 -0
- package/android/src/main/res/drawable/ic_launcher_sdk.png +0 -0
- package/android/src/main/res/drawable/incoming_call_small_icon.png +0 -0
- package/android/src/main/res/drawable/outgoing_call_small_icon.png +0 -0
- package/android/src/main/res/raw/disconnect.wav +0 -0
- package/android/src/main/res/raw/incoming.wav +0 -0
- package/android/src/main/res/raw/outgoing.wav +0 -0
- package/android/src/main/res/raw/ringtone.wav +0 -0
- package/android/src/main/res/raw/silent.wav +0 -0
- package/android/src/main/res/values/colors.xml +11 -0
- package/android/src/main/res/values/config.xml +5 -0
- package/android/src/main/res/values/dimens.xml +7 -0
- package/android/src/main/res/values/strings.xml +25 -0
- package/android/src/main/res/values/styles.xml +10 -0
- package/android/src/main/res/values-night/colors.xml +11 -0
- package/expo-config-plugin/android.js +191 -0
- package/expo-config-plugin/ios.js +22 -0
- package/expo-module.config.json +6 -0
- package/ios/TwilioVoicePushRegistry.h +19 -0
- package/ios/TwilioVoicePushRegistry.m +72 -0
- package/ios/TwilioVoiceReactNative+CallInvite.m +56 -0
- package/ios/TwilioVoiceReactNative+CallKit.m +533 -0
- package/ios/TwilioVoiceReactNative+CallMessage.m +81 -0
- package/ios/TwilioVoiceReactNative.h +74 -0
- package/ios/TwilioVoiceReactNative.m +1046 -0
- package/ios/TwilioVoiceReactNative.xcodeproj/project.pbxproj +328 -0
- package/ios/TwilioVoiceReactNativeConstants.h +200 -0
- package/ios/Utilities/TwilioVoiceStatsReport.h +175 -0
- package/lib/commonjs/AudioDevice.js +101 -0
- package/lib/commonjs/AudioDevice.js.map +1 -0
- package/lib/commonjs/Call.js +765 -0
- package/lib/commonjs/Call.js.map +1 -0
- package/lib/commonjs/CallInvite.js +452 -0
- package/lib/commonjs/CallInvite.js.map +1 -0
- package/lib/commonjs/CallMessage/CallMessage.js +54 -0
- package/lib/commonjs/CallMessage/CallMessage.js.map +1 -0
- package/lib/commonjs/CallMessage/IncomingCallMessage.js +120 -0
- package/lib/commonjs/CallMessage/IncomingCallMessage.js.map +1 -0
- package/lib/commonjs/CallMessage/OutgoingCallMessage.js +148 -0
- package/lib/commonjs/CallMessage/OutgoingCallMessage.js.map +1 -0
- package/lib/commonjs/ExpoModule.js +69 -0
- package/lib/commonjs/ExpoModule.js.map +1 -0
- package/lib/commonjs/Voice.js +611 -0
- package/lib/commonjs/Voice.js.map +1 -0
- package/lib/commonjs/common.js +26 -0
- package/lib/commonjs/common.js.map +1 -0
- package/lib/commonjs/constants.js +158 -0
- package/lib/commonjs/constants.js.map +1 -0
- package/lib/commonjs/error/InvalidArgumentError.js +32 -0
- package/lib/commonjs/error/InvalidArgumentError.js.map +1 -0
- package/lib/commonjs/error/InvalidStateError.js +33 -0
- package/lib/commonjs/error/InvalidStateError.js.map +1 -0
- package/lib/commonjs/error/TwilioError.js +38 -0
- package/lib/commonjs/error/TwilioError.js.map +1 -0
- package/lib/commonjs/error/UnsupportedPlatformError.js +33 -0
- package/lib/commonjs/error/UnsupportedPlatformError.js.map +1 -0
- package/lib/commonjs/error/generated.js +2343 -0
- package/lib/commonjs/error/generated.js.map +1 -0
- package/lib/commonjs/error/index.js +112 -0
- package/lib/commonjs/error/index.js.map +1 -0
- package/lib/commonjs/error/utility.js +37 -0
- package/lib/commonjs/error/utility.js.map +1 -0
- package/lib/commonjs/index.js +95 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/type/AudioDevice.js +6 -0
- package/lib/commonjs/type/AudioDevice.js.map +1 -0
- package/lib/commonjs/type/Call.js +6 -0
- package/lib/commonjs/type/Call.js.map +1 -0
- package/lib/commonjs/type/CallInvite.js +6 -0
- package/lib/commonjs/type/CallInvite.js.map +1 -0
- package/lib/commonjs/type/CallKit.js +30 -0
- package/lib/commonjs/type/CallKit.js.map +1 -0
- package/lib/commonjs/type/CallMessage.js +6 -0
- package/lib/commonjs/type/CallMessage.js.map +1 -0
- package/lib/commonjs/type/Error.js +6 -0
- package/lib/commonjs/type/Error.js.map +1 -0
- package/lib/commonjs/type/NativeModule.js +6 -0
- package/lib/commonjs/type/NativeModule.js.map +1 -0
- package/lib/commonjs/type/RTCStats.js +29 -0
- package/lib/commonjs/type/RTCStats.js.map +1 -0
- package/lib/commonjs/type/Voice.js +6 -0
- package/lib/commonjs/type/Voice.js.map +1 -0
- package/lib/commonjs/type/common.js +2 -0
- package/lib/commonjs/type/common.js.map +1 -0
- package/lib/module/AudioDevice.js +97 -0
- package/lib/module/AudioDevice.js.map +1 -0
- package/lib/module/Call.js +766 -0
- package/lib/module/Call.js.map +1 -0
- package/lib/module/CallInvite.js +450 -0
- package/lib/module/CallInvite.js.map +1 -0
- package/lib/module/CallMessage/CallMessage.js +51 -0
- package/lib/module/CallMessage/CallMessage.js.map +1 -0
- package/lib/module/CallMessage/IncomingCallMessage.js +116 -0
- package/lib/module/CallMessage/IncomingCallMessage.js.map +1 -0
- package/lib/module/CallMessage/OutgoingCallMessage.js +154 -0
- package/lib/module/CallMessage/OutgoingCallMessage.js.map +1 -0
- package/lib/module/ExpoModule.js +58 -0
- package/lib/module/ExpoModule.js.map +1 -0
- package/lib/module/Voice.js +598 -0
- package/lib/module/Voice.js.map +1 -0
- package/lib/module/common.js +11 -0
- package/lib/module/common.js.map +1 -0
- package/lib/module/constants.js +151 -0
- package/lib/module/constants.js.map +1 -0
- package/lib/module/error/InvalidArgumentError.js +23 -0
- package/lib/module/error/InvalidArgumentError.js.map +1 -0
- package/lib/module/error/InvalidStateError.js +24 -0
- package/lib/module/error/InvalidStateError.js.map +1 -0
- package/lib/module/error/TwilioError.js +29 -0
- package/lib/module/error/TwilioError.js.map +1 -0
- package/lib/module/error/UnsupportedPlatformError.js +24 -0
- package/lib/module/error/UnsupportedPlatformError.js.map +1 -0
- package/lib/module/error/generated.js +2315 -0
- package/lib/module/error/generated.js.map +1 -0
- package/lib/module/error/index.js +6 -0
- package/lib/module/error/index.js.map +1 -0
- package/lib/module/error/utility.js +27 -0
- package/lib/module/error/utility.js.map +1 -0
- package/lib/module/index.js +23 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/type/AudioDevice.js +2 -0
- package/lib/module/type/AudioDevice.js.map +1 -0
- package/lib/module/type/Call.js +2 -0
- package/lib/module/type/Call.js.map +1 -0
- package/lib/module/type/CallInvite.js +2 -0
- package/lib/module/type/CallInvite.js.map +1 -0
- package/lib/module/type/CallKit.js +22 -0
- package/lib/module/type/CallKit.js.map +1 -0
- package/lib/module/type/CallMessage.js +2 -0
- package/lib/module/type/CallMessage.js.map +1 -0
- package/lib/module/type/Error.js +2 -0
- package/lib/module/type/Error.js.map +1 -0
- package/lib/module/type/NativeModule.js +2 -0
- package/lib/module/type/NativeModule.js.map +1 -0
- package/lib/module/type/RTCStats.js +21 -0
- package/lib/module/type/RTCStats.js.map +1 -0
- package/lib/module/type/Voice.js +2 -0
- package/lib/module/type/Voice.js.map +1 -0
- package/lib/module/type/common.js +2 -0
- package/lib/module/type/common.js.map +1 -0
- package/lib/typescript/AudioDevice.d.ts +74 -0
- package/lib/typescript/Call.d.ts +874 -0
- package/lib/typescript/CallInvite.d.ts +484 -0
- package/lib/typescript/CallMessage/CallMessage.d.ts +53 -0
- package/lib/typescript/CallMessage/IncomingCallMessage.d.ts +75 -0
- package/lib/typescript/CallMessage/OutgoingCallMessage.d.ts +198 -0
- package/lib/typescript/ExpoModule.d.ts +13 -0
- package/lib/typescript/Voice.d.ts +620 -0
- package/lib/typescript/common.d.ts +11 -0
- package/lib/typescript/constants.d.ts +148 -0
- package/lib/typescript/error/InvalidArgumentError.d.ts +11 -0
- package/lib/typescript/error/InvalidStateError.d.ts +12 -0
- package/lib/typescript/error/TwilioError.d.ts +14 -0
- package/lib/typescript/error/UnsupportedPlatformError.d.ts +12 -0
- package/lib/typescript/error/generated.d.ts +1558 -0
- package/lib/typescript/error/index.d.ts +5 -0
- package/lib/typescript/error/utility.d.ts +12 -0
- package/lib/typescript/index.d.ts +18 -0
- package/lib/typescript/type/AudioDevice.d.ts +15 -0
- package/lib/typescript/type/Call.d.ts +59 -0
- package/lib/typescript/type/CallInvite.d.ts +40 -0
- package/lib/typescript/type/CallKit.d.ts +60 -0
- package/lib/typescript/type/CallMessage.d.ts +20 -0
- package/lib/typescript/type/Error.d.ts +9 -0
- package/lib/typescript/type/NativeModule.d.ts +59 -0
- package/lib/typescript/type/RTCStats.d.ts +91 -0
- package/lib/typescript/type/Voice.d.ts +16 -0
- package/lib/typescript/type/common.d.ts +15 -0
- package/package.json +167 -0
- package/src/AudioDevice.tsx +88 -0
- package/src/Call.tsx +1343 -0
- package/src/CallInvite.tsx +757 -0
- package/src/CallMessage/CallMessage.ts +83 -0
- package/src/CallMessage/IncomingCallMessage.ts +104 -0
- package/src/CallMessage/OutgoingCallMessage.ts +308 -0
- package/src/ExpoModule.ts +59 -0
- package/src/Voice.tsx +1010 -0
- package/src/common.ts +16 -0
- package/src/constants.ts +193 -0
- package/src/error/InvalidArgumentError.ts +19 -0
- package/src/error/InvalidStateError.ts +19 -0
- package/src/error/TwilioError.ts +22 -0
- package/src/error/UnsupportedPlatformError.ts +19 -0
- package/src/error/generated.ts +2277 -0
- package/src/error/index.ts +18 -0
- package/src/error/utility.ts +36 -0
- package/src/index.tsx +24 -0
- package/src/type/AudioDevice.ts +18 -0
- package/src/type/Call.ts +102 -0
- package/src/type/CallInvite.ts +59 -0
- package/src/type/CallKit.ts +61 -0
- package/src/type/CallMessage.ts +31 -0
- package/src/type/Error.ts +11 -0
- package/src/type/NativeModule.ts +93 -0
- package/src/type/RTCStats.ts +99 -0
- package/src/type/Voice.ts +31 -0
- package/src/type/common.ts +16 -0
- package/twilio-voice-react-native.podspec +22 -0
|
@@ -0,0 +1,778 @@
|
|
|
1
|
+
package com.twiliovoicereactnative;
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.NonNull;
|
|
4
|
+
import androidx.core.app.NotificationManagerCompat;
|
|
5
|
+
|
|
6
|
+
import com.facebook.react.bridge.Arguments;
|
|
7
|
+
import com.facebook.react.bridge.Promise;
|
|
8
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
9
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
10
|
+
import com.facebook.react.bridge.ReactMethod;
|
|
11
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
12
|
+
import com.facebook.react.bridge.ReadableMapKeySetIterator;
|
|
13
|
+
import com.facebook.react.bridge.ReadableType;
|
|
14
|
+
import com.facebook.react.bridge.WritableArray;
|
|
15
|
+
import com.facebook.react.bridge.WritableMap;
|
|
16
|
+
import com.facebook.react.module.annotations.ReactModule;
|
|
17
|
+
import com.google.firebase.messaging.FirebaseMessaging;
|
|
18
|
+
import com.twilio.audioswitch.AudioDevice;
|
|
19
|
+
import com.twilio.voice.Call;
|
|
20
|
+
import com.twilio.voice.CallMessage;
|
|
21
|
+
import com.twilio.voice.ConnectOptions;
|
|
22
|
+
import com.twilio.voice.LogLevel;
|
|
23
|
+
import com.twilio.voice.RegistrationException;
|
|
24
|
+
import com.twilio.voice.RegistrationListener;
|
|
25
|
+
import com.twilio.voice.UnregistrationListener;
|
|
26
|
+
import com.twilio.voice.Voice;
|
|
27
|
+
|
|
28
|
+
import java.util.HashMap;
|
|
29
|
+
import java.util.Map;
|
|
30
|
+
import java.util.UUID;
|
|
31
|
+
|
|
32
|
+
import static com.twiliovoicereactnative.CommonConstants.ReactNativeVoiceSDK;
|
|
33
|
+
import static com.twiliovoicereactnative.CommonConstants.ReactNativeVoiceSDKVer;
|
|
34
|
+
import static com.twiliovoicereactnative.CommonConstants.VoiceEventType;
|
|
35
|
+
import static com.twiliovoicereactnative.CommonConstants.VoiceErrorKeyError;
|
|
36
|
+
import static com.twiliovoicereactnative.CommonConstants.ScopeVoice;
|
|
37
|
+
import static com.twiliovoicereactnative.CommonConstants.VoiceEventAudioDevicesUpdated;
|
|
38
|
+
import static com.twiliovoicereactnative.CommonConstants.VoiceEventError;
|
|
39
|
+
import static com.twiliovoicereactnative.CommonConstants.VoiceEventRegistered;
|
|
40
|
+
import static com.twiliovoicereactnative.CommonConstants.VoiceEventUnregistered;
|
|
41
|
+
import static com.twiliovoicereactnative.ConfigurationProperties.isFullScreenNotificationEnabled;
|
|
42
|
+
import static com.twiliovoicereactnative.JSEventEmitter.constructJSMap;
|
|
43
|
+
import static com.twiliovoicereactnative.ReactNativeArgumentsSerializer.serializeCall;
|
|
44
|
+
import static com.twiliovoicereactnative.ReactNativeArgumentsSerializer.serializeCallInvite;
|
|
45
|
+
import static com.twiliovoicereactnative.VoiceApplicationProxy.getCallRecordDatabase;
|
|
46
|
+
import static com.twiliovoicereactnative.VoiceApplicationProxy.getJSEventEmitter;
|
|
47
|
+
import static com.twiliovoicereactnative.VoiceApplicationProxy.getVoiceServiceApi;
|
|
48
|
+
import static com.twiliovoicereactnative.ReactNativeArgumentsSerializer.*;
|
|
49
|
+
|
|
50
|
+
import android.annotation.SuppressLint;
|
|
51
|
+
import android.content.Intent;
|
|
52
|
+
import android.net.Uri;
|
|
53
|
+
import android.os.Build;
|
|
54
|
+
import android.os.Handler;
|
|
55
|
+
import android.os.Looper;
|
|
56
|
+
import android.provider.Settings;
|
|
57
|
+
import android.util.Pair;
|
|
58
|
+
|
|
59
|
+
import com.twiliovoicereactnative.CallRecordDatabase.CallRecord;
|
|
60
|
+
|
|
61
|
+
@ReactModule(name = TwilioVoiceReactNativeModule.TAG)
|
|
62
|
+
public class TwilioVoiceReactNativeModule extends ReactContextBaseJavaModule {
|
|
63
|
+
static final String TAG = "TwilioVoiceReactNative";
|
|
64
|
+
|
|
65
|
+
private static final SDKLog logger = new SDKLog(TwilioVoiceReactNativeModule.class);
|
|
66
|
+
private static final String GLOBAL_ENV = "com.twilio.voice.env";
|
|
67
|
+
private static final String SDK_VERSION = "com.twilio.voice.env.sdk.version";
|
|
68
|
+
private final Handler mainHandler = new Handler(Looper.getMainLooper());
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Map of common constant score strings to the Call.Score enum.
|
|
72
|
+
*/
|
|
73
|
+
private static final Map<String, Call.Score> scoreMap = Map.of(
|
|
74
|
+
CommonConstants.CallFeedbackScoreNotReported, Call.Score.NOT_REPORTED,
|
|
75
|
+
CommonConstants.CallFeedbackScoreOne, Call.Score.ONE,
|
|
76
|
+
CommonConstants.CallFeedbackScoreTwo, Call.Score.TWO,
|
|
77
|
+
CommonConstants.CallFeedbackScoreThree, Call.Score.THREE,
|
|
78
|
+
CommonConstants.CallFeedbackScoreFour, Call.Score.FOUR,
|
|
79
|
+
CommonConstants.CallFeedbackScoreFive, Call.Score.FIVE
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Map of common constant issue strings to the Call.Issue enum.
|
|
84
|
+
*/
|
|
85
|
+
private static final Map<String, Call.Issue> issueMap = Map.of(
|
|
86
|
+
CommonConstants.CallFeedbackIssueAudioLatency, Call.Issue.AUDIO_LATENCY,
|
|
87
|
+
CommonConstants.CallFeedbackIssueChoppyAudio, Call.Issue.CHOPPY_AUDIO,
|
|
88
|
+
CommonConstants.CallFeedbackIssueEcho, Call.Issue.ECHO,
|
|
89
|
+
CommonConstants.CallFeedbackIssueDroppedCall, Call.Issue.DROPPED_CALL,
|
|
90
|
+
CommonConstants.CallFeedbackIssueNoisyCall, Call.Issue.NOISY_CALL,
|
|
91
|
+
CommonConstants.CallFeedbackIssueNotReported, Call.Issue.NOT_REPORTED,
|
|
92
|
+
CommonConstants.CallFeedbackIssueOneWayAudio, Call.Issue.ONE_WAY_AUDIO
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
private final ReactApplicationContext reactContext;
|
|
96
|
+
private final AudioSwitchManager audioSwitchManager;
|
|
97
|
+
|
|
98
|
+
public TwilioVoiceReactNativeModule(ReactApplicationContext reactContext) {
|
|
99
|
+
super(reactContext);
|
|
100
|
+
|
|
101
|
+
logger.log("instantiation of TwilioVoiceReactNativeModule");
|
|
102
|
+
this.reactContext = reactContext;
|
|
103
|
+
System.setProperty(GLOBAL_ENV, ReactNativeVoiceSDK);
|
|
104
|
+
System.setProperty(SDK_VERSION, ReactNativeVoiceSDKVer);
|
|
105
|
+
Voice.setLogLevel(BuildConfig.DEBUG ? LogLevel.DEBUG : LogLevel.ERROR);
|
|
106
|
+
|
|
107
|
+
getJSEventEmitter().setContext(reactContext);
|
|
108
|
+
|
|
109
|
+
audioSwitchManager = VoiceApplicationProxy.getAudioSwitchManager()
|
|
110
|
+
.setListener((audioDevices, selectedDeviceUuid, selectedDevice) -> {
|
|
111
|
+
WritableMap audioDeviceInfo = serializeAudioDeviceInfo(
|
|
112
|
+
audioDevices,
|
|
113
|
+
selectedDeviceUuid,
|
|
114
|
+
selectedDevice
|
|
115
|
+
);
|
|
116
|
+
audioDeviceInfo.putString(VoiceEventType, VoiceEventAudioDevicesUpdated);
|
|
117
|
+
getJSEventEmitter().sendEvent(ScopeVoice, audioDeviceInfo);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Invoked by React Native, necessary when passing this NativeModule to the constructor of a
|
|
123
|
+
* NativeEventEmitter on the JS layer.
|
|
124
|
+
* <p>
|
|
125
|
+
* Invoked when a listener is added to the NativeEventEmitter.
|
|
126
|
+
*
|
|
127
|
+
* @param eventName The string representation of the event.
|
|
128
|
+
*/
|
|
129
|
+
@ReactMethod
|
|
130
|
+
public void addListener(String eventName) {
|
|
131
|
+
logger.debug(String.format("Calling addListener: %s", eventName));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Invoked by React Native, necessary when passing this NativeModule to the constructor of a
|
|
136
|
+
* NativeEventEmitter on the JS layer.
|
|
137
|
+
* <p>
|
|
138
|
+
* Invoked when listeners are removed from the NativeEventEmitter.
|
|
139
|
+
*
|
|
140
|
+
* @param count The number of event listeners removed.
|
|
141
|
+
*/
|
|
142
|
+
@ReactMethod
|
|
143
|
+
public void removeListeners(Integer count) {
|
|
144
|
+
logger.debug("Calling removeListeners: " + count);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
@ReactMethod
|
|
148
|
+
public void voice_connect_android(
|
|
149
|
+
String accessToken,
|
|
150
|
+
ReadableMap twimlParams,
|
|
151
|
+
String notificationDisplayName,
|
|
152
|
+
Promise promise
|
|
153
|
+
) {
|
|
154
|
+
logger.debug(".voice_connect_android()");
|
|
155
|
+
|
|
156
|
+
mainHandler.post(() -> {
|
|
157
|
+
logger.debug(".voice_connect_android() > runnable");
|
|
158
|
+
|
|
159
|
+
HashMap<String, String> parsedTwimlParams = new HashMap<>();
|
|
160
|
+
|
|
161
|
+
ReadableMapKeySetIterator iterator = twimlParams.keySetIterator();
|
|
162
|
+
while (iterator.hasNextKey()) {
|
|
163
|
+
String key = iterator.nextKey();
|
|
164
|
+
ReadableType readableType = twimlParams.getType(key);
|
|
165
|
+
switch (readableType) {
|
|
166
|
+
case Boolean:
|
|
167
|
+
parsedTwimlParams.put(key, String.valueOf(twimlParams.getBoolean(key)));
|
|
168
|
+
break;
|
|
169
|
+
case Number:
|
|
170
|
+
// Can be int or double.
|
|
171
|
+
parsedTwimlParams.put(key, String.valueOf(twimlParams.getDouble(key)));
|
|
172
|
+
break;
|
|
173
|
+
case String:
|
|
174
|
+
parsedTwimlParams.put(key, twimlParams.getString(key));
|
|
175
|
+
break;
|
|
176
|
+
default:
|
|
177
|
+
logger.warning("Could not convert with key: " + key + ".");
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// connect & create call record
|
|
183
|
+
final UUID uuid = UUID.randomUUID();
|
|
184
|
+
final String callRecipient =
|
|
185
|
+
(parsedTwimlParams.containsKey("to") && !(parsedTwimlParams.get("to").isBlank()))
|
|
186
|
+
? parsedTwimlParams.get("to")
|
|
187
|
+
: reactContext.getString(R.string.unknown_call_recipient);
|
|
188
|
+
ConnectOptions connectOptions = new ConnectOptions.Builder(accessToken)
|
|
189
|
+
.enableDscp(true)
|
|
190
|
+
.params(parsedTwimlParams)
|
|
191
|
+
.callMessageListener(new CallMessageListenerProxy())
|
|
192
|
+
.build();
|
|
193
|
+
try {
|
|
194
|
+
CallRecord callRecord = new CallRecord(
|
|
195
|
+
uuid,
|
|
196
|
+
getVoiceServiceApi().connect(
|
|
197
|
+
connectOptions,
|
|
198
|
+
new CallListenerProxy(uuid, getVoiceServiceApi().getServiceContext())),
|
|
199
|
+
callRecipient,
|
|
200
|
+
parsedTwimlParams,
|
|
201
|
+
CallRecord.Direction.OUTGOING,
|
|
202
|
+
notificationDisplayName);
|
|
203
|
+
getCallRecordDatabase().add(callRecord);
|
|
204
|
+
// notify JS layer
|
|
205
|
+
promise.resolve(serializeCall(callRecord));
|
|
206
|
+
} catch (SecurityException e) {
|
|
207
|
+
promise.reject(e, serializeError(31401, e.getMessage()));
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
@ReactMethod
|
|
213
|
+
public void voice_getVersion(Promise promise) {
|
|
214
|
+
promise.resolve(Voice.getVersion());
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
@ReactMethod
|
|
218
|
+
public void voice_getDeviceToken(Promise promise) {
|
|
219
|
+
FirebaseMessaging.getInstance().getToken()
|
|
220
|
+
.addOnCompleteListener(task -> {
|
|
221
|
+
if (!task.isSuccessful()) {
|
|
222
|
+
final String warningMsg =
|
|
223
|
+
reactContext.getString(R.string.fcm_token_registration_fail, task.getException());
|
|
224
|
+
logger.warning(warningMsg);
|
|
225
|
+
promise.reject(warningMsg);
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Get FCM registration token
|
|
230
|
+
String fcmToken = task.getResult();
|
|
231
|
+
|
|
232
|
+
if (fcmToken == null) {
|
|
233
|
+
final String warningMsg = reactContext.getString(R.string.fcm_token_null);
|
|
234
|
+
logger.warning(warningMsg);
|
|
235
|
+
promise.reject(warningMsg);
|
|
236
|
+
} else {
|
|
237
|
+
promise.resolve(fcmToken);
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
@ReactMethod
|
|
243
|
+
public void voice_showNativeAvRoutePicker(Promise promise) {
|
|
244
|
+
// This API is iOS specific.
|
|
245
|
+
promise.resolve(null);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
@ReactMethod
|
|
249
|
+
public void voice_getCalls(Promise promise) {
|
|
250
|
+
logger.debug(".voice_getCalls()");
|
|
251
|
+
|
|
252
|
+
mainHandler.post(() -> {
|
|
253
|
+
logger.debug(".voice_getCalls() > runnable");
|
|
254
|
+
|
|
255
|
+
WritableArray callInfos = Arguments.createArray();
|
|
256
|
+
for (CallRecord callRecord : getCallRecordDatabase().getCollection()) {
|
|
257
|
+
// incoming calls that have not been acted on do not have call-objects
|
|
258
|
+
if (null != callRecord.getVoiceCall()) {
|
|
259
|
+
callInfos.pushMap(serializeCall(callRecord));
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
promise.resolve(callInfos);
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
@ReactMethod
|
|
268
|
+
public void voice_getCallInvites(Promise promise) {
|
|
269
|
+
logger.debug(".voice_getCallInvites()");
|
|
270
|
+
|
|
271
|
+
mainHandler.post(() -> {
|
|
272
|
+
logger.debug(".voice_getCallInvites() > runnable");
|
|
273
|
+
|
|
274
|
+
WritableArray callInviteInfos = Arguments.createArray();
|
|
275
|
+
for (CallRecord callRecord : getCallRecordDatabase().getCollection()) {
|
|
276
|
+
if (null != callRecord.getCallInvite() &&
|
|
277
|
+
CallRecord.CallInviteState.ACTIVE == callRecord.getCallInviteState()) {
|
|
278
|
+
callInviteInfos.pushMap(serializeCallInvite(callRecord));
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
promise.resolve(callInviteInfos);
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
@ReactMethod
|
|
287
|
+
public void voice_getAudioDevices(Promise promise) {
|
|
288
|
+
Map<String, AudioDevice> audioDevices = audioSwitchManager.getAudioDevices();
|
|
289
|
+
String selectedAudioDeviceUuid = audioSwitchManager.getSelectedAudioDeviceUuid();
|
|
290
|
+
AudioDevice selectedAudioDevice = audioSwitchManager.getSelectedAudioDevice();
|
|
291
|
+
|
|
292
|
+
WritableMap audioDeviceInfo = serializeAudioDeviceInfo(
|
|
293
|
+
audioDevices,
|
|
294
|
+
selectedAudioDeviceUuid,
|
|
295
|
+
selectedAudioDevice
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
promise.resolve(audioDeviceInfo);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
@ReactMethod
|
|
302
|
+
public void voice_selectAudioDevice(String uuid, Promise promise) {
|
|
303
|
+
AudioDevice audioDevice = audioSwitchManager.getAudioDevices().get(uuid);
|
|
304
|
+
if (audioDevice == null) {
|
|
305
|
+
promise.reject(reactContext.getString(R.string.missing_audiodevice_uuid, uuid));
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
audioSwitchManager.getAudioSwitch().selectDevice(audioDevice);
|
|
310
|
+
|
|
311
|
+
promise.resolve(null);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
@ReactMethod
|
|
315
|
+
public void voice_setIncomingCallContactHandleTemplate(String template, Promise promise) {
|
|
316
|
+
ConfigurationProperties.setIncomingCallContactHandleTemplate(reactContext, template);
|
|
317
|
+
promise.resolve(null);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Call methods.
|
|
322
|
+
*/
|
|
323
|
+
|
|
324
|
+
@ReactMethod
|
|
325
|
+
public void call_getState(String uuid, Promise promise) {
|
|
326
|
+
logger.debug(".call_getState()");
|
|
327
|
+
|
|
328
|
+
mainHandler.post(() -> {
|
|
329
|
+
logger.debug(".call_getState() > runnable");
|
|
330
|
+
|
|
331
|
+
final CallRecord callRecord = validateCallRecord(UUID.fromString(uuid), promise);
|
|
332
|
+
|
|
333
|
+
if (null != callRecord) {
|
|
334
|
+
promise.resolve(callRecord.getVoiceCall().getState().toString().toLowerCase());
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
@ReactMethod
|
|
340
|
+
public void call_isMuted(String uuid, Promise promise) {
|
|
341
|
+
logger.debug(".call_isMuted()");
|
|
342
|
+
|
|
343
|
+
mainHandler.post(() -> {
|
|
344
|
+
logger.debug(".call_isMuted() > runnable");
|
|
345
|
+
|
|
346
|
+
final CallRecord callRecord = validateCallRecord(UUID.fromString(uuid), promise);
|
|
347
|
+
|
|
348
|
+
if (null != callRecord) {
|
|
349
|
+
promise.resolve(callRecord.getVoiceCall().isMuted());
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
@ReactMethod
|
|
355
|
+
public void call_isOnHold(String uuid, Promise promise) {
|
|
356
|
+
logger.debug(".call_isOnHold()");
|
|
357
|
+
|
|
358
|
+
mainHandler.post(() -> {
|
|
359
|
+
logger.debug(".call_isOnHold() > runnable");
|
|
360
|
+
|
|
361
|
+
final CallRecord callRecord = validateCallRecord(UUID.fromString(uuid), promise);
|
|
362
|
+
|
|
363
|
+
if (null != callRecord) {
|
|
364
|
+
promise.resolve(callRecord.getVoiceCall().isOnHold());
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
@ReactMethod
|
|
370
|
+
public void call_disconnect(String uuid, Promise promise) {
|
|
371
|
+
logger.debug(".call_disconnect()");
|
|
372
|
+
|
|
373
|
+
mainHandler.post(() -> {
|
|
374
|
+
logger.debug(".call_disconnect() > runnable");
|
|
375
|
+
|
|
376
|
+
final CallRecordDatabase.CallRecord callRecord =
|
|
377
|
+
validateCallRecord(UUID.fromString(uuid), promise);
|
|
378
|
+
|
|
379
|
+
if (null != callRecord) {
|
|
380
|
+
getVoiceServiceApi().disconnect(callRecord);
|
|
381
|
+
promise.resolve(uuid);
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
@ReactMethod
|
|
387
|
+
public void call_hold(String uuid, boolean hold, Promise promise) {
|
|
388
|
+
logger.debug(".call_hold()");
|
|
389
|
+
|
|
390
|
+
mainHandler.post(() -> {
|
|
391
|
+
logger.debug(".call_hold() > runnable");
|
|
392
|
+
|
|
393
|
+
final CallRecord callRecord = validateCallRecord(UUID.fromString(uuid), promise);
|
|
394
|
+
|
|
395
|
+
if (null != callRecord) {
|
|
396
|
+
callRecord.getVoiceCall().hold(hold);
|
|
397
|
+
promise.resolve(callRecord.getVoiceCall().isOnHold());
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
@ReactMethod
|
|
403
|
+
public void call_mute(String uuid, boolean mute, Promise promise) {
|
|
404
|
+
logger.debug(".call_mute()");
|
|
405
|
+
|
|
406
|
+
mainHandler.post(() -> {
|
|
407
|
+
logger.debug(".call_mute() > runnable");
|
|
408
|
+
|
|
409
|
+
final CallRecord callRecord = validateCallRecord(UUID.fromString(uuid), promise);
|
|
410
|
+
|
|
411
|
+
if (null != callRecord) {
|
|
412
|
+
callRecord.getVoiceCall().mute(mute);
|
|
413
|
+
promise.resolve(callRecord.getVoiceCall().isMuted());
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
@ReactMethod
|
|
419
|
+
public void call_sendDigits(String uuid, String digits, Promise promise) {
|
|
420
|
+
logger.debug(".call_sendDigits()");
|
|
421
|
+
|
|
422
|
+
mainHandler.post(() -> {
|
|
423
|
+
logger.debug(".call_sendDigits() > runnable");
|
|
424
|
+
|
|
425
|
+
final CallRecord callRecord = validateCallRecord(UUID.fromString(uuid), promise);
|
|
426
|
+
|
|
427
|
+
if (null != callRecord) {
|
|
428
|
+
callRecord.getVoiceCall().sendDigits(digits);
|
|
429
|
+
promise.resolve(uuid);
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
@ReactMethod
|
|
435
|
+
public void call_postFeedback(String uuid, String score, String issue, Promise promise) {
|
|
436
|
+
logger.debug(".call_postFeedback()");
|
|
437
|
+
|
|
438
|
+
mainHandler.post(() -> {
|
|
439
|
+
logger.debug(".call_postFeedback() > runnable");
|
|
440
|
+
|
|
441
|
+
final CallRecord callRecord = validateCallRecord(UUID.fromString(uuid), promise);
|
|
442
|
+
|
|
443
|
+
if (null != callRecord) {
|
|
444
|
+
Call.Score parsedScore = getScoreFromString(score);
|
|
445
|
+
Call.Issue parsedIssue = getIssueFromString(issue);
|
|
446
|
+
|
|
447
|
+
callRecord.getVoiceCall().postFeedback(parsedScore, parsedIssue);
|
|
448
|
+
|
|
449
|
+
promise.resolve(uuid);
|
|
450
|
+
}
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
@ReactMethod
|
|
456
|
+
public void call_getStats(String uuid, Promise promise) {
|
|
457
|
+
logger.debug(".call_getStats()");
|
|
458
|
+
|
|
459
|
+
mainHandler.post(() -> {
|
|
460
|
+
logger.debug(".call_getStats() > runnable");
|
|
461
|
+
|
|
462
|
+
final CallRecord callRecord = validateCallRecord(UUID.fromString(uuid), promise);
|
|
463
|
+
|
|
464
|
+
if (null != callRecord) {
|
|
465
|
+
callRecord.getVoiceCall().getStats(new StatsListenerProxy(uuid, reactContext, promise));
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
@ReactMethod
|
|
471
|
+
public void call_sendMessage(String uuid, String content, String contentType, String messageType, Promise promise) {
|
|
472
|
+
logger.debug(".call_sendMessage()");
|
|
473
|
+
|
|
474
|
+
mainHandler.post(() -> {
|
|
475
|
+
logger.debug(".call_sendMessage() > runnable");
|
|
476
|
+
|
|
477
|
+
final CallRecord callRecord = getCallRecordDatabase().get(new CallRecord(UUID.fromString(uuid)));
|
|
478
|
+
|
|
479
|
+
final CallMessage callMessage = new CallMessage.Builder(messageType)
|
|
480
|
+
.contentType(contentType).content(content).build();
|
|
481
|
+
|
|
482
|
+
promise.resolve((CallRecord.CallInviteState.ACTIVE == callRecord.getCallInviteState())
|
|
483
|
+
? callRecord.getCallInvite().sendMessage(callMessage)
|
|
484
|
+
: callRecord.getVoiceCall().sendMessage(callMessage));
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// Register/UnRegister
|
|
489
|
+
|
|
490
|
+
@ReactMethod
|
|
491
|
+
public void voice_register(String token, Promise promise) {
|
|
492
|
+
logger.debug(".voice_register()");
|
|
493
|
+
|
|
494
|
+
mainHandler.post(() -> {
|
|
495
|
+
logger.debug(".voice_register() > runnable");
|
|
496
|
+
|
|
497
|
+
FirebaseMessaging.getInstance().getToken()
|
|
498
|
+
.addOnCompleteListener(task -> {
|
|
499
|
+
if (!task.isSuccessful()) {
|
|
500
|
+
final String warningMsg =
|
|
501
|
+
reactContext.getString(R.string.fcm_token_registration_fail, task.getException());
|
|
502
|
+
logger.warning(warningMsg);
|
|
503
|
+
promise.reject(warningMsg);
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// Get new FCM registration token
|
|
508
|
+
String fcmToken = task.getResult();
|
|
509
|
+
|
|
510
|
+
if (fcmToken == null) {
|
|
511
|
+
final String warningMsg = reactContext.getString(R.string.fcm_token_null);
|
|
512
|
+
logger.warning(warningMsg);
|
|
513
|
+
promise.reject(warningMsg);
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// Log and toast
|
|
518
|
+
logger.debug("Registering with FCM with token " + fcmToken);
|
|
519
|
+
RegistrationListener registrationListener = createRegistrationListener(promise);
|
|
520
|
+
Voice.register(token, Voice.RegistrationChannel.FCM, fcmToken, registrationListener);
|
|
521
|
+
});
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
@ReactMethod
|
|
526
|
+
public void voice_unregister(String token, Promise promise) {
|
|
527
|
+
logger.debug(".voice_unregister()");
|
|
528
|
+
|
|
529
|
+
mainHandler.post(() -> {
|
|
530
|
+
logger.debug(".voice_unregister() > runnable");
|
|
531
|
+
|
|
532
|
+
FirebaseMessaging.getInstance().getToken()
|
|
533
|
+
.addOnCompleteListener(task -> {
|
|
534
|
+
if (!task.isSuccessful()) {
|
|
535
|
+
final String warningMsg =
|
|
536
|
+
reactContext.getString(R.string.fcm_token_registration_fail, task.getException());
|
|
537
|
+
logger.warning(warningMsg);
|
|
538
|
+
promise.reject(warningMsg);
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
// Get new FCM registration token
|
|
543
|
+
String fcmToken = task.getResult();
|
|
544
|
+
|
|
545
|
+
if (fcmToken == null) {
|
|
546
|
+
final String warningMsg = reactContext.getString(R.string.fcm_token_null);
|
|
547
|
+
logger.warning(warningMsg);
|
|
548
|
+
promise.reject(warningMsg);
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// Log and toast
|
|
553
|
+
logger.debug("Registering with FCM with token " + fcmToken);
|
|
554
|
+
UnregistrationListener unregistrationListener = createUnregistrationListener(promise);
|
|
555
|
+
Voice.unregister(token, Voice.RegistrationChannel.FCM, fcmToken, unregistrationListener);
|
|
556
|
+
});
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
@ReactMethod void voice_handleEvent(ReadableMap messageData, Promise promise) {
|
|
561
|
+
logger.debug(".voice_handleEvent()");
|
|
562
|
+
|
|
563
|
+
mainHandler.post(() -> {
|
|
564
|
+
logger.debug(".voice_handleEvent() > runnable");
|
|
565
|
+
|
|
566
|
+
// validate embedded firebase module is disabled
|
|
567
|
+
if (ConfigurationProperties.isFirebaseServiceEnabled(reactContext)) {
|
|
568
|
+
final String errorMsg = reactContext.getString(R.string.method_invocation_invalid);
|
|
569
|
+
logger.warning("Embedded firebase messaging enabled, handleEvent invocation invalid!");
|
|
570
|
+
promise.reject(errorMsg);
|
|
571
|
+
return;
|
|
572
|
+
}
|
|
573
|
+
// parse data to string map
|
|
574
|
+
final HashMap<String, String> parsedMessageData = new HashMap<>();
|
|
575
|
+
ReadableMapKeySetIterator iterator = messageData.keySetIterator();
|
|
576
|
+
while (iterator.hasNextKey()) {
|
|
577
|
+
String key = iterator.nextKey();
|
|
578
|
+
parsedMessageData.put(key, messageData.getString(key));
|
|
579
|
+
}
|
|
580
|
+
// attempt to parse message
|
|
581
|
+
if (Voice.handleMessage(
|
|
582
|
+
reactContext,
|
|
583
|
+
parsedMessageData,
|
|
584
|
+
new VoiceFirebaseMessagingService.MessageHandler(),
|
|
585
|
+
new CallMessageListenerProxy())) {
|
|
586
|
+
promise.resolve(true);
|
|
587
|
+
} else {
|
|
588
|
+
promise.resolve(false);
|
|
589
|
+
}
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
// CallInvite
|
|
594
|
+
|
|
595
|
+
@ReactMethod
|
|
596
|
+
public void callInvite_accept(String callInviteUuid, ReadableMap options, Promise promise) {
|
|
597
|
+
logger.debug("callInvite_accept uuid" + callInviteUuid);
|
|
598
|
+
|
|
599
|
+
mainHandler.post(() -> {
|
|
600
|
+
logger.debug(".callInvite_accept() > runnable");
|
|
601
|
+
|
|
602
|
+
final CallRecord callRecord =
|
|
603
|
+
validateCallInviteRecord(UUID.fromString(callInviteUuid), promise);
|
|
604
|
+
|
|
605
|
+
if (null != callRecord) {
|
|
606
|
+
// Store promise for callback
|
|
607
|
+
callRecord.setCallAcceptedPromise(promise);
|
|
608
|
+
|
|
609
|
+
// Send Event to service
|
|
610
|
+
try {
|
|
611
|
+
getVoiceServiceApi().acceptCall(callRecord);
|
|
612
|
+
} catch (SecurityException e) {
|
|
613
|
+
promise.reject(e, serializeError(31401, e.getMessage()));
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
});
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
@ReactMethod
|
|
620
|
+
public void callInvite_reject(String uuid, Promise promise) {
|
|
621
|
+
logger.debug("callInvite_reject uuid" + uuid);
|
|
622
|
+
|
|
623
|
+
mainHandler.post(() -> {
|
|
624
|
+
logger.debug(".callInvite_reject() > runnable");
|
|
625
|
+
|
|
626
|
+
final CallRecord callRecord = validateCallInviteRecord(UUID.fromString(uuid), promise);
|
|
627
|
+
|
|
628
|
+
if (null != callRecord) {
|
|
629
|
+
// Store promise for callback
|
|
630
|
+
callRecord.setCallRejectedPromise(promise);
|
|
631
|
+
|
|
632
|
+
// Send Event to service
|
|
633
|
+
getVoiceServiceApi().rejectCall(callRecord);
|
|
634
|
+
}
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
@ReactMethod
|
|
639
|
+
public void system_isFullScreenNotificationEnabled(Promise promise) {
|
|
640
|
+
boolean isEnabled =
|
|
641
|
+
isFullScreenNotificationEnabled(reactContext) &&
|
|
642
|
+
NotificationManagerCompat.from(reactContext).canUseFullScreenIntent();
|
|
643
|
+
|
|
644
|
+
promise.resolve(isEnabled);
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
@ReactMethod
|
|
648
|
+
public void system_requestFullScreenNotificationPermission(Promise promise) {
|
|
649
|
+
final boolean shouldStartActivity =
|
|
650
|
+
Build.VERSION.SDK_INT > Build.VERSION_CODES.TIRAMISU &&
|
|
651
|
+
isFullScreenNotificationEnabled(reactContext);
|
|
652
|
+
|
|
653
|
+
if (shouldStartActivity) {
|
|
654
|
+
try {
|
|
655
|
+
Intent intent = new Intent(
|
|
656
|
+
Settings.ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT,
|
|
657
|
+
Uri.parse("package:" + reactContext.getPackageName()));
|
|
658
|
+
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
659
|
+
reactContext.startActivity(intent);
|
|
660
|
+
} catch (Exception e) {
|
|
661
|
+
promise.reject(e);
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
promise.resolve(null);
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
@Override
|
|
669
|
+
@NonNull
|
|
670
|
+
public String getName() {
|
|
671
|
+
return TAG;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
private RegistrationListener createRegistrationListener(Promise promise) {
|
|
675
|
+
return new RegistrationListener() {
|
|
676
|
+
@Override
|
|
677
|
+
public void onRegistered(@NonNull String accessToken, @NonNull String fcmToken) {
|
|
678
|
+
logger.log("Successfully registered FCM");
|
|
679
|
+
sendJSEvent(constructJSMap(new Pair<>(VoiceEventType, VoiceEventRegistered)));
|
|
680
|
+
promise.resolve(null);
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
@Override
|
|
684
|
+
public void onError(@NonNull RegistrationException registrationException,
|
|
685
|
+
@NonNull String accessToken,
|
|
686
|
+
@NonNull String fcmToken) {
|
|
687
|
+
String errorMessage = reactContext.getString(
|
|
688
|
+
R.string.registration_error,
|
|
689
|
+
registrationException.getErrorCode(),
|
|
690
|
+
registrationException.getMessage());
|
|
691
|
+
logger.error(errorMessage);
|
|
692
|
+
|
|
693
|
+
sendJSEvent(constructJSMap(
|
|
694
|
+
new Pair<>(VoiceEventType, VoiceEventError),
|
|
695
|
+
new Pair<>(VoiceErrorKeyError, serializeVoiceException(registrationException))));
|
|
696
|
+
|
|
697
|
+
promise.reject(errorMessage);
|
|
698
|
+
}
|
|
699
|
+
};
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
private UnregistrationListener createUnregistrationListener(Promise promise) {
|
|
703
|
+
return new UnregistrationListener() {
|
|
704
|
+
@Override
|
|
705
|
+
public void onUnregistered(String accessToken, String fcmToken) {
|
|
706
|
+
logger.log("Successfully unregistered FCM");
|
|
707
|
+
sendJSEvent(constructJSMap(new Pair<>(VoiceEventType, VoiceEventUnregistered)));
|
|
708
|
+
promise.resolve(null);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
@Override
|
|
712
|
+
public void onError(RegistrationException registrationException, String accessToken, String fcmToken) {
|
|
713
|
+
@SuppressLint("DefaultLocale")
|
|
714
|
+
String errorMessage = reactContext.getString(
|
|
715
|
+
R.string.unregistration_error,
|
|
716
|
+
registrationException.getErrorCode(),
|
|
717
|
+
registrationException.getMessage());
|
|
718
|
+
logger.error(errorMessage);
|
|
719
|
+
|
|
720
|
+
sendJSEvent(constructJSMap(
|
|
721
|
+
new Pair<>(VoiceEventType, VoiceEventError),
|
|
722
|
+
new Pair<>(VoiceErrorKeyError, serializeVoiceException(registrationException))));
|
|
723
|
+
|
|
724
|
+
promise.reject(errorMessage);
|
|
725
|
+
}
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
/**
|
|
730
|
+
* Use the score map to get a Call.Score value from a string.
|
|
731
|
+
* @param score The score as a string passed from the JS layer.
|
|
732
|
+
* @return a Call.Score enum value. If the passed string is not in the enum, defaults to
|
|
733
|
+
* Call.Score.NOT_REPORTED.
|
|
734
|
+
*/
|
|
735
|
+
private static Call.Score getScoreFromString(String score) {
|
|
736
|
+
return scoreMap.containsKey(score)
|
|
737
|
+
? scoreMap.get(score)
|
|
738
|
+
: Call.Score.NOT_REPORTED;
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
/**
|
|
742
|
+
* Use the issue map to get a Call.Issue value from a string.
|
|
743
|
+
* @param issue The issue as a string passed from the JS layer.
|
|
744
|
+
* @return a Call.Issue enum value. If the passed string is not in the enum, defaults to
|
|
745
|
+
* Call.Issue.NOT_REPORTED.
|
|
746
|
+
*/
|
|
747
|
+
private static Call.Issue getIssueFromString(String issue) {
|
|
748
|
+
return issueMap.containsKey(issue)
|
|
749
|
+
? issueMap.get(issue)
|
|
750
|
+
: Call.Issue.NOT_REPORTED;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
private CallRecord validateCallRecord(@NonNull final UUID uuid,
|
|
754
|
+
@NonNull final Promise promise) {
|
|
755
|
+
CallRecord callRecord = getCallRecordDatabase().get(new CallRecord(uuid));
|
|
756
|
+
|
|
757
|
+
if (null == callRecord || null == callRecord.getVoiceCall()) {
|
|
758
|
+
promise.reject(reactContext.getString(R.string.missing_call_uuid, uuid));
|
|
759
|
+
return null;
|
|
760
|
+
}
|
|
761
|
+
return callRecord;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
private CallRecord validateCallInviteRecord(@NonNull final UUID uuid,
|
|
765
|
+
@NonNull final Promise promise) {
|
|
766
|
+
CallRecord callRecord = getCallRecordDatabase().get(new CallRecord(uuid));
|
|
767
|
+
|
|
768
|
+
if (null == callRecord || null == callRecord.getCallInvite()) {
|
|
769
|
+
promise.reject(reactContext.getString(R.string.missing_callinvite_uuid, uuid));
|
|
770
|
+
return null;
|
|
771
|
+
}
|
|
772
|
+
return callRecord;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
private void sendJSEvent(@NonNull WritableMap event) {
|
|
776
|
+
getJSEventEmitter().sendEvent(ScopeVoice, event);
|
|
777
|
+
}
|
|
778
|
+
}
|