mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-26 19:36:08 +03:00
Show the foreground service for incoming and outgoing calls.
This commit is contained in:
parent
fb6bcc8470
commit
5d476e7259
11 changed files with 69 additions and 68 deletions
|
@ -41,7 +41,7 @@ interface CallsListener {
|
|||
// */
|
||||
// fun onCallHangUp(peerSignalingClient: PeerSignalingClient)
|
||||
|
||||
fun onCallInviteReceived(signalingRoomId: String, callInviteContent: CallInviteContent)
|
||||
fun onCallInviteReceived(signalingRoomId: String, participantUserId: String, callInviteContent: CallInviteContent)
|
||||
|
||||
fun onCallAnswerReceived(callAnswerContent: CallAnswerContent)
|
||||
|
||||
|
|
|
@ -144,7 +144,7 @@ internal class DefaultCallService @Inject constructor(
|
|||
}
|
||||
EventType.CALL_INVITE -> {
|
||||
event.getClearContent().toModel<CallInviteContent>()?.let {
|
||||
onCallInvite(event.roomId ?: "", it)
|
||||
onCallInvite(event.roomId ?: "", event.senderId ?: "", it)
|
||||
}
|
||||
}
|
||||
EventType.CALL_HANGUP -> {
|
||||
|
@ -171,10 +171,12 @@ internal class DefaultCallService @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun onCallInvite(roomId: String, answer: CallInviteContent) {
|
||||
private fun onCallInvite(roomId: String, userId: String, answer: CallInviteContent) {
|
||||
if (userId == this.userId) return
|
||||
|
||||
callListeners.forEach {
|
||||
tryThis {
|
||||
it.onCallInviteReceived(roomId, answer)
|
||||
it.onCallInviteReceived(roomId, userId, answer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@ import im.vector.riotx.core.utils.PERMISSION_REQUEST_CODE_LAUNCH_CAMERA
|
|||
import im.vector.riotx.core.utils.allGranted
|
||||
import im.vector.riotx.core.utils.checkPermissions
|
||||
import im.vector.riotx.core.utils.toast
|
||||
import im.vector.riotx.features.call.VectorCallActivity
|
||||
import im.vector.riotx.features.debug.sas.DebugSasEmojiActivity
|
||||
import im.vector.riotx.features.qrcode.QrCodeScannerActivity
|
||||
import kotlinx.android.synthetic.debug.activity_debug_menu.*
|
||||
|
@ -185,7 +184,8 @@ class DebugMenuActivity : VectorBaseActivity() {
|
|||
fun scanQRCode() {
|
||||
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, this, PERMISSION_REQUEST_CODE_LAUNCH_CAMERA)) {
|
||||
// doScanQRCode()
|
||||
startActivity(VectorCallActivity.newIntent(this, "!cyIJhOLwWgmmqreHLD:matrix.org"))
|
||||
// TODO. Find a better way?
|
||||
//startActivity(VectorCallActivity.newIntent(this, "!cyIJhOLwWgmmqreHLD:matrix.org"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
intent action. -->
|
||||
|
||||
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||
|
||||
<!-- Adding CAMERA permission prevents Chromebooks to see the application on the PlayStore -->
|
||||
<!-- Tell that the Camera is not mandatory to install the application -->
|
||||
|
|
|
@ -69,7 +69,7 @@ class VectorCallViewModel @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun onCallInviteReceived(signalingRoomId: String, callInviteContent: CallInviteContent) {
|
||||
override fun onCallInviteReceived(signalingRoomId: String, participantUserId: String, callInviteContent: CallInviteContent) {
|
||||
}
|
||||
|
||||
override fun onCallHangupReceived(callHangupContent: CallHangupContent) {
|
||||
|
|
|
@ -19,21 +19,16 @@ package im.vector.riotx.features.call
|
|||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.drawable.Icon
|
||||
import android.os.Build
|
||||
import android.telecom.PhoneAccount
|
||||
import android.telecom.PhoneAccountHandle
|
||||
import android.telecom.TelecomManager
|
||||
import android.content.ServiceConnection
|
||||
import android.os.IBinder
|
||||
import androidx.core.content.ContextCompat
|
||||
import im.vector.matrix.android.api.session.call.CallsListener
|
||||
import im.vector.matrix.android.api.session.call.EglUtils
|
||||
import im.vector.matrix.android.api.session.room.model.call.CallAnswerContent
|
||||
import im.vector.matrix.android.api.session.room.model.call.CallHangupContent
|
||||
import im.vector.matrix.android.api.session.room.model.call.CallInviteContent
|
||||
import im.vector.riotx.BuildConfig
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ActiveSessionHolder
|
||||
import im.vector.riotx.features.call.service.CallHeadsUpService
|
||||
import im.vector.riotx.features.call.telecom.VectorConnectionService
|
||||
import org.webrtc.AudioSource
|
||||
import org.webrtc.AudioTrack
|
||||
import org.webrtc.DefaultVideoDecoderFactory
|
||||
|
@ -62,8 +57,9 @@ import javax.inject.Singleton
|
|||
*/
|
||||
@Singleton
|
||||
class WebRtcPeerConnectionManager @Inject constructor(
|
||||
private val context: Context
|
||||
) : CallsListener {
|
||||
private val context: Context,
|
||||
private val sessionHolder: ActiveSessionHolder
|
||||
) : CallsListener {
|
||||
|
||||
interface Listener {
|
||||
fun addLocalIceCandidate(candidates: IceCandidate)
|
||||
|
@ -74,27 +70,8 @@ class WebRtcPeerConnectionManager @Inject constructor(
|
|||
fun sendOffer(sessionDescription: SessionDescription)
|
||||
}
|
||||
|
||||
var phoneAccountHandle: PhoneAccountHandle? = null
|
||||
var localMediaStream: MediaStream? = null
|
||||
|
||||
init {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
val componentName = ComponentName(BuildConfig.APPLICATION_ID, VectorConnectionService::class.java.name)
|
||||
val appName = context.getString(R.string.app_name)
|
||||
phoneAccountHandle = PhoneAccountHandle(componentName, appName)
|
||||
val phoneAccount = PhoneAccount.Builder(phoneAccountHandle, BuildConfig.APPLICATION_ID)
|
||||
.setIcon(Icon.createWithResource(context, R.drawable.riotx_logo))
|
||||
.setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)
|
||||
.setCapabilities(PhoneAccount.CAPABILITY_VIDEO_CALLING)
|
||||
.setCapabilities(PhoneAccount.CAPABILITY_CALL_SUBJECT)
|
||||
.build()
|
||||
ContextCompat.getSystemService(context, TelecomManager::class.java)
|
||||
?.registerPhoneAccount(phoneAccount)
|
||||
} else {
|
||||
// ignore?
|
||||
}
|
||||
}
|
||||
|
||||
var listener: Listener? = null
|
||||
|
||||
// *Comments copied from webrtc demo app*
|
||||
|
@ -121,6 +98,17 @@ class WebRtcPeerConnectionManager @Inject constructor(
|
|||
var localSurfaceRenderer: WeakReference<SurfaceViewRenderer>? = null
|
||||
var remoteSurfaceRenderer: WeakReference<SurfaceViewRenderer>? = null
|
||||
|
||||
var callHeadsUpService: CallHeadsUpService? = null
|
||||
|
||||
private val serviceConnection = object : ServiceConnection {
|
||||
override fun onServiceDisconnected(name: ComponentName?) {
|
||||
}
|
||||
|
||||
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
||||
callHeadsUpService = (service as? CallHeadsUpService.CallHeadsUpServiceBinder)?.getService()
|
||||
}
|
||||
}
|
||||
|
||||
fun createPeerConnectionFactory() {
|
||||
executor.execute {
|
||||
if (peerConnectionFactory == null) {
|
||||
|
@ -331,6 +319,7 @@ class WebRtcPeerConnectionManager @Inject constructor(
|
|||
peerConnectionFactory?.stopAecDump()
|
||||
peerConnectionFactory = null
|
||||
}
|
||||
context.stopService(Intent(context, CallHeadsUpService::class.java))
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@ -356,27 +345,20 @@ class WebRtcPeerConnectionManager @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun onCallInviteReceived(signalingRoomId: String, callInviteContent: CallInviteContent) {
|
||||
val callHeadsUpServiceIntent = Intent(context, CallHeadsUpService::class.java)
|
||||
fun startOutgoingCall(context: Context, signalingRoomId: String, participantUserId: String, isVideoCall: Boolean) {
|
||||
startHeadsUpService(signalingRoomId, sessionHolder.getActiveSession().myUserId, false, isVideoCall)
|
||||
context.startActivity(VectorCallActivity.newIntent(context, signalingRoomId, participantUserId, false, isVideoCall))
|
||||
}
|
||||
|
||||
override fun onCallInviteReceived(signalingRoomId: String, participantUserId: String, callInviteContent: CallInviteContent) {
|
||||
startHeadsUpService(signalingRoomId, participantUserId, true, callInviteContent.isVideo())
|
||||
}
|
||||
|
||||
private fun startHeadsUpService(roomId: String, participantUserId: String, isIncomingCall: Boolean, isVideoCall: Boolean) {
|
||||
val callHeadsUpServiceIntent = CallHeadsUpService.newInstance(context, roomId, participantUserId, isIncomingCall, isVideoCall)
|
||||
ContextCompat.startForegroundService(context, callHeadsUpServiceIntent)
|
||||
/*
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
ContextCompat.getSystemService(context, TelecomManager::class.java)?.let { telecomManager ->
|
||||
phoneAccountHandle?.let { phoneAccountHandle ->
|
||||
telecomManager.addNewIncomingCall(
|
||||
phoneAccountHandle,
|
||||
Bundle().apply {
|
||||
putString("MX_CALL_ROOM_ID", signalingRoomId)
|
||||
putString("MX_CALL_CALL_ID", callInviteContent.callId)
|
||||
putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle)
|
||||
putInt(TelecomManager.EXTRA_INCOMING_VIDEO_STATE, VideoProfile.STATE_BIDIRECTIONAL)
|
||||
putInt(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, VideoProfile.STATE_BIDIRECTIONAL)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
context.bindService(Intent(context, CallHeadsUpService::class.java), serviceConnection, 0)
|
||||
}
|
||||
|
||||
override fun onCallAnswerReceived(callAnswerContent: CallAnswerContent) {
|
||||
|
|
|
@ -21,7 +21,8 @@ import kotlinx.android.parcel.Parcelize
|
|||
|
||||
@Parcelize
|
||||
data class CallHeadsUpServiceArgs(
|
||||
val callerDisplayName: String,
|
||||
val roomId: String,
|
||||
val participantUserId: String,
|
||||
val isIncomingCall: Boolean,
|
||||
val isVideoCall: Boolean
|
||||
) : Parcelable
|
||||
|
|
|
@ -127,7 +127,7 @@ import im.vector.riotx.features.attachments.ContactAttachment
|
|||
import im.vector.riotx.features.attachments.preview.AttachmentsPreviewActivity
|
||||
import im.vector.riotx.features.attachments.preview.AttachmentsPreviewArgs
|
||||
import im.vector.riotx.features.attachments.toGroupedContentAttachmentData
|
||||
import im.vector.riotx.features.call.service.CallHeadsUpService
|
||||
import im.vector.riotx.features.call.WebRtcPeerConnectionManager
|
||||
import im.vector.riotx.features.command.Command
|
||||
import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreActivity
|
||||
import im.vector.riotx.features.crypto.util.toImageRes
|
||||
|
@ -197,7 +197,8 @@ class RoomDetailFragment @Inject constructor(
|
|||
val roomDetailViewModelFactory: RoomDetailViewModel.Factory,
|
||||
private val eventHtmlRenderer: EventHtmlRenderer,
|
||||
private val vectorPreferences: VectorPreferences,
|
||||
private val colorProvider: ColorProvider) :
|
||||
private val colorProvider: ColorProvider,
|
||||
private val webRtcPeerConnectionManager: WebRtcPeerConnectionManager) :
|
||||
VectorBaseFragment(),
|
||||
TimelineEventController.Callback,
|
||||
VectorInviteView.Callback,
|
||||
|
@ -484,14 +485,10 @@ class RoomDetailFragment @Inject constructor(
|
|||
roomDetailViewModel.handle(RoomDetailAction.ResendAll)
|
||||
return true
|
||||
}
|
||||
if (item.itemId == R.id.voip_call) {
|
||||
/*
|
||||
VectorCallActivity.newIntent(requireContext(), roomDetailArgs.roomId).let {
|
||||
startActivity(it)
|
||||
if (item.itemId == R.id.voice_call || item.itemId == R.id.video_call) {
|
||||
roomDetailViewModel.getOtherUserIds()?.firstOrNull()?.let {
|
||||
webRtcPeerConnectionManager.startOutgoingCall(requireContext(), roomDetailArgs.roomId, it, item.itemId == R.id.video_call)
|
||||
}
|
||||
*/
|
||||
val callHeadsUpServiceIntent = Intent(requireContext(), CallHeadsUpService::class.java)
|
||||
ContextCompat.startForegroundService(requireContext(), callHeadsUpServiceIntent)
|
||||
return true
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
|
|
|
@ -213,6 +213,8 @@ class RoomDetailViewModel @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun getOtherUserIds() = room.roomSummary()?.otherMemberIds
|
||||
|
||||
override fun handle(action: RoomDetailAction) {
|
||||
when (action) {
|
||||
is RoomDetailAction.UserIsTyping -> handleUserIsTyping(action)
|
||||
|
@ -366,7 +368,7 @@ class RoomDetailViewModel @AssistedInject constructor(
|
|||
}
|
||||
|
||||
fun isMenuItemVisible(@IdRes itemId: Int) = when (itemId) {
|
||||
R.id.clear_message_queue ->
|
||||
R.id.clear_message_queue ->
|
||||
/* For now always disable on production, worker cancellation is not working properly */
|
||||
timeline.pendingEventCount() > 0 && vectorPreferences.developerMode()
|
||||
R.id.resend_all -> timeline.failedToDeliverEventCount() > 0
|
||||
|
|
|
@ -2,6 +2,13 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<item
|
||||
android:id="@+id/video_call"
|
||||
android:icon="@drawable/ic_videocam"
|
||||
android:title="@string/action_video_call"
|
||||
android:visible="false"
|
||||
app:showAsAction="always"
|
||||
tools:visible="true" />
|
||||
|
||||
<item
|
||||
android:id="@+id/open_matrix_apps"
|
||||
|
|
|
@ -190,5 +190,14 @@
|
|||
<color name="riotx_keys_backup_banner_accent_color_light">#FFF8E3</color>
|
||||
<color name="riotx_keys_backup_banner_accent_color_dark">#22262E</color>
|
||||
|
||||
<attr name="riotx_call_actions_bg_gradient_start" format="color" />
|
||||
<color name="riotx_call_actions_bg_gradient_start_light">#000000</color>
|
||||
<color name="riotx_call_actions_bg_gradient_start_dark">#000000</color>
|
||||
<color name="riotx_call_actions_bg_gradient_start_black">#000000</color>
|
||||
|
||||
<attr name="riotx_call_actions_bg_gradient_end" format="color" />
|
||||
<color name="riotx_call_actions_bg_gradient_end_light">@android:color/transparent</color>
|
||||
<color name="riotx_call_actions_bg_gradient_end_dark">@android:color/transparent</color>
|
||||
<color name="riotx_call_actions_bg_gradient_end_black">@android:color/transparent</color>
|
||||
|
||||
</resources>
|
Loading…
Reference in a new issue