@@ -7,8 +7,6 @@ import android.content.Context
77import android.content.Intent
88import android.content.IntentFilter
99import android.graphics.drawable.GradientDrawable
10- import android.media.Ringtone
11- import android.media.RingtoneManager
1210import android.os.Build
1311import android.os.Bundle
1412import android.os.Handler
@@ -31,14 +29,16 @@ import chat.rocket.reactnative.notification.Ejson
3129/* *
3230 * Full-screen Activity displayed when an incoming VoIP call arrives.
3331 * Shows on lock screen and handles user actions (Accept/Decline).
32+ *
33+ * Ring audio is owned by [VoipNotification]'s NotificationChannel — do not
34+ * play a ringtone here; a second source would double-ring on most Android versions.
3435 */
3536class IncomingCallActivity : Activity () {
3637
3738 companion object {
3839 private const val TAG = " RocketChat.IncomingCall"
3940 }
4041
41- private var ringtone: Ringtone ? = null
4242 private var voipPayload: VoipPayload ? = null
4343 private var isCallStateReceiverRegistered = false
4444 private val timeoutHandler = Handler (Looper .getMainLooper())
@@ -51,7 +51,6 @@ class IncomingCallActivity : Activity() {
5151 }
5252
5353 clearTimeout()
54- stopRingtone()
5554 finish()
5655 }
5756 }
@@ -97,7 +96,6 @@ class IncomingCallActivity : Activity() {
9796 Log .d(TAG , " IncomingCallActivity created - callId: ${voipPayload.callId} , caller: ${voipPayload.caller} " )
9897
9998 updateUI(voipPayload)
100- startRingtone()
10199 setupButtons(voipPayload)
102100 scheduleTimeout(voipPayload)
103101 val intentFilter = IntentFilter ().apply {
@@ -225,27 +223,6 @@ class IncomingCallActivity : Activity() {
225223 }
226224 }
227225
228- private fun startRingtone () {
229- try {
230- val ringtoneUri = RingtoneManager .getDefaultUri(RingtoneManager .TYPE_RINGTONE )
231- ringtone = RingtoneManager .getRingtone(applicationContext, ringtoneUri)
232- ringtone?.play()
233- Log .d(TAG , " Ringtone started" )
234- } catch (e: Exception ) {
235- Log .e(TAG , " Failed to start ringtone" , e)
236- }
237- }
238-
239- private fun stopRingtone () {
240- try {
241- ringtone?.stop()
242- ringtone = null
243- Log .d(TAG , " Ringtone stopped" )
244- } catch (e: Exception ) {
245- Log .e(TAG , " Failed to stop ringtone" , e)
246- }
247- }
248-
249226 private fun setupButtons (payload : VoipPayload ) {
250227 findViewById<LinearLayout >(R .id.btn_accept)?.setOnClickListener {
251228 handleAccept(payload)
@@ -259,14 +236,12 @@ class IncomingCallActivity : Activity() {
259236 private fun scheduleTimeout (payload : VoipPayload ) {
260237 val remainingLifetimeMs = payload.getRemainingLifetimeMs()
261238 if (remainingLifetimeMs == null || remainingLifetimeMs <= 0L ) {
262- stopRingtone()
263239 finish()
264240 return
265241 }
266242
267243 clearTimeout()
268244 timeoutRunnable = Runnable {
269- stopRingtone()
270245 VoipNotification .handleTimeout(this , payload)
271246 finish()
272247 }.also { timeoutHandler.postDelayed(it, remainingLifetimeMs) }
@@ -281,7 +256,6 @@ class IncomingCallActivity : Activity() {
281256 Log .d(TAG , " Call accepted - callId: ${payload.callId} " )
282257 clearTimeout()
283258 VoipNotification .cancelTimeout(payload.callId)
284- stopRingtone()
285259 VoipNotification .handleAcceptAction(this , payload)
286260 // Activity finishes when ACTION_DISMISS is broadcast from handleAcceptAction (async DDP).
287261 }
@@ -290,7 +264,6 @@ class IncomingCallActivity : Activity() {
290264 Log .d(TAG , " Call declined - callId: ${payload.callId} " )
291265 clearTimeout()
292266 VoipNotification .cancelTimeout(payload.callId)
293- stopRingtone()
294267 VoipNotification .handleDeclineAction(this , payload)
295268
296269 finish()
@@ -303,7 +276,6 @@ class IncomingCallActivity : Activity() {
303276 LocalBroadcastManager .getInstance(this ).unregisterReceiver(callStateReceiver)
304277 isCallStateReceiverRegistered = false
305278 }
306- stopRingtone()
307279 }
308280
309281 override fun onBackPressed () {
0 commit comments