mirror of
https://github.com/element-hq/element-android
synced 2024-11-28 05:31:21 +03:00
Call transfer: prepare code for consult feature
This commit is contained in:
parent
a9c61dc309
commit
8eeae51cc6
8 changed files with 75 additions and 11 deletions
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.matrix.android.sdk.api.session.call
|
||||||
|
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
object CallIdGenerator {
|
||||||
|
fun generate() = UUID.randomUUID().toString()
|
||||||
|
}
|
|
@ -92,7 +92,10 @@ interface MxCall : MxCallDetail {
|
||||||
/**
|
/**
|
||||||
* Send a m.call.replaces event to initiate call transfer.
|
* Send a m.call.replaces event to initiate call transfer.
|
||||||
*/
|
*/
|
||||||
suspend fun transfer(targetUserId: String, targetRoomId: String?)
|
suspend fun transfer(targetUserId: String,
|
||||||
|
targetRoomId: String?,
|
||||||
|
createCallId: String?,
|
||||||
|
awaitCallId: String?)
|
||||||
|
|
||||||
fun addListener(listener: StateListener)
|
fun addListener(listener: StateListener)
|
||||||
fun removeListener(listener: StateListener)
|
fun removeListener(listener: StateListener)
|
||||||
|
|
|
@ -56,6 +56,9 @@ data class CallHangupContent(
|
||||||
@Json(name = "user_hangup")
|
@Json(name = "user_hangup")
|
||||||
USER_HANGUP,
|
USER_HANGUP,
|
||||||
|
|
||||||
|
@Json(name = "replaced")
|
||||||
|
REPLACED,
|
||||||
|
|
||||||
@Json(name = "user_media_failed")
|
@Json(name = "user_media_failed")
|
||||||
USER_MEDIA_FAILED,
|
USER_MEDIA_FAILED,
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ data class CallReplacesContent(
|
||||||
* (possibly waiting for user confirmation) and then continues the transfer in this room.
|
* (possibly waiting for user confirmation) and then continues the transfer in this room.
|
||||||
* If absent, the transferee contacts the Matrix User ID given in the target_user field in a room of its choosing.
|
* If absent, the transferee contacts the Matrix User ID given in the target_user field in a room of its choosing.
|
||||||
*/
|
*/
|
||||||
@Json(name = "target_room") val targerRoomId: String? = null,
|
@Json(name = "target_room") val targetRoomId: String? = null,
|
||||||
/**
|
/**
|
||||||
* An object giving information about the transfer target
|
* An object giving information about the transfer target
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
package org.matrix.android.sdk.internal.session.call
|
package org.matrix.android.sdk.internal.session.call
|
||||||
|
|
||||||
import org.matrix.android.sdk.api.MatrixConfiguration
|
import org.matrix.android.sdk.api.MatrixConfiguration
|
||||||
|
import org.matrix.android.sdk.api.session.call.CallIdGenerator
|
||||||
import org.matrix.android.sdk.api.session.call.MxCall
|
import org.matrix.android.sdk.api.session.call.MxCall
|
||||||
import org.matrix.android.sdk.api.session.room.model.call.CallCapabilities
|
import org.matrix.android.sdk.api.session.room.model.call.CallCapabilities
|
||||||
import org.matrix.android.sdk.api.session.room.model.call.CallInviteContent
|
import org.matrix.android.sdk.api.session.room.model.call.CallInviteContent
|
||||||
|
@ -63,7 +64,7 @@ internal class MxCallFactory @Inject constructor(
|
||||||
|
|
||||||
fun createOutgoingCall(roomId: String, opponentUserId: String, isVideoCall: Boolean): MxCall {
|
fun createOutgoingCall(roomId: String, opponentUserId: String, isVideoCall: Boolean): MxCall {
|
||||||
return MxCallImpl(
|
return MxCallImpl(
|
||||||
callId = UUID.randomUUID().toString(),
|
callId = CallIdGenerator.generate(),
|
||||||
isOutgoing = true,
|
isOutgoing = true,
|
||||||
roomId = roomId,
|
roomId = roomId,
|
||||||
userId = userId,
|
userId = userId,
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
package org.matrix.android.sdk.internal.session.call.model
|
package org.matrix.android.sdk.internal.session.call.model
|
||||||
|
|
||||||
import org.matrix.android.sdk.api.MatrixConfiguration
|
import org.matrix.android.sdk.api.MatrixConfiguration
|
||||||
|
import org.matrix.android.sdk.api.session.call.CallIdGenerator
|
||||||
import org.matrix.android.sdk.api.session.call.CallState
|
import org.matrix.android.sdk.api.session.call.CallState
|
||||||
import org.matrix.android.sdk.api.session.call.MxCall
|
import org.matrix.android.sdk.api.session.call.MxCall
|
||||||
import org.matrix.android.sdk.api.session.events.model.Content
|
import org.matrix.android.sdk.api.session.events.model.Content
|
||||||
|
@ -202,7 +203,10 @@ internal class MxCallImpl(
|
||||||
.also { eventSenderProcessor.postEvent(it) }
|
.also { eventSenderProcessor.postEvent(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun transfer(targetUserId: String, targetRoomId: String?) {
|
override suspend fun transfer(targetUserId: String,
|
||||||
|
targetRoomId: String?,
|
||||||
|
createCallId: String?,
|
||||||
|
awaitCallId: String?) {
|
||||||
val profileInfoParams = GetProfileInfoTask.Params(targetUserId)
|
val profileInfoParams = GetProfileInfoTask.Params(targetUserId)
|
||||||
val profileInfo = try {
|
val profileInfo = try {
|
||||||
getProfileInfoTask.execute(profileInfoParams)
|
getProfileInfoTask.execute(profileInfoParams)
|
||||||
|
@ -213,15 +217,16 @@ internal class MxCallImpl(
|
||||||
CallReplacesContent(
|
CallReplacesContent(
|
||||||
callId = callId,
|
callId = callId,
|
||||||
partyId = ourPartyId,
|
partyId = ourPartyId,
|
||||||
replacementId = UUID.randomUUID().toString(),
|
replacementId = CallIdGenerator.generate(),
|
||||||
version = MxCall.VOIP_PROTO_VERSION.toString(),
|
version = MxCall.VOIP_PROTO_VERSION.toString(),
|
||||||
targetUser = CallReplacesContent.TargetUser(
|
targetUser = CallReplacesContent.TargetUser(
|
||||||
id = targetUserId,
|
id = targetUserId,
|
||||||
displayName = profileInfo?.get(ProfileService.DISPLAY_NAME_KEY) as? String,
|
displayName = profileInfo?.get(ProfileService.DISPLAY_NAME_KEY) as? String,
|
||||||
avatarUrl = profileInfo?.get(ProfileService.AVATAR_URL_KEY) as? String
|
avatarUrl = profileInfo?.get(ProfileService.AVATAR_URL_KEY) as? String
|
||||||
),
|
),
|
||||||
targerRoomId = targetRoomId,
|
targetRoomId = targetRoomId,
|
||||||
createCall = UUID.randomUUID().toString()
|
awaitCall = awaitCallId,
|
||||||
|
createCall = createCallId
|
||||||
)
|
)
|
||||||
.let { createEventAndLocalEcho(type = EventType.CALL_REPLACES, roomId = roomId, content = it.toContent()) }
|
.let { createEventAndLocalEcho(type = EventType.CALL_REPLACES, roomId = roomId, content = it.toContent()) }
|
||||||
.also { eventSenderProcessor.postEvent(it) }
|
.also { eventSenderProcessor.postEvent(it) }
|
||||||
|
|
|
@ -75,7 +75,7 @@ class CallTransferViewModel @AssistedInject constructor(@Assisted initialState:
|
||||||
|
|
||||||
override fun handle(action: CallTransferAction) {
|
override fun handle(action: CallTransferAction) {
|
||||||
when (action) {
|
when (action) {
|
||||||
is CallTransferAction.ConnectWithUserId -> connectWithUserId(action)
|
is CallTransferAction.ConnectWithUserId -> connectWithUserId(action)
|
||||||
is CallTransferAction.ConnectWithPhoneNumber -> connectWithPhoneNumber(action)
|
is CallTransferAction.ConnectWithPhoneNumber -> connectWithPhoneNumber(action)
|
||||||
}.exhaustive
|
}.exhaustive
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ class CallTransferViewModel @AssistedInject constructor(@Assisted initialState:
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
try {
|
try {
|
||||||
_viewEvents.post(CallTransferViewEvents.Loading)
|
_viewEvents.post(CallTransferViewEvents.Loading)
|
||||||
call?.mxCall?.transfer(action.selectedUserId, null)
|
call?.transferToUser(action.selectedUserId, null)
|
||||||
_viewEvents.post(CallTransferViewEvents.Dismiss)
|
_viewEvents.post(CallTransferViewEvents.Dismiss)
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
_viewEvents.post(CallTransferViewEvents.FailToTransfer)
|
_viewEvents.post(CallTransferViewEvents.FailToTransfer)
|
||||||
|
@ -97,7 +97,7 @@ class CallTransferViewModel @AssistedInject constructor(@Assisted initialState:
|
||||||
try {
|
try {
|
||||||
_viewEvents.post(CallTransferViewEvents.Loading)
|
_viewEvents.post(CallTransferViewEvents.Loading)
|
||||||
val result = dialPadLookup.lookupPhoneNumber(action.phoneNumber)
|
val result = dialPadLookup.lookupPhoneNumber(action.phoneNumber)
|
||||||
call?.mxCall?.transfer(result.userId, result.roomId)
|
call?.transferToUser(result.userId, result.roomId)
|
||||||
_viewEvents.post(CallTransferViewEvents.Dismiss)
|
_viewEvents.post(CallTransferViewEvents.Dismiss)
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
_viewEvents.post(CallTransferViewEvents.FailToTransfer)
|
_viewEvents.post(CallTransferViewEvents.FailToTransfer)
|
||||||
|
|
|
@ -45,6 +45,7 @@ import kotlinx.coroutines.withContext
|
||||||
import org.matrix.android.sdk.api.extensions.orFalse
|
import org.matrix.android.sdk.api.extensions.orFalse
|
||||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
|
import org.matrix.android.sdk.api.session.call.CallIdGenerator
|
||||||
import org.matrix.android.sdk.api.session.call.CallState
|
import org.matrix.android.sdk.api.session.call.CallState
|
||||||
import org.matrix.android.sdk.api.session.call.MxCall
|
import org.matrix.android.sdk.api.session.call.MxCall
|
||||||
import org.matrix.android.sdk.api.session.call.MxPeerConnectionState
|
import org.matrix.android.sdk.api.session.call.MxPeerConnectionState
|
||||||
|
@ -268,7 +269,7 @@ class WebRtcCall(val mxCall: MxCall,
|
||||||
|
|
||||||
sessionScope?.launch(dispatcher) {
|
sessionScope?.launch(dispatcher) {
|
||||||
when (mode) {
|
when (mode) {
|
||||||
VectorCallActivity.INCOMING_ACCEPT -> {
|
VectorCallActivity.INCOMING_ACCEPT -> {
|
||||||
internalAcceptIncomingCall()
|
internalAcceptIncomingCall()
|
||||||
}
|
}
|
||||||
VectorCallActivity.INCOMING_RINGING -> {
|
VectorCallActivity.INCOMING_RINGING -> {
|
||||||
|
@ -286,6 +287,34 @@ class WebRtcCall(val mxCall: MxCall,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun transferToUser(targetUserId: String, targetRoomId: String?) {
|
||||||
|
mxCall.transfer(
|
||||||
|
targetUserId = targetUserId,
|
||||||
|
targetRoomId = targetRoomId,
|
||||||
|
createCallId = CallIdGenerator.generate(),
|
||||||
|
awaitCallId = null
|
||||||
|
)
|
||||||
|
endCall(true, CallHangupContent.Reason.REPLACED)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun transferToCall(transferTargetCall: WebRtcCall) {
|
||||||
|
val newCallId = CallIdGenerator.generate()
|
||||||
|
transferTargetCall.mxCall.transfer(
|
||||||
|
targetUserId = this.mxCall.opponentUserId,
|
||||||
|
targetRoomId = null,
|
||||||
|
createCallId = null,
|
||||||
|
awaitCallId = newCallId
|
||||||
|
)
|
||||||
|
this.mxCall.transfer(
|
||||||
|
transferTargetCall.mxCall.opponentUserId,
|
||||||
|
targetRoomId = null,
|
||||||
|
createCallId = newCallId,
|
||||||
|
awaitCallId = null
|
||||||
|
)
|
||||||
|
endCall(true, CallHangupContent.Reason.REPLACED)
|
||||||
|
transferTargetCall.endCall(true, CallHangupContent.Reason.REPLACED)
|
||||||
|
}
|
||||||
|
|
||||||
fun acceptIncomingCall() {
|
fun acceptIncomingCall() {
|
||||||
sessionScope?.launch {
|
sessionScope?.launch {
|
||||||
Timber.v("## VOIP acceptIncomingCall from state ${mxCall.state}")
|
Timber.v("## VOIP acceptIncomingCall from state ${mxCall.state}")
|
||||||
|
|
Loading…
Reference in a new issue