rns-nativecall 0.1.3 → 0.1.5
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 +37 -30
- package/android/src/main/java/com/rnsnativecall/NativeCallManager.kt +32 -6
- 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,6 +1,6 @@
|
|
|
1
|
-
/////Users/bush/Desktop/Apps/Raiidr/package/android/src/main/java/com/rnsnativecall/MyConnectionService.kt
|
|
2
1
|
package com.rnsnativecall
|
|
3
2
|
|
|
3
|
+
import android.net.Uri // <--- ADD THIS IMPORT
|
|
4
4
|
import android.telecom.Connection
|
|
5
5
|
import android.telecom.ConnectionRequest
|
|
6
6
|
import android.telecom.ConnectionService
|
|
@@ -23,46 +23,53 @@ class MyConnectionService : ConnectionService() {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
override fun onCreateIncomingConnection(
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
connectionManagerPhoneAccount: PhoneAccountHandle?,
|
|
27
|
+
request: ConnectionRequest?
|
|
28
28
|
): Connection {
|
|
29
29
|
|
|
30
|
-
// 1️⃣ Read extras FIRST
|
|
31
30
|
val extras = request?.extras
|
|
32
31
|
val callUUID = extras?.getString("EXTRA_CALL_UUID")
|
|
33
32
|
val playRing = extras?.getBoolean("EXTRA_PLAY_RING", true) ?: true
|
|
34
|
-
val callerName = extras?.getString(TelecomManager.EXTRA_CALL_SUBJECT)
|
|
35
|
-
|
|
36
|
-
// 2️⃣ Create connection
|
|
37
|
-
val connection = MyCallConnection(
|
|
38
|
-
context = applicationContext,
|
|
39
|
-
callUUID = callUUID,
|
|
40
|
-
playRing = playRing,
|
|
41
|
-
onAcceptCallback = { uuid ->
|
|
42
|
-
CallModule.sendEventToJS("onCallAccepted", uuid)
|
|
43
|
-
},
|
|
44
|
-
onRejectCallback = { uuid ->
|
|
45
|
-
CallModule.sendEventToJS("onCallRejected", uuid)
|
|
46
|
-
}
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
// 3️⃣ Set caller display name (THIS FIXES MISALIGNMENT)
|
|
50
|
-
callerName?.let {
|
|
51
|
-
connection.setCallerDisplayName(
|
|
52
|
-
it,
|
|
53
|
-
TelecomManager.PRESENTATION_ALLOWED
|
|
54
|
-
)
|
|
55
|
-
}
|
|
56
33
|
|
|
57
|
-
//
|
|
34
|
+
// 1. "John Doe" (Top slot)
|
|
35
|
+
val actualPersonName = extras?.getString("EXTRA_CALLER_NAME") ?: "Someone"
|
|
36
|
+
|
|
37
|
+
// 2. "Raiidr Video Call" (Middle/Number slot)
|
|
38
|
+
val appLabel = extras?.getString(TelecomManager.EXTRA_CALL_SUBJECT) ?: "Incoming Call"
|
|
39
|
+
|
|
40
|
+
val connection =
|
|
41
|
+
MyCallConnection(
|
|
42
|
+
context = applicationContext,
|
|
43
|
+
callUUID = callUUID,
|
|
44
|
+
playRing = playRing,
|
|
45
|
+
onAcceptCallback = { uuid ->
|
|
46
|
+
CallModule.sendEventToJS("onCallAccepted", uuid)
|
|
47
|
+
},
|
|
48
|
+
onRejectCallback = { uuid ->
|
|
49
|
+
CallModule.sendEventToJS("onCallRejected", uuid)
|
|
50
|
+
}
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
// 3. Set the LARGE text on top to the Person's Name
|
|
54
|
+
connection.setCallerDisplayName(actualPersonName, TelecomManager.PRESENTATION_ALLOWED)
|
|
55
|
+
|
|
56
|
+
// 4. Standard Telecom setup
|
|
58
57
|
connection.connectionCapabilities =
|
|
59
|
-
|
|
58
|
+
Connection.CAPABILITY_MUTE or Connection.CAPABILITY_SUPPORT_HOLD
|
|
59
|
+
|
|
60
|
+
// --- THE UI FIX ---
|
|
61
|
+
// We force the App Label (e.g. "Raiidr Video Call") into the Address slot
|
|
62
|
+
// This replaces the raw phone number/handle on the incoming call screen.
|
|
63
|
+
val labelUri = Uri.fromParts("tel", appLabel, null)
|
|
64
|
+
connection.setAddress(labelUri, TelecomManager.PRESENTATION_ALLOWED)
|
|
60
65
|
|
|
61
|
-
connection.setAddress(request?.address, TelecomManager.PRESENTATION_ALLOWED)
|
|
62
66
|
connection.setInitializing()
|
|
63
67
|
connection.setRinging()
|
|
64
68
|
|
|
65
|
-
//
|
|
69
|
+
// Emit event to JS so the app can send the 'ringing' status
|
|
70
|
+
callUUID?.let { CallModule.sendEventToJS("onCallDisplayed", it) }
|
|
71
|
+
|
|
72
|
+
// Track connection
|
|
66
73
|
callUUID?.let { addConnection(it, connection) }
|
|
67
74
|
|
|
68
75
|
return connection
|
|
@@ -6,17 +6,34 @@ import android.net.Uri
|
|
|
6
6
|
import android.os.Bundle
|
|
7
7
|
import android.telecom.PhoneAccountHandle
|
|
8
8
|
import android.telecom.TelecomManager
|
|
9
|
-
import android.telecom.VideoProfile
|
|
9
|
+
import android.telecom.VideoProfile
|
|
10
10
|
|
|
11
11
|
object NativeCallManager {
|
|
12
12
|
|
|
13
13
|
fun handleIncomingPush(context: Context, data: Map<String, String>) {
|
|
14
14
|
val uuid = data["callId"] ?: return
|
|
15
15
|
val handle = data["from"] ?: "Unknown"
|
|
16
|
+
val callType = data["callType"] ?: "audio"
|
|
16
17
|
val name = data["name"] ?: handle
|
|
17
|
-
val hasVideo = data["hasVideo"]?.toBoolean() ?: false
|
|
18
18
|
val playRing = data["playRing"]?.toBoolean() ?: true
|
|
19
19
|
|
|
20
|
+
// 1. Get Dynamic App Name
|
|
21
|
+
val appName =
|
|
22
|
+
try {
|
|
23
|
+
val pm = context.packageManager
|
|
24
|
+
val ai = pm.getApplicationInfo(context.packageName, 0)
|
|
25
|
+
pm.getApplicationLabel(ai).toString()
|
|
26
|
+
} catch (e: Exception) {
|
|
27
|
+
"App"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// 2. Format Sub-label (e.g., "Raiidr Video Call")
|
|
31
|
+
val capitalizedCallType =
|
|
32
|
+
callType.replaceFirstChar {
|
|
33
|
+
if (it.isLowerCase()) it.titlecase() else it.toString()
|
|
34
|
+
}
|
|
35
|
+
val subLabel = "$appName $capitalizedCallType Call"
|
|
36
|
+
|
|
20
37
|
val telecomManager = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
|
|
21
38
|
val phoneAccountHandle = getPhoneAccountHandle(context)
|
|
22
39
|
|
|
@@ -27,15 +44,23 @@ object NativeCallManager {
|
|
|
27
44
|
Uri.fromParts("sip", handle, null)
|
|
28
45
|
)
|
|
29
46
|
putString("EXTRA_CALL_UUID", uuid)
|
|
30
|
-
|
|
47
|
+
|
|
48
|
+
// This goes to the SECONDARY slot in MyConnectionService
|
|
49
|
+
putString(TelecomManager.EXTRA_CALL_SUBJECT, subLabel)
|
|
50
|
+
|
|
51
|
+
// This goes to the PRIMARY slot (The Name) in MyConnectionService
|
|
52
|
+
putString("EXTRA_CALLER_NAME", name)
|
|
53
|
+
|
|
31
54
|
putBoolean("EXTRA_PLAY_RING", playRing)
|
|
32
55
|
|
|
33
|
-
|
|
56
|
+
val isVideo = callType.equals("video", ignoreCase = true)
|
|
34
57
|
val videoState =
|
|
35
|
-
if (
|
|
58
|
+
if (isVideo) VideoProfile.STATE_BIDIRECTIONAL
|
|
36
59
|
else VideoProfile.STATE_AUDIO_ONLY
|
|
37
|
-
|
|
38
60
|
putInt(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, videoState)
|
|
61
|
+
|
|
62
|
+
// Forward all other data
|
|
63
|
+
data.forEach { (key, value) -> putString(key, value) }
|
|
39
64
|
}
|
|
40
65
|
|
|
41
66
|
try {
|
|
@@ -45,6 +70,7 @@ object NativeCallManager {
|
|
|
45
70
|
}
|
|
46
71
|
}
|
|
47
72
|
|
|
73
|
+
// This function must be OUTSIDE handleIncomingPush but INSIDE the object
|
|
48
74
|
private fun getPhoneAccountHandle(context: Context): PhoneAccountHandle {
|
|
49
75
|
val componentName = ComponentName(context, MyConnectionService::class.java)
|
|
50
76
|
return PhoneAccountHandle(componentName, "${context.packageName}.voip")
|
package/package.json
CHANGED