Call: make PiP works with 2 calls

This commit is contained in:
ganfra 2021-08-18 10:52:19 +02:00
parent d3e4a3c010
commit 799cd99176
5 changed files with 100 additions and 74 deletions

View file

@ -93,7 +93,6 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
}
private val callViewModel: VectorCallViewModel by viewModel()
private lateinit var callArgs: CallArgs
@Inject lateinit var callManager: WebRtcCallManager
@Inject lateinit var viewModelFactory: VectorCallViewModel.Factory
@ -123,13 +122,6 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
window.navigationBarColor = Color.BLACK
super.onCreate(savedInstanceState)
if (intent.hasExtra(MvRx.KEY_ARG)) {
callArgs = intent.getParcelableExtra(MvRx.KEY_ARG)!!
} else {
Timber.tag(loggerTag.value).e("missing callArgs for VectorCall Activity")
finish()
}
Timber.tag(loggerTag.value).v("EXTRA_MODE is ${intent.getStringExtra(EXTRA_MODE)}")
if (intent.getStringExtra(EXTRA_MODE) == INCOMING_RINGING) {
turnScreenOnAndKeyguardOff()
@ -152,16 +144,27 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
}
.disposeOnDestroy()
if (callArgs.isVideoCall) {
callViewModel.selectSubscribe(this, VectorCallViewState::callId, VectorCallViewState::isVideoCall) { _, isVideoCall ->
if (isVideoCall) {
if (checkPermissions(PERMISSIONS_FOR_VIDEO_IP_CALL, this, permissionCameraLauncher, R.string.permissions_rationale_msg_camera_and_audio)) {
start()
setupRenderersIfNeeded()
}
} else {
if (checkPermissions(PERMISSIONS_FOR_AUDIO_IP_CALL, this, permissionCameraLauncher, R.string.permissions_rationale_msg_record_audio)) {
start()
setupRenderersIfNeeded()
}
}
}
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
intent?.takeIf { it.hasExtra(MvRx.KEY_ARG) }
?.let { intent.getParcelableExtra<CallArgs>(MvRx.KEY_ARG) }
?.let {
callViewModel.handle(VectorCallViewActions.SwitchCall(it))
}
}
override fun getMenuRes() = R.menu.vector_call
@ -211,13 +214,19 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
}
override fun onDestroy() {
callManager.getCallById(callArgs.callId)?.detachRenderers(listOf(views.pipRenderer, views.fullscreenRenderer))
detachRenderersIfNeeded()
turnScreenOffAndKeyguardOn()
super.onDestroy()
}
private fun detachRenderersIfNeeded() {
val callId = withState(callViewModel) { it.callId }
callManager.getCallById(callId)?.detachRenderers(listOf(views.pipRenderer, views.fullscreenRenderer))
if (surfaceRenderersAreInitialized) {
views.pipRenderer.release()
views.fullscreenRenderer.release()
surfaceRenderersAreInitialized = false
}
turnScreenOffAndKeyguardOn()
super.onDestroy()
}
private fun renderState(state: VectorCallViewState) {
@ -291,7 +300,7 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
configureCallInfo(state)
} else {
configureCallInfo(state)
if (callArgs.isVideoCall) {
if (state.isVideoCall) {
views.fullscreenRenderer.isVisible = true
views.pipRendererWrapper.isVisible = true
views.callInfoGroup.isVisible = false
@ -403,10 +412,13 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
views.otherKnownCallLayout.setOnClickListener {
withState(callViewModel) {
val otherCall = callManager.getCallById(it.otherKnownCallInfo?.callId ?: "") ?: return@withState
startActivity(newIntent(this, otherCall, null))
finish()
val callArgs = CallArgs(otherCall.nativeRoomId, otherCall.callId, otherCall.mxCall.opponentUserId, !otherCall.mxCall.isOutgoing, otherCall.mxCall.isVideoCall)
callViewModel.handle(VectorCallViewActions.SwitchCall(callArgs))
}
}
views.pipRendererWrapper.setOnClickListener {
callViewModel.handle(VectorCallViewActions.ToggleCamera)
}
pipDraggrableView = views.pipRendererWrapper.setupDraggable()
.setStickyMode(DraggableView.Mode.STICKY_XY)
.build()
@ -418,14 +430,15 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
private val permissionCameraLauncher = registerForPermissionsResult { allGranted, _ ->
if (allGranted) {
start()
setupRenderersIfNeeded()
} else {
// TODO display something
finish()
}
}
private fun start() {
private fun setupRenderersIfNeeded() {
detachRenderersIfNeeded()
rootEglBase = EglUtils.rootEglBase ?: return Unit.also {
Timber.tag(loggerTag.value).v("rootEglBase is null")
finish()
@ -443,11 +456,10 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
views.fullscreenRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL)
views.fullscreenRenderer.setEnableHardwareScaler(true /* enabled */)
callManager.getCallById(callArgs.callId)?.attachViewRenderers(views.pipRenderer, views.fullscreenRenderer,
intent.getStringExtra(EXTRA_MODE)?.takeIf { isFirstCreation() })
views.pipRendererWrapper.setOnClickListener {
callViewModel.handle(VectorCallViewActions.ToggleCamera)
val callId = withState(callViewModel) { it.callId }
callManager.getCallById(callId)?.also { webRtcCall ->
webRtcCall.attachViewRenderers(views.pipRenderer, views.fullscreenRenderer, intent.getStringExtra(EXTRA_MODE))
intent.removeExtra(EXTRA_MODE)
}
surfaceRenderersAreInitialized = true
}
@ -467,7 +479,8 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
}.show(supportFragmentManager, FRAGMENT_DIAL_PAD_TAG)
}
is VectorCallViewEvents.ShowCallTransferScreen -> {
navigator.openCallTransfer(this, callArgs.callId)
val callId = withState(callViewModel) { it.callId }
navigator.openCallTransfer(this, callId)
}
null -> {
}
@ -486,39 +499,6 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
.show()
}
companion object {
private const val EXTRA_MODE = "EXTRA_MODE"
private const val FRAGMENT_DIAL_PAD_TAG = "FRAGMENT_DIAL_PAD_TAG"
const val OUTGOING_CREATED = "OUTGOING_CREATED"
const val INCOMING_RINGING = "INCOMING_RINGING"
const val INCOMING_ACCEPT = "INCOMING_ACCEPT"
fun newIntent(context: Context, call: WebRtcCall, mode: String?): Intent {
return Intent(context, VectorCallActivity::class.java).apply {
// what could be the best flags?
flags = Intent.FLAG_ACTIVITY_NEW_TASK
putExtra(MvRx.KEY_ARG, CallArgs(call.nativeRoomId, call.callId, call.mxCall.opponentUserId, !call.mxCall.isOutgoing, call.mxCall.isVideoCall))
putExtra(EXTRA_MODE, mode)
}
}
fun newIntent(context: Context,
callId: String,
signalingRoomId: String,
otherUserId: String,
isIncomingCall: Boolean,
isVideoCall: Boolean,
mode: String?): Intent {
return Intent(context, VectorCallActivity::class.java).apply {
// what could be the best flags?
flags = FLAG_ACTIVITY_CLEAR_TOP
putExtra(MvRx.KEY_ARG, CallArgs(signalingRoomId, callId, otherUserId, isIncomingCall, isVideoCall))
putExtra(EXTRA_MODE, mode)
}
}
}
override fun didTapAudioSettings() {
CallSoundDeviceChooserBottomSheet().show(supportFragmentManager, "SoundDeviceChooser")
}
@ -544,7 +524,8 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
}
private fun returnToChat() {
val args = RoomDetailArgs(callArgs.signalingRoomId)
val roomId = withState(callViewModel) { it.roomId }
val args = RoomDetailArgs(roomId)
val intent = RoomDetailActivity.newIntent(this, args).apply {
flags = FLAG_ACTIVITY_CLEAR_TOP
}
@ -592,4 +573,37 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
)
}
}
companion object {
private const val EXTRA_MODE = "EXTRA_MODE"
private const val FRAGMENT_DIAL_PAD_TAG = "FRAGMENT_DIAL_PAD_TAG"
const val OUTGOING_CREATED = "OUTGOING_CREATED"
const val INCOMING_RINGING = "INCOMING_RINGING"
const val INCOMING_ACCEPT = "INCOMING_ACCEPT"
fun newIntent(context: Context, call: WebRtcCall, mode: String?): Intent {
return Intent(context, VectorCallActivity::class.java).apply {
// what could be the best flags?
flags = Intent.FLAG_ACTIVITY_NEW_TASK
putExtra(MvRx.KEY_ARG, CallArgs(call.nativeRoomId, call.callId, call.mxCall.opponentUserId, !call.mxCall.isOutgoing, call.mxCall.isVideoCall))
putExtra(EXTRA_MODE, mode)
}
}
fun newIntent(context: Context,
callId: String,
signalingRoomId: String,
otherUserId: String,
isIncomingCall: Boolean,
isVideoCall: Boolean,
mode: String?): Intent {
return Intent(context, VectorCallActivity::class.java).apply {
// what could be the best flags?
flags = Intent.FLAG_ACTIVITY_NEW_TASK
putExtra(MvRx.KEY_ARG, CallArgs(signalingRoomId, callId, otherUserId, isIncomingCall, isVideoCall))
putExtra(EXTRA_MODE, mode)
}
}
}
}

View file

@ -29,6 +29,8 @@ sealed class VectorCallViewActions : VectorViewModelAction {
data class ChangeAudioDevice(val device: CallAudioManager.Device) : VectorCallViewActions()
object OpenDialPad: VectorCallViewActions()
data class SendDtmfDigit(val digit: String) : VectorCallViewActions()
data class SwitchCall(val callArgs: CallArgs) : VectorCallViewActions()
object SwitchSoundDevice : VectorCallViewActions()
object HeadSetButtonPressed : VectorCallViewActions()
object ToggleCamera : VectorCallViewActions()

View file

@ -174,7 +174,12 @@ class VectorCallViewModel @AssistedInject constructor(
}
init {
val webRtcCall = callManager.getCallById(initialState.callId)
setupCallWithCurrentState()
}
private fun setupCallWithCurrentState() = withState { state ->
call?.removeListener(callListener)
val webRtcCall = callManager.getCallById(state.callId)
if (webRtcCall == null) {
setState {
copy(callState = Fail(IllegalArgumentException("No call")))
@ -229,6 +234,7 @@ class VectorCallViewModel @AssistedInject constructor(
override fun onCleared() {
callManager.removeCurrentCallListener(currentCallListener)
call?.removeListener(callListener)
call = null
proximityManager.stop()
super.onCleared()
}
@ -309,6 +315,10 @@ class VectorCallViewModel @AssistedInject constructor(
VectorCallViewActions.TransferCall -> {
handleCallTransfer()
}
is VectorCallViewActions.SwitchCall -> {
setState { VectorCallViewState(action.callArgs) }
setupCallWithCurrentState()
}
}.exhaustive
}

View file

@ -348,7 +348,7 @@ class WebRtcCall(
fun attachViewRenderers(localViewRenderer: SurfaceViewRenderer?, remoteViewRenderer: SurfaceViewRenderer, mode: String?) {
sessionScope?.launch(dispatcher) {
Timber.tag(loggerTag.value).v("attachViewRenderers localRendeder $localViewRenderer / $remoteViewRenderer")
Timber.tag(loggerTag.value).v("attachViewRenderers localRenderer $localViewRenderer / $remoteViewRenderer")
localSurfaceRenderers.addIfNeeded(localViewRenderer)
remoteSurfaceRenderers.addIfNeeded(remoteViewRenderer)
when (mode) {

View file

@ -358,7 +358,7 @@ class NoticeEventFormatter @Inject constructor(
}
EventType.CALL_REJECT ->
if (event.isSentByCurrentUser()) {
sp.getString(R.string.call_tile_you_declined)
sp.getString(R.string.call_tile_you_declined,"")
} else {
sp.getString(R.string.call_tile_other_declined, senderName)
}