rns-nativecall 0.6.2 → 0.6.3
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/README.md +77 -157
- package/android/build.gradle +0 -3
- package/android/src/main/java/com/rnsnativecall/AcceptCallActivity.kt +62 -35
- package/android/src/main/java/com/rnsnativecall/CallActionReceiver.kt +32 -27
- package/android/src/main/java/com/rnsnativecall/CallHeadlessTask.kt +21 -49
- package/android/src/main/java/com/rnsnativecall/CallMessagingService.kt +87 -83
- package/android/src/main/java/com/rnsnativecall/CallModule.kt +90 -21
- package/android/src/main/java/com/rnsnativecall/CallState.kt +54 -0
- package/android/src/main/java/com/rnsnativecall/NativeCallManager.kt +93 -53
- package/android/src/main/java/com/rnsnativecall/UnlockPromptActivity.kt +55 -0
- package/app.plugin.js +1 -1
- package/index.d.ts +13 -26
- package/index.js +36 -10
- package/package.json +12 -24
- package/rns-nativecall.podspec +1 -1
- package/withNativeCallVoip.js +72 -83
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
package com.rnsnativecall
|
|
2
|
+
|
|
3
|
+
import android.app.Activity
|
|
4
|
+
import android.app.KeyguardManager
|
|
5
|
+
import android.content.Context
|
|
6
|
+
import android.content.Intent
|
|
7
|
+
import android.os.Build
|
|
8
|
+
import android.os.Bundle
|
|
9
|
+
import android.view.WindowManager
|
|
10
|
+
|
|
11
|
+
class UnlockPromptActivity : Activity() {
|
|
12
|
+
override fun onCreate(savedInstanceState: Bundle?) {
|
|
13
|
+
super.onCreate(savedInstanceState)
|
|
14
|
+
|
|
15
|
+
// Ensure this activity shows over the lockscreen to trigger the prompt
|
|
16
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
|
|
17
|
+
setShowWhenLocked(true)
|
|
18
|
+
setTurnScreenOn(true)
|
|
19
|
+
} else {
|
|
20
|
+
window.addFlags(
|
|
21
|
+
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
|
|
22
|
+
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
val km = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
|
|
27
|
+
|
|
28
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
29
|
+
km.requestDismissKeyguard(this, object : KeyguardManager.KeyguardDismissCallback() {
|
|
30
|
+
override fun onDismissSucceeded() {
|
|
31
|
+
super.onDismissSucceeded()
|
|
32
|
+
// Unlock successful, launch the main app
|
|
33
|
+
val launchIntent = packageManager.getLaunchIntentForPackage(packageName)
|
|
34
|
+
startActivity(launchIntent)
|
|
35
|
+
finish()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
override fun onDismissCancelled() {
|
|
39
|
+
super.onDismissCancelled()
|
|
40
|
+
finish()
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
override fun onDismissError() {
|
|
44
|
+
super.onDismissError()
|
|
45
|
+
finish()
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
} else {
|
|
49
|
+
// Fallback for older Android versions
|
|
50
|
+
val launchIntent = packageManager.getLaunchIntentForPackage(packageName)
|
|
51
|
+
startActivity(launchIntent)
|
|
52
|
+
finish()
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
package/app.plugin.js
CHANGED
package/index.d.ts
CHANGED
|
@@ -2,50 +2,37 @@ export interface CallData {
|
|
|
2
2
|
callUuid: string;
|
|
3
3
|
name?: string;
|
|
4
4
|
callType?: 'audio' | 'video';
|
|
5
|
-
|
|
5
|
+
isBusySignal?: boolean;
|
|
6
|
+
[key: string]: any;
|
|
6
7
|
}
|
|
7
8
|
|
|
8
|
-
export type
|
|
9
|
-
export type CallRejectedCallback = (data: CallData) => void;
|
|
10
|
-
export type CallFailedCallback = (data: any) => void;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Manually request/check Android permissions for Telecom.
|
|
14
|
-
*/
|
|
15
|
-
export function ensureAndroidPermissions(): Promise<boolean>;
|
|
9
|
+
export type CallEventType = 'INCOMING_CALL' | 'BUSY';
|
|
16
10
|
|
|
17
11
|
export interface CallHandlerType {
|
|
18
12
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* @param name Caller display name
|
|
22
|
-
* @param callType 'audio' or 'video'
|
|
13
|
+
* Registers the Headless JS task.
|
|
14
|
+
* Handles Busy signals and Call Validity automatically.
|
|
23
15
|
*/
|
|
16
|
+
registerHeadlessTask(
|
|
17
|
+
callback: (data: CallData, eventType: CallEventType) => Promise<void>
|
|
18
|
+
): void;
|
|
19
|
+
|
|
24
20
|
displayCall(
|
|
25
21
|
uuid: string,
|
|
26
22
|
name: string,
|
|
27
23
|
callType: 'audio' | 'video',
|
|
28
24
|
): Promise<boolean>;
|
|
29
25
|
|
|
30
|
-
/**
|
|
31
|
-
* Dismiss the native call UI (Sticky Pill).
|
|
32
|
-
*/
|
|
33
26
|
destroyNativeCallUI(uuid: string): void;
|
|
34
27
|
|
|
28
|
+
getInitialCallData(): Promise<any | null>;
|
|
35
29
|
|
|
36
|
-
getInitialCallData(): Promise<CallData | null>;
|
|
37
|
-
/**
|
|
38
|
-
* Subscribe to call events. Automatically checks for cold-start data
|
|
39
|
-
* if the app was opened via the Answer button.
|
|
40
|
-
* @returns Function to unsubscribe
|
|
41
|
-
*/
|
|
42
30
|
subscribe(
|
|
43
|
-
onAccept:
|
|
44
|
-
onReject:
|
|
45
|
-
onFailed?:
|
|
31
|
+
onAccept: (data: CallData) => void,
|
|
32
|
+
onReject: (data: CallData) => void,
|
|
33
|
+
onFailed?: (data: any) => void
|
|
46
34
|
): () => void;
|
|
47
35
|
}
|
|
48
36
|
|
|
49
37
|
declare const CallHandler: CallHandlerType;
|
|
50
|
-
|
|
51
38
|
export default CallHandler;
|
package/index.js
CHANGED
|
@@ -1,13 +1,48 @@
|
|
|
1
1
|
import {
|
|
2
2
|
NativeModules,
|
|
3
3
|
NativeEventEmitter,
|
|
4
|
+
AppRegistry,
|
|
4
5
|
} from 'react-native';
|
|
5
6
|
|
|
6
7
|
const { CallModule } = NativeModules;
|
|
7
|
-
|
|
8
8
|
const callEventEmitter = CallModule ? new NativeEventEmitter(CallModule) : null;
|
|
9
9
|
|
|
10
10
|
export const CallHandler = {
|
|
11
|
+
/**
|
|
12
|
+
* INTERNAL GATEKEEPER: Moves headless logic into the package.
|
|
13
|
+
* The dev just passes their "NativeCall" function.
|
|
14
|
+
*/
|
|
15
|
+
registerHeadlessTask: (onAction) => {
|
|
16
|
+
AppRegistry.registerHeadlessTask('ColdStartCallTask', () => async (data) => {
|
|
17
|
+
const { callUuid, isBusySignal } = data;
|
|
18
|
+
const uuid = callUuid?.toLowerCase().trim();
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
// 1. Handle Busy Signal (Second Caller)
|
|
22
|
+
if (isBusySignal) {
|
|
23
|
+
console.log(`[RNSNativeCall] System busy. Informing app to send busy signal for: ${uuid}`);
|
|
24
|
+
if (onAction) await onAction(data, 'BUSY');
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// 2. Gatekeeping: Check Validity with Native logic
|
|
29
|
+
const status = await CallModule.checkCallValidity(uuid);
|
|
30
|
+
if (!status.isValid) {
|
|
31
|
+
console.log(`[RNSNativeCall] Aborting task: ${uuid} no longer valid or canceled.`);
|
|
32
|
+
if (onAction) await onAction(data, 'ABORTED_CALL');
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// 3. Valid Incoming Call: Pass to Developer's UI logic
|
|
37
|
+
if (onAction) {
|
|
38
|
+
await onAction(data, 'INCOMING_CALL');
|
|
39
|
+
}
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.error('[RNSNativeCall] Headless Task Error:', error);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
|
|
11
46
|
displayCall: async (uuid, name, callType = "audio") => {
|
|
12
47
|
if (!CallModule) return false;
|
|
13
48
|
return await CallModule.displayIncomingCall(uuid.toLowerCase().trim(), name, callType);
|
|
@@ -19,10 +54,6 @@ export const CallHandler = {
|
|
|
19
54
|
}
|
|
20
55
|
},
|
|
21
56
|
|
|
22
|
-
/**
|
|
23
|
-
* Manually check for cold-start data (App killed -> Answered).
|
|
24
|
-
* Call this in your App.js useEffect.
|
|
25
|
-
*/
|
|
26
57
|
getInitialCallData: async () => {
|
|
27
58
|
if (!CallModule?.getInitialCallData) return null;
|
|
28
59
|
return await CallModule.getInitialCallData();
|
|
@@ -40,11 +71,6 @@ export const CallHandler = {
|
|
|
40
71
|
subs.push(callEventEmitter.addListener('onCallFailed', onFailed));
|
|
41
72
|
}
|
|
42
73
|
|
|
43
|
-
// Auto-check on subscribe for convenience
|
|
44
|
-
CallHandler.getInitialCallData().then((data) => {
|
|
45
|
-
if (data) onAccept(data);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
74
|
return () => subs.forEach(s => s.remove());
|
|
49
75
|
}
|
|
50
76
|
};
|
package/package.json
CHANGED
|
@@ -1,37 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rns-nativecall",
|
|
3
|
-
"version": "0.6.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.6.3",
|
|
4
|
+
"description": "High-performance React Native module for handling native VoIP call UI on Android and iOS.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
7
7
|
"homepage": "https://github.com/raiidr/rns-nativecall",
|
|
8
8
|
"license": "MIT",
|
|
9
|
-
"author":
|
|
10
|
-
"name": "Your Name",
|
|
11
|
-
"email": "your.email@example.com"
|
|
12
|
-
},
|
|
9
|
+
"author": "Your Name <your.email@example.com>",
|
|
13
10
|
"repository": {
|
|
14
11
|
"type": "git",
|
|
15
|
-
"url": "https://github.com/raiidr/rns-nativecall.git"
|
|
12
|
+
"url": "git+https://github.com/raiidr/rns-nativecall.git"
|
|
16
13
|
},
|
|
17
|
-
"react-native": "index.js",
|
|
18
14
|
"scripts": {
|
|
19
15
|
"p": "npm publish --access public"
|
|
20
16
|
},
|
|
21
|
-
"expo": {
|
|
22
|
-
"autolink": true,
|
|
23
|
-
"plugins": [
|
|
24
|
-
"./app.plugin.js"
|
|
25
|
-
]
|
|
26
|
-
},
|
|
27
17
|
"keywords": [
|
|
28
18
|
"react-native",
|
|
29
19
|
"nativecall",
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"call keep",
|
|
20
|
+
"voip",
|
|
21
|
+
"callkit",
|
|
33
22
|
"android",
|
|
34
|
-
"
|
|
23
|
+
"ios",
|
|
24
|
+
"expo",
|
|
25
|
+
"config-plugin"
|
|
35
26
|
],
|
|
36
27
|
"files": [
|
|
37
28
|
"android",
|
|
@@ -39,18 +30,15 @@
|
|
|
39
30
|
"app.plugin.js",
|
|
40
31
|
"index.d.ts",
|
|
41
32
|
"index.js",
|
|
42
|
-
"package.json",
|
|
43
33
|
"react-native.config.js",
|
|
44
|
-
"README.md",
|
|
45
34
|
"rns-nativecall.podspec",
|
|
46
35
|
"withNativeCallVoip.js"
|
|
47
36
|
],
|
|
48
37
|
"peerDependencies": {
|
|
49
|
-
"
|
|
50
|
-
"
|
|
38
|
+
"react-native": ">=0.60.0",
|
|
39
|
+
"expo": ">=45.0.0"
|
|
51
40
|
},
|
|
52
41
|
"dependencies": {
|
|
53
|
-
"@expo/config-plugins": "
|
|
54
|
-
"rns-nativecall": "^0.5.9"
|
|
42
|
+
"@expo/config-plugins": "^9.0.0"
|
|
55
43
|
}
|
|
56
44
|
}
|
package/rns-nativecall.podspec
CHANGED
|
@@ -10,7 +10,7 @@ Pod::Spec.new do |s|
|
|
|
10
10
|
s.license = package["license"]
|
|
11
11
|
s.authors = package["author"]
|
|
12
12
|
s.platforms = { :ios => "10.0" }
|
|
13
|
-
s.source = { :git => "https://github.com/
|
|
13
|
+
s.source = { :git => "https://github.com/raiidr.git", :tag => "#{s.version}" }
|
|
14
14
|
|
|
15
15
|
s.source_files = "ios/**/*.{h,m,mm}"
|
|
16
16
|
|
package/withNativeCallVoip.js
CHANGED
|
@@ -4,134 +4,123 @@ const { withAndroidManifest, withInfoPlist, withPlugins, withMainActivity } = re
|
|
|
4
4
|
function withMainActivityDataFix(config) {
|
|
5
5
|
return withMainActivity(config, (config) => {
|
|
6
6
|
let contents = config.modResults.contents;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
'import android.view.WindowManager',
|
|
10
|
-
'import android.os.Build',
|
|
11
|
-
'import android.os.Bundle',
|
|
12
|
-
'import android.content.Intent',
|
|
13
|
-
'import android.content.Context' // Added: Required for KEYGUARD_SERVICE
|
|
14
|
-
];
|
|
15
|
-
|
|
16
|
-
imports.forEach(imp => {
|
|
17
|
-
if (!contents.includes(imp)) {
|
|
18
|
-
contents = contents.replace(/package .*/, (match) => `${match}\n${imp}`);
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
const wakeLogic = `super.onCreate(savedInstanceState)
|
|
23
|
-
if (intent?.getBooleanExtra("navigatingToCall", false) == true) {
|
|
24
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
|
|
25
|
-
setShowWhenLocked(true)
|
|
26
|
-
setTurnScreenOn(true)
|
|
27
|
-
} else {
|
|
28
|
-
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON)
|
|
7
|
+
if (!contents.includes('import android.content.Intent')) {
|
|
8
|
+
contents = contents.replace(/package .*/, (match) => `${match}\n\nimport android.content.Intent`);
|
|
29
9
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
keyguardManager?.requestDismissKeyguard(this, null)
|
|
33
|
-
}`;
|
|
34
|
-
|
|
35
|
-
if (!contents.includes('setShowWhenLocked')) {
|
|
36
|
-
contents = contents.replace(/super\.onCreate\(.*\)/, wakeLogic);
|
|
10
|
+
if (!contents.includes('import android.os.Bundle')) {
|
|
11
|
+
contents = contents.replace(/package .*/, (match) => `${match}\n\nimport android.os.Bundle`);
|
|
37
12
|
}
|
|
38
|
-
|
|
39
|
-
if (!contents.includes('override fun onNewIntent')) {
|
|
40
|
-
const onNewIntentCode = `
|
|
13
|
+
const onNewIntentCode = `
|
|
41
14
|
override fun onNewIntent(intent: Intent) {
|
|
42
15
|
super.onNewIntent(intent)
|
|
43
16
|
setIntent(intent)
|
|
44
|
-
|
|
17
|
+
val dataMap = mutableMapOf<String, String>()
|
|
18
|
+
intent.extras?.keySet()?.forEach { key ->
|
|
19
|
+
dataMap[key] = intent.extras?.get(key)?.toString() ?: ""
|
|
20
|
+
}
|
|
21
|
+
if (dataMap.isNotEmpty()) {
|
|
22
|
+
com.rnsnativecall.CallModule.setPendingCallData(dataMap)
|
|
23
|
+
com.rnsnativecall.CallModule.sendEventToJS("onCallAccepted", dataMap)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
`;
|
|
27
|
+
const onCreateCode = `
|
|
28
|
+
override fun onCreate(savedInstanceState: Bundle?) {
|
|
29
|
+
super.onCreate(savedInstanceState)
|
|
30
|
+
if (intent.getBooleanExtra("background_wake", false)) {
|
|
31
|
+
moveTaskToBack(true)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
`;
|
|
35
|
+
if (!contents.includes('override fun onNewIntent')) {
|
|
45
36
|
const lastBraceIndex = contents.lastIndexOf('}');
|
|
46
37
|
contents = contents.slice(0, lastBraceIndex) + onNewIntentCode + contents.slice(lastBraceIndex);
|
|
47
38
|
}
|
|
48
|
-
|
|
39
|
+
if (!contents.includes('override fun onCreate')) {
|
|
40
|
+
const lastBraceIndex = contents.lastIndexOf('}');
|
|
41
|
+
contents = contents.slice(0, lastBraceIndex) + onCreateCode + contents.slice(lastBraceIndex);
|
|
42
|
+
}
|
|
49
43
|
config.modResults.contents = contents;
|
|
50
44
|
return config;
|
|
51
45
|
});
|
|
52
46
|
}
|
|
53
|
-
|
|
54
47
|
/** 2. ANDROID MANIFEST CONFIG **/
|
|
55
48
|
function withAndroidConfig(config) {
|
|
56
49
|
return withAndroidManifest(config, (config) => {
|
|
57
|
-
const
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
// Permissions
|
|
50
|
+
const manifest = config.modResults;
|
|
51
|
+
const application = manifest.manifest.application[0];
|
|
61
52
|
const permissions = [
|
|
62
53
|
'android.permission.USE_FULL_SCREEN_INTENT',
|
|
63
54
|
'android.permission.VIBRATE',
|
|
64
55
|
'android.permission.FOREGROUND_SERVICE',
|
|
65
56
|
'android.permission.FOREGROUND_SERVICE_PHONE_CALL',
|
|
66
57
|
'android.permission.POST_NOTIFICATIONS',
|
|
58
|
+
'android.permission.SYSTEM_ALERT_WINDOW',
|
|
67
59
|
'android.permission.WAKE_LOCK',
|
|
68
|
-
'android.permission.
|
|
69
|
-
'android.permission.DISABLE_KEYGUARD',
|
|
70
|
-
'android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS',
|
|
71
|
-
'android.permission.RECEIVE_BOOT_COMPLETED'
|
|
60
|
+
'android.permission.DISABLE_KEYGUARD'
|
|
72
61
|
];
|
|
73
|
-
|
|
74
|
-
androidManifest['uses-permission'] = androidManifest['uses-permission'] || [];
|
|
62
|
+
manifest.manifest['uses-permission'] = manifest.manifest['uses-permission'] || [];
|
|
75
63
|
permissions.forEach((perm) => {
|
|
76
|
-
if (!
|
|
77
|
-
|
|
64
|
+
if (!manifest.manifest['uses-permission'].some((p) => p.$['android:name'] === perm)) {
|
|
65
|
+
manifest.manifest['uses-permission'].push({ $: { 'android:name': perm } });
|
|
78
66
|
}
|
|
79
67
|
});
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if (!mainApplication.activity.some(a => a.$['android:name'] === 'com.rnsnativecall.AcceptCallActivity')) {
|
|
84
|
-
mainApplication.activity.push({
|
|
68
|
+
application.activity = application.activity || [];
|
|
69
|
+
if (!application.activity.some(a => a.$['android:name'] === 'com.rnsnativecall.AcceptCallActivity')) {
|
|
70
|
+
application.activity.push({
|
|
85
71
|
$: {
|
|
86
72
|
'android:name': 'com.rnsnativecall.AcceptCallActivity',
|
|
87
73
|
'android:theme': '@android:style/Theme.Translucent.NoTitleBar',
|
|
88
|
-
'android:
|
|
74
|
+
'android:excludeFromRecents': 'true',
|
|
75
|
+
'android:noHistory': 'true',
|
|
76
|
+
'android:exported': 'false',
|
|
77
|
+
'android:launchMode': 'singleInstance',
|
|
89
78
|
'android:showWhenLocked': 'true',
|
|
90
|
-
'android:turnScreenOn': 'true'
|
|
91
|
-
'android:launchMode': 'singleInstance' // Add this to prevent multiple instances
|
|
79
|
+
'android:turnScreenOn': 'true'
|
|
92
80
|
}
|
|
93
81
|
});
|
|
94
82
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
mainApplication.receiver = mainApplication.receiver || [];
|
|
98
|
-
if (!mainApplication.receiver.some(r => r.$['android:name'] === 'com.rnsnativecall.CallActionReceiver')) {
|
|
99
|
-
mainApplication.receiver.push({
|
|
83
|
+
if (!application.activity.some(a => a.$['android:name'] === 'com.rnsnativecall.UnlockPromptActivity')) {
|
|
84
|
+
application.activity.push({
|
|
100
85
|
$: {
|
|
101
|
-
'android:name': 'com.rnsnativecall.
|
|
102
|
-
'android:
|
|
86
|
+
'android:name': 'com.rnsnativecall.UnlockPromptActivity',
|
|
87
|
+
'android:theme': '@android:style/Theme.Translucent.NoTitleBar',
|
|
88
|
+
'android:excludeFromRecents': 'true',
|
|
89
|
+
'android:noHistory': 'true',
|
|
90
|
+
'android:exported': 'false',
|
|
91
|
+
'android:launchMode': 'singleInstance',
|
|
92
|
+
'android:showWhenLocked': 'true',
|
|
93
|
+
'android:turnScreenOn': 'true'
|
|
103
94
|
}
|
|
104
95
|
});
|
|
105
96
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
mainApplication.service.push({
|
|
112
|
-
$: { 'android:name': 'com.rnsnativecall.CallMessagingService', 'android:exported': 'false' },
|
|
97
|
+
application.service = application.service || [];
|
|
98
|
+
const firebaseServiceName = 'com.rnsnativecall.CallMessagingService';
|
|
99
|
+
if (!application.service.some(s => s.$['android:name'] === firebaseServiceName)) {
|
|
100
|
+
application.service.push({
|
|
101
|
+
$: { 'android:name': firebaseServiceName, 'android:exported': 'false' },
|
|
113
102
|
'intent-filter': [{ action: [{ $: { 'android:name': 'com.google.firebase.MESSAGING_EVENT' } }] }]
|
|
114
103
|
});
|
|
115
104
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
else mainApplication.service.push(headlessEntry);
|
|
105
|
+
const headlessServiceName = 'com.rnsnativecall.CallHeadlessTask';
|
|
106
|
+
if (!application.service.some(s => s.$['android:name'] === headlessServiceName)) {
|
|
107
|
+
application.service.push({
|
|
108
|
+
$: { 'android:name': headlessServiceName, 'android:exported': 'false' }
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
application.receiver = application.receiver || [];
|
|
112
|
+
const receiverName = 'com.rnsnativecall.CallActionReceiver';
|
|
113
|
+
if (!application.receiver.some(r => r.$['android:name'] === receiverName)) {
|
|
114
|
+
application.receiver.push({
|
|
115
|
+
$: { 'android:name': receiverName, 'android:exported': 'false' }
|
|
116
|
+
});
|
|
117
|
+
}
|
|
130
118
|
|
|
131
119
|
return config;
|
|
132
120
|
});
|
|
133
121
|
}
|
|
134
122
|
|
|
123
|
+
/** 3. IOS CONFIG **/
|
|
135
124
|
function withIosConfig(config) {
|
|
136
125
|
return withInfoPlist(config, (config) => {
|
|
137
126
|
const infoPlist = config.modResults;
|