rns-nativecall 0.1.2 → 0.1.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/android/src/main/java/com/rnsnativecall/CallModule.kt +43 -35
- package/android/src/main/java/com/rnsnativecall/CallPackage.kt +5 -3
- package/android/src/main/java/com/rnsnativecall/MyCallConnection.kt +20 -18
- package/android/src/main/java/com/rnsnativecall/MyConnectionService.kt +26 -26
- package/android/src/main/java/com/rnsnativecall/NativeCallManager.kt +31 -8
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
///Users/bush/Desktop/Apps/Raiidr/package/android/src/main/java/com/rnsnativecall/CallModule.kt
|
|
1
|
+
/// Users/bush/Desktop/Apps/Raiidr/package/android/src/main/java/com/rnsnativecall/CallModule.kt
|
|
2
2
|
package com.rnsnativecall
|
|
3
3
|
|
|
4
4
|
import android.content.ComponentName
|
|
@@ -6,10 +6,10 @@ import android.content.Context
|
|
|
6
6
|
import android.content.Intent
|
|
7
7
|
import android.net.Uri
|
|
8
8
|
import android.os.Bundle
|
|
9
|
+
import android.telecom.DisconnectCause
|
|
9
10
|
import android.telecom.PhoneAccount
|
|
10
11
|
import android.telecom.PhoneAccountHandle
|
|
11
12
|
import android.telecom.TelecomManager
|
|
12
|
-
import android.telecom.DisconnectCause
|
|
13
13
|
import com.facebook.react.bridge.*
|
|
14
14
|
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
15
15
|
|
|
@@ -29,47 +29,56 @@ class CallModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
private fun registerPhoneAccount() {
|
|
32
|
-
val telecomManager =
|
|
32
|
+
val telecomManager =
|
|
33
|
+
reactApplicationContext.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
|
|
33
34
|
val phoneAccountHandle = getPhoneAccountHandle()
|
|
34
35
|
|
|
35
36
|
// Dynamically get the app's display name from the Android Manifest
|
|
36
|
-
val appName =
|
|
37
|
+
val appName =
|
|
38
|
+
reactApplicationContext
|
|
39
|
+
.applicationInfo
|
|
40
|
+
.loadLabel(reactApplicationContext.packageManager)
|
|
41
|
+
.toString()
|
|
37
42
|
|
|
38
43
|
// Correct bitmasking: Combine all capabilities into a single integer
|
|
39
|
-
val capabilities =
|
|
40
|
-
|
|
44
|
+
val capabilities =
|
|
45
|
+
PhoneAccount.CAPABILITY_VIDEO_CALLING or
|
|
46
|
+
PhoneAccount.CAPABILITY_SUPPORTS_VIDEO_CALLING
|
|
41
47
|
|
|
42
|
-
val phoneAccount =
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
48
|
+
val phoneAccount =
|
|
49
|
+
PhoneAccount.builder(phoneAccountHandle, appName)
|
|
50
|
+
.setCapabilities(capabilities)
|
|
51
|
+
.setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)
|
|
52
|
+
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
|
|
53
|
+
.build()
|
|
47
54
|
|
|
48
55
|
telecomManager.registerPhoneAccount(phoneAccount)
|
|
49
56
|
}
|
|
50
57
|
|
|
51
58
|
@ReactMethod
|
|
52
59
|
fun displayIncomingCall(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
60
|
+
uuid: String,
|
|
61
|
+
number: String,
|
|
62
|
+
name: String,
|
|
63
|
+
hasVideo: Boolean,
|
|
64
|
+
playRing: Boolean,
|
|
65
|
+
promise: Promise
|
|
59
66
|
) {
|
|
60
|
-
val telecomManager =
|
|
67
|
+
val telecomManager =
|
|
68
|
+
reactApplicationContext.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
|
|
61
69
|
val phoneAccountHandle = getPhoneAccountHandle()
|
|
62
70
|
|
|
63
|
-
val extras =
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
val extras =
|
|
72
|
+
Bundle().apply {
|
|
73
|
+
putParcelable(
|
|
74
|
+
TelecomManager.EXTRA_INCOMING_CALL_ADDRESS,
|
|
75
|
+
Uri.fromParts("sip", number, null)
|
|
76
|
+
)
|
|
77
|
+
putString(TelecomManager.EXTRA_CALL_SUBJECT, name)
|
|
78
|
+
putString("EXTRA_CALL_UUID", uuid)
|
|
79
|
+
putBoolean("EXTRA_PLAY_RING", playRing)
|
|
80
|
+
putBoolean(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, hasVideo)
|
|
81
|
+
}
|
|
73
82
|
|
|
74
83
|
try {
|
|
75
84
|
telecomManager.addNewIncomingCall(phoneAccountHandle, extras)
|
|
@@ -91,7 +100,8 @@ class CallModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
91
100
|
|
|
92
101
|
@ReactMethod
|
|
93
102
|
fun checkTelecomPermissions(promise: Promise) {
|
|
94
|
-
val telecomManager =
|
|
103
|
+
val telecomManager =
|
|
104
|
+
reactApplicationContext.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
|
|
95
105
|
val phoneAccountHandle = getPhoneAccountHandle()
|
|
96
106
|
|
|
97
107
|
val account = telecomManager.getPhoneAccount(phoneAccountHandle)
|
|
@@ -113,12 +123,10 @@ class CallModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
113
123
|
private var instance: CallModule? = null
|
|
114
124
|
|
|
115
125
|
fun sendEventToJS(eventName: String, uuid: String?) {
|
|
116
|
-
val params = Arguments.createMap().apply {
|
|
117
|
-
putString("callUUID", uuid)
|
|
118
|
-
}
|
|
126
|
+
val params = Arguments.createMap().apply { putString("callUUID", uuid) }
|
|
119
127
|
instance?.reactApplicationContext
|
|
120
|
-
|
|
121
|
-
|
|
128
|
+
?.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
129
|
+
?.emit(eventName, params)
|
|
122
130
|
}
|
|
123
131
|
}
|
|
124
|
-
}
|
|
132
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/////Users/bush/Desktop/Apps/Raiidr/package/android/src/main/java/com/rnsnativecall/CallPackage.kt
|
|
1
|
+
///// Users/bush/Desktop/Apps/Raiidr/package/android/src/main/java/com/rnsnativecall/CallPackage.kt
|
|
2
2
|
package com.rnsnativecall
|
|
3
3
|
|
|
4
4
|
import com.facebook.react.ReactPackage
|
|
@@ -11,7 +11,9 @@ class CallPackage : ReactPackage {
|
|
|
11
11
|
return listOf(CallModule(reactContext))
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
override fun createViewManagers(
|
|
14
|
+
override fun createViewManagers(
|
|
15
|
+
reactContext: ReactApplicationContext
|
|
16
|
+
): List<ViewManager<*, *>> {
|
|
15
17
|
return emptyList()
|
|
16
18
|
}
|
|
17
|
-
}
|
|
19
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
/////
|
|
1
|
+
/////
|
|
2
|
+
// Users/bush/Desktop/Apps/Raiidr/package/android/src/main/java/com/rnsnativecall/MyCallConnection.kt
|
|
2
3
|
package com.rnsnativecall
|
|
3
4
|
|
|
4
5
|
import android.content.Context
|
|
@@ -10,11 +11,11 @@ import android.telecom.Connection
|
|
|
10
11
|
import android.telecom.DisconnectCause
|
|
11
12
|
|
|
12
13
|
class MyCallConnection(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
private val context: Context,
|
|
15
|
+
private val callUUID: String?,
|
|
16
|
+
private val playRing: Boolean,
|
|
17
|
+
private val onAcceptCallback: (String?) -> Unit,
|
|
18
|
+
private val onRejectCallback: (String?) -> Unit
|
|
18
19
|
) : Connection() {
|
|
19
20
|
|
|
20
21
|
private var mediaPlayer: MediaPlayer? = null
|
|
@@ -31,18 +32,19 @@ class MyCallConnection(
|
|
|
31
32
|
private fun startRingtone() {
|
|
32
33
|
val uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
|
|
33
34
|
|
|
34
|
-
mediaPlayer =
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
35
|
+
mediaPlayer =
|
|
36
|
+
MediaPlayer().apply {
|
|
37
|
+
setDataSource(context, uri)
|
|
38
|
+
setAudioAttributes(
|
|
39
|
+
AudioAttributes.Builder()
|
|
40
|
+
.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
|
|
41
|
+
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
|
|
42
|
+
.build()
|
|
43
|
+
)
|
|
44
|
+
isLooping = true
|
|
45
|
+
prepare()
|
|
46
|
+
start()
|
|
47
|
+
}
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
private fun stopRingtone() {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
/////
|
|
1
|
+
/////
|
|
2
|
+
// Users/bush/Desktop/Apps/Raiidr/package/android/src/main/java/com/rnsnativecall/MyConnectionService.kt
|
|
2
3
|
package com.rnsnativecall
|
|
3
4
|
|
|
4
5
|
import android.telecom.Connection
|
|
@@ -23,46 +24,45 @@ class MyConnectionService : ConnectionService() {
|
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
override fun onCreateIncomingConnection(
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
connectionManagerPhoneAccount: PhoneAccountHandle?,
|
|
28
|
+
request: ConnectionRequest?
|
|
28
29
|
): Connection {
|
|
29
30
|
|
|
30
|
-
// 1
|
|
31
|
+
// 1. Read extras
|
|
31
32
|
val extras = request?.extras
|
|
32
33
|
val callUUID = extras?.getString("EXTRA_CALL_UUID")
|
|
33
34
|
val playRing = extras?.getBoolean("EXTRA_PLAY_RING", true) ?: true
|
|
34
35
|
val callerName = extras?.getString(TelecomManager.EXTRA_CALL_SUBJECT)
|
|
35
36
|
|
|
36
|
-
// 2
|
|
37
|
-
val connection =
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
37
|
+
// 2. Create connection
|
|
38
|
+
val connection =
|
|
39
|
+
MyCallConnection(
|
|
40
|
+
context = applicationContext,
|
|
41
|
+
callUUID = callUUID,
|
|
42
|
+
playRing = playRing,
|
|
43
|
+
onAcceptCallback = { uuid ->
|
|
44
|
+
CallModule.sendEventToJS("onCallAccepted", uuid)
|
|
45
|
+
},
|
|
46
|
+
onRejectCallback = { uuid ->
|
|
47
|
+
CallModule.sendEventToJS("onCallRejected", uuid)
|
|
48
|
+
}
|
|
49
|
+
)
|
|
48
50
|
|
|
49
|
-
// 3
|
|
50
|
-
callerName?.let {
|
|
51
|
-
connection.setCallerDisplayName(
|
|
52
|
-
it,
|
|
53
|
-
TelecomManager.PRESENTATION_ALLOWED
|
|
54
|
-
)
|
|
55
|
-
}
|
|
51
|
+
// 3. Set caller display name
|
|
52
|
+
callerName?.let { connection.setCallerDisplayName(it, TelecomManager.PRESENTATION_ALLOWED) }
|
|
56
53
|
|
|
57
|
-
// 4
|
|
54
|
+
// 4. Standard Telecom setup
|
|
58
55
|
connection.connectionCapabilities =
|
|
59
|
-
|
|
56
|
+
Connection.CAPABILITY_MUTE or Connection.CAPABILITY_SUPPORT_HOLD
|
|
60
57
|
|
|
61
58
|
connection.setAddress(request?.address, TelecomManager.PRESENTATION_ALLOWED)
|
|
62
59
|
connection.setInitializing()
|
|
63
60
|
connection.setRinging()
|
|
64
61
|
|
|
65
|
-
//
|
|
62
|
+
// ✅ EMIT EVENT TO JS (Fixed variable name to callUUID)
|
|
63
|
+
callUUID?.let { CallModule.sendEventToJS("onCallDisplayed", it) }
|
|
64
|
+
|
|
65
|
+
// 5. Track connection
|
|
66
66
|
callUUID?.let { addConnection(it, connection) }
|
|
67
67
|
|
|
68
68
|
return connection
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
///
|
|
2
|
-
// Users/bush/Desktop/Packages/rns-nativecall/android/src/main/java/com/rnsnativecall/NativeCallManager.kt
|
|
3
1
|
package com.rnsnativecall
|
|
4
2
|
|
|
5
3
|
import android.content.ComponentName
|
|
@@ -8,20 +6,41 @@ import android.net.Uri
|
|
|
8
6
|
import android.os.Bundle
|
|
9
7
|
import android.telecom.PhoneAccountHandle
|
|
10
8
|
import android.telecom.TelecomManager
|
|
9
|
+
import android.telecom.VideoProfile
|
|
11
10
|
|
|
12
11
|
object NativeCallManager {
|
|
13
12
|
|
|
13
|
+
// Inside NativeCallManager.kt
|
|
14
|
+
|
|
14
15
|
fun handleIncomingPush(context: Context, data: Map<String, String>) {
|
|
15
16
|
val uuid = data["callId"] ?: return
|
|
16
17
|
val handle = data["from"] ?: "Unknown"
|
|
18
|
+
val callType = data["callType"] ?: "audio" // video or audio
|
|
17
19
|
val name = data["name"] ?: handle
|
|
18
|
-
val hasVideo = data["hasVideo"]?.toBoolean() ?: false
|
|
19
20
|
val playRing = data["playRing"]?.toBoolean() ?: true
|
|
20
21
|
|
|
22
|
+
// 1. Get the real App Name dynamically
|
|
23
|
+
val appName =
|
|
24
|
+
try {
|
|
25
|
+
val pm = context.packageManager
|
|
26
|
+
val ai = pm.getApplicationInfo(context.packageName, 0)
|
|
27
|
+
pm.getApplicationLabel(ai).toString()
|
|
28
|
+
} catch (e: Exception) {
|
|
29
|
+
"App" // Fallback
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 2. Capitalize callType (e.g., "video" -> "Video")
|
|
33
|
+
val capitalizedCallType =
|
|
34
|
+
callType.replaceFirstChar {
|
|
35
|
+
if (it.isLowerCase()) it.titlecase() else it.toString()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// 3. Construct the robust label: "Incoming [AppName] [Video/Audio] Call"
|
|
39
|
+
val displayLabel = "Incoming $appName $capitalizedCallType Call"
|
|
40
|
+
|
|
21
41
|
val telecomManager = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
|
|
22
42
|
val phoneAccountHandle = getPhoneAccountHandle(context)
|
|
23
43
|
|
|
24
|
-
// In NativeCallManager.kt
|
|
25
44
|
val extras =
|
|
26
45
|
Bundle().apply {
|
|
27
46
|
putParcelable(
|
|
@@ -31,15 +50,19 @@ object NativeCallManager {
|
|
|
31
50
|
putString("EXTRA_CALL_UUID", uuid)
|
|
32
51
|
putString(
|
|
33
52
|
TelecomManager.EXTRA_CALL_SUBJECT,
|
|
34
|
-
|
|
35
|
-
) //
|
|
53
|
+
displayLabel
|
|
54
|
+
) // Set the dynamic label
|
|
36
55
|
putBoolean("EXTRA_PLAY_RING", playRing)
|
|
37
56
|
|
|
38
|
-
//
|
|
57
|
+
// Ensure hasVideo is properly mapped to Telecom constants
|
|
58
|
+
val isVideo = callType.equals("video", ignoreCase = true)
|
|
39
59
|
val videoState =
|
|
40
|
-
if (
|
|
60
|
+
if (isVideo) VideoProfile.STATE_BIDIRECTIONAL
|
|
41
61
|
else VideoProfile.STATE_AUDIO_ONLY
|
|
42
62
|
putInt(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, videoState)
|
|
63
|
+
|
|
64
|
+
// Pass all other data so ConnectionService can access it if needed
|
|
65
|
+
data.forEach { (key, value) -> putString(key, value) }
|
|
43
66
|
}
|
|
44
67
|
|
|
45
68
|
try {
|
package/package.json
CHANGED