mirror of
https://gitlab.linphone.org/BC/public/linphone-android.git
synced 2026-01-17 11:28:06 +00:00
Added early media advanced settings + added video views in incoming/outgoing call fragments to see/capture early media video if any
This commit is contained in:
parent
17e3622bdc
commit
00fbfcc490
17 changed files with 398 additions and 144 deletions
|
|
@ -126,6 +126,20 @@ class CorePreferences
|
|||
config.setBool("app", "show_confirmation_dialog_zrtp_trust_call", value)
|
||||
}
|
||||
|
||||
@get:WorkerThread @set:WorkerThread
|
||||
var acceptEarlyMedia: Boolean
|
||||
get() = config.getBool("sip", "incoming_calls_early_media", false)
|
||||
set(value) {
|
||||
config.setBool("sip", "incoming_calls_early_media", value)
|
||||
}
|
||||
|
||||
@get:WorkerThread @set:WorkerThread
|
||||
var allowOutgoingEarlyMedia: Boolean
|
||||
get() = config.getBool("misc", "real_early_media", false)
|
||||
set(value) {
|
||||
config.setBool("misc", "real_early_media", value)
|
||||
}
|
||||
|
||||
// Conversation related
|
||||
|
||||
var markConversationAsReadWhenDismissingMessageNotification: Boolean
|
||||
|
|
|
|||
|
|
@ -492,7 +492,7 @@ class CallActivity : GenericActivity() {
|
|||
}
|
||||
|
||||
private fun hideUI(hide: Boolean) {
|
||||
Log.i("$TAG Switching full screen mode to ${if (hide) "ON" else "OFF"}")
|
||||
Log.i("$TAG Switching full screen mode to [${if (hide) "ON" else "OFF"}]")
|
||||
val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
|
||||
if (hide) {
|
||||
windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
|
||||
|
|
|
|||
|
|
@ -19,14 +19,12 @@
|
|||
*/
|
||||
package org.linphone.ui.call.conference.fragment
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.os.SystemClock
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
|
|
@ -78,33 +76,6 @@ class ActiveConferenceCallFragment : GenericCallFragment() {
|
|||
override fun onSlide(bottomSheet: View, slideOffset: Float) { }
|
||||
}
|
||||
|
||||
// For moving video preview purposes
|
||||
|
||||
private var previewX: Float = 0f
|
||||
private var previewY: Float = 0f
|
||||
|
||||
private val previewTouchListener = View.OnTouchListener { view, event ->
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
previewX = view.x - event.rawX
|
||||
previewY = view.y - event.rawY
|
||||
true
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
view.animate()
|
||||
.x(event.rawX + previewX)
|
||||
.y(event.rawY + previewY)
|
||||
.setDuration(0)
|
||||
.start()
|
||||
true
|
||||
}
|
||||
else -> {
|
||||
view.performClick()
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val backPressedCallback = object : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
val actionsBottomSheetBehavior = BottomSheetBehavior.from(binding.bottomBar.root)
|
||||
|
|
@ -329,23 +300,21 @@ class ActiveConferenceCallFragment : GenericCallFragment() {
|
|||
)
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
coreContext.postOnCoreThread {
|
||||
binding.localPreviewVideoSurface.setOnTouchListener(previewTouchListener)
|
||||
setupVideoPreview(binding.localPreviewVideoSurface)
|
||||
|
||||
coreContext.postOnCoreThread {
|
||||
// Need to be done manually
|
||||
callViewModel.updateCallDuration()
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
|
||||
binding.localPreviewVideoSurface.setOnTouchListener(null)
|
||||
cleanVideoPreview(binding.localPreviewVideoSurface)
|
||||
}
|
||||
|
||||
private fun updateHingeRelatedConstraints(feature: FoldingFeature) {
|
||||
|
|
|
|||
|
|
@ -19,12 +19,10 @@
|
|||
*/
|
||||
package org.linphone.ui.call.fragment
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import android.os.SystemClock
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.animation.Animation
|
||||
|
|
@ -67,33 +65,6 @@ class ActiveCallFragment : GenericCallFragment() {
|
|||
|
||||
private var zrtpSasDialog: Dialog? = null
|
||||
|
||||
// For moving video preview purposes
|
||||
|
||||
private var previewX: Float = 0f
|
||||
private var previewY: Float = 0f
|
||||
|
||||
private val previewTouchListener = View.OnTouchListener { view, event ->
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
previewX = view.x - event.rawX
|
||||
previewY = view.y - event.rawY
|
||||
true
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
view.animate()
|
||||
.x(event.rawX + previewX)
|
||||
.y(event.rawY + previewY)
|
||||
.setDuration(0)
|
||||
.start()
|
||||
true
|
||||
}
|
||||
else -> {
|
||||
view.performClick()
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val actionsBottomSheetCallback = object : BottomSheetBehavior.BottomSheetCallback() {
|
||||
override fun onStateChanged(bottomSheet: View, newState: Int) {
|
||||
if (newState == BottomSheetBehavior.STATE_EXPANDED) {
|
||||
|
|
@ -253,7 +224,7 @@ class ActiveCallFragment : GenericCallFragment() {
|
|||
}
|
||||
|
||||
callViewModel.fullScreenMode.observe(viewLifecycleOwner) { hide ->
|
||||
Log.i("$TAG Switching full screen mode to ${if (hide) "ON" else "OFF"}")
|
||||
Log.i("$TAG Switching full screen mode to [${if (hide) "ON" else "OFF"}]")
|
||||
sharedViewModel.toggleFullScreenEvent.value = Event(hide)
|
||||
numpadBottomSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
callStatsBottomSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
|
|
@ -420,14 +391,14 @@ class ActiveCallFragment : GenericCallFragment() {
|
|||
)
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
coreContext.postOnCoreThread { core ->
|
||||
core.nativeVideoWindowId = binding.remoteVideoSurface
|
||||
setupVideoPreview(binding.localPreviewVideoSurface)
|
||||
|
||||
binding.localPreviewVideoSurface.setOnTouchListener(previewTouchListener)
|
||||
coreContext.postOnCoreThread { core ->
|
||||
Log.i("$TAG Fragment resuming, setting native video window ID")
|
||||
core.nativeVideoWindowId = binding.remoteVideoSurface
|
||||
|
||||
// Need to be done manually
|
||||
callViewModel.updateCallDuration()
|
||||
|
|
@ -442,14 +413,13 @@ class ActiveCallFragment : GenericCallFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
|
||||
zrtpSasDialog?.dismiss()
|
||||
zrtpSasDialog = null
|
||||
|
||||
binding.localPreviewVideoSurface.setOnTouchListener(null)
|
||||
cleanVideoPreview(binding.localPreviewVideoSurface)
|
||||
}
|
||||
|
||||
private fun updateHingeRelatedConstraints(feature: FoldingFeature) {
|
||||
|
|
|
|||
|
|
@ -19,11 +19,14 @@
|
|||
*/
|
||||
package org.linphone.ui.call.fragment
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import androidx.annotation.UiThread
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import org.linphone.ui.GenericFragment
|
||||
import org.linphone.ui.call.view.RoundCornersTextureView
|
||||
import org.linphone.ui.call.viewmodel.SharedCallViewModel
|
||||
|
||||
@UiThread
|
||||
|
|
@ -34,6 +37,34 @@ abstract class GenericCallFragment : GenericFragment() {
|
|||
|
||||
protected lateinit var sharedViewModel: SharedCallViewModel
|
||||
|
||||
// For moving video preview purposes
|
||||
private val videoPreviewTouchListener = View.OnTouchListener { view, event ->
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
sharedViewModel.videoPreviewX = view.x - event.rawX
|
||||
sharedViewModel.videoPreviewY = view.y - event.rawY
|
||||
true
|
||||
}
|
||||
MotionEvent.ACTION_UP -> {
|
||||
sharedViewModel.videoPreviewX = view.translationX
|
||||
sharedViewModel.videoPreviewY = view.translationY
|
||||
true
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
view.animate()
|
||||
.x(event.rawX + sharedViewModel.videoPreviewX)
|
||||
.y(event.rawY + sharedViewModel.videoPreviewY)
|
||||
.setDuration(0)
|
||||
.start()
|
||||
true
|
||||
}
|
||||
else -> {
|
||||
view.performClick()
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
|
|
@ -41,4 +72,21 @@ abstract class GenericCallFragment : GenericFragment() {
|
|||
ViewModelProvider(this)[SharedCallViewModel::class.java]
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
protected fun setupVideoPreview(localPreviewVideoSurface: RoundCornersTextureView) {
|
||||
// To restore video preview position if possible
|
||||
localPreviewVideoSurface.animate()
|
||||
.x(sharedViewModel.videoPreviewX)
|
||||
.y(sharedViewModel.videoPreviewY)
|
||||
.setDuration(0)
|
||||
.start()
|
||||
|
||||
localPreviewVideoSurface.setOnTouchListener(videoPreviewTouchListener)
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
protected fun cleanVideoPreview(localPreviewVideoSurface: RoundCornersTextureView) {
|
||||
localPreviewVideoSurface.setOnTouchListener(null)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,11 +26,16 @@ import android.view.ViewGroup
|
|||
import androidx.annotation.UiThread
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.databinding.CallIncomingFragmentBinding
|
||||
import org.linphone.ui.call.viewmodel.CurrentCallViewModel
|
||||
|
||||
@UiThread
|
||||
class IncomingCallFragment : GenericCallFragment() {
|
||||
companion object {
|
||||
private const val TAG = "[Incoming Call Fragment]"
|
||||
}
|
||||
|
||||
private lateinit var binding: CallIncomingFragmentBinding
|
||||
|
||||
private lateinit var callViewModel: CurrentCallViewModel
|
||||
|
|
@ -53,6 +58,15 @@ class IncomingCallFragment : GenericCallFragment() {
|
|||
|
||||
binding.lifecycleOwner = viewLifecycleOwner
|
||||
binding.viewModel = callViewModel
|
||||
|
||||
callViewModel.isIncomingEarlyMedia.observe(viewLifecycleOwner) { earlyMedia ->
|
||||
if (earlyMedia) {
|
||||
coreContext.postOnCoreThread { core ->
|
||||
Log.i("$TAG Incoming early-media call, setting video surface")
|
||||
core.nativeVideoWindowId = binding.remoteVideoSurface
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
|
|
|||
|
|
@ -25,11 +25,17 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import androidx.annotation.UiThread
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.databinding.CallOutgoingFragmentBinding
|
||||
import org.linphone.ui.call.viewmodel.CurrentCallViewModel
|
||||
|
||||
@UiThread
|
||||
class OutgoingCallFragment : GenericCallFragment() {
|
||||
companion object {
|
||||
private const val TAG = "[Outgoing Call Fragment]"
|
||||
}
|
||||
|
||||
private lateinit var binding: CallOutgoingFragmentBinding
|
||||
|
||||
private lateinit var callViewModel: CurrentCallViewModel
|
||||
|
|
@ -52,5 +58,26 @@ class OutgoingCallFragment : GenericCallFragment() {
|
|||
|
||||
binding.lifecycleOwner = viewLifecycleOwner
|
||||
binding.viewModel = callViewModel
|
||||
|
||||
callViewModel.isOutgoingEarlyMedia.observe(viewLifecycleOwner) { earlyMedia ->
|
||||
if (earlyMedia) {
|
||||
coreContext.postOnCoreThread { core ->
|
||||
Log.i("$TAG Outgoing early-media call with video, setting preview surface")
|
||||
core.nativePreviewWindowId = binding.localPreviewVideoSurface
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
setupVideoPreview(binding.localPreviewVideoSurface)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
|
||||
cleanVideoPreview(binding.localPreviewVideoSurface)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,10 +87,14 @@ class CurrentCallViewModel
|
|||
|
||||
val videoUpdateInProgress = MutableLiveData<Boolean>()
|
||||
|
||||
val isIncomingEarlyMedia = MutableLiveData<Boolean>()
|
||||
|
||||
val isOutgoing = MutableLiveData<Boolean>()
|
||||
|
||||
val isOutgoingRinging = MutableLiveData<Boolean>()
|
||||
|
||||
val isOutgoingEarlyMedia = MutableLiveData<Boolean>()
|
||||
|
||||
val isRecordingEnabled = MutableLiveData<Boolean>()
|
||||
|
||||
val isRecording = MutableLiveData<Boolean>()
|
||||
|
|
@ -420,6 +424,8 @@ class CurrentCallViewModel
|
|||
message: String
|
||||
) {
|
||||
isOutgoingRinging.postValue(call.state == Call.State.OutgoingRinging)
|
||||
isIncomingEarlyMedia.postValue(call.state == Call.State.IncomingEarlyMedia)
|
||||
isOutgoingEarlyMedia.postValue(call.state == Call.State.OutgoingEarlyMedia)
|
||||
|
||||
if (::currentCall.isInitialized) {
|
||||
if (call != currentCall) {
|
||||
|
|
@ -1129,10 +1135,13 @@ class CurrentCallViewModel
|
|||
updateOutputAudioDevice(audioDevice)
|
||||
|
||||
isOutgoing.postValue(call.dir == Call.Dir.Outgoing)
|
||||
isOutgoingRinging.postValue(call.state == Call.State.OutgoingRinging)
|
||||
val state = call.state
|
||||
isOutgoingRinging.postValue(state == Call.State.OutgoingRinging)
|
||||
isIncomingEarlyMedia.postValue(state == Call.State.IncomingEarlyMedia)
|
||||
isOutgoingEarlyMedia.postValue(state == Call.State.OutgoingEarlyMedia)
|
||||
|
||||
isPaused.postValue(isCallPaused())
|
||||
isPausedByRemote.postValue(call.state == Call.State.PausedByRemote)
|
||||
isPausedByRemote.postValue(state == Call.State.PausedByRemote)
|
||||
canBePaused.postValue(canCallBePaused())
|
||||
|
||||
val address = call.callLog.remoteAddress
|
||||
|
|
|
|||
|
|
@ -31,4 +31,8 @@ class SharedCallViewModel
|
|||
val toggleFullScreenEvent = MutableLiveData<Event<Boolean>>()
|
||||
|
||||
val foldingState = MutableLiveData<FoldingFeature>()
|
||||
|
||||
// For moving video preview purposes
|
||||
var videoPreviewX: Float = 0f
|
||||
var videoPreviewY: Float = 0f
|
||||
}
|
||||
|
|
|
|||
|
|
@ -187,6 +187,8 @@ class SettingsViewModel
|
|||
val mediaEncryptionLabels = arrayListOf<String>()
|
||||
private val mediaEncryptionValues = arrayListOf<MediaEncryption>()
|
||||
val mediaEncryptionMandatory = MutableLiveData<Boolean>()
|
||||
val acceptEarlyMedia = MutableLiveData<Boolean>()
|
||||
val allowOutgoingEarlyMedia = MutableLiveData<Boolean>()
|
||||
|
||||
val expandAudioDevices = MutableLiveData<Boolean>()
|
||||
val inputAudioDeviceIndex = MutableLiveData<Int>()
|
||||
|
|
@ -671,6 +673,8 @@ class SettingsViewModel
|
|||
}
|
||||
|
||||
mediaEncryptionMandatory.postValue(core.isMediaEncryptionMandatory)
|
||||
acceptEarlyMedia.postValue(corePreferences.acceptEarlyMedia)
|
||||
allowOutgoingEarlyMedia.postValue(corePreferences.allowOutgoingEarlyMedia)
|
||||
}
|
||||
|
||||
@UiThread
|
||||
|
|
@ -696,6 +700,26 @@ class SettingsViewModel
|
|||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun toggleAcceptEarlyMedia() {
|
||||
val newValue = acceptEarlyMedia.value == false
|
||||
|
||||
coreContext.postOnCoreThread { core ->
|
||||
corePreferences.acceptEarlyMedia = newValue
|
||||
acceptEarlyMedia.postValue(newValue)
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun toggleAllowOutgoingEarlyMedia() {
|
||||
val newValue = allowOutgoingEarlyMedia.value == false
|
||||
|
||||
coreContext.postOnCoreThread { core ->
|
||||
corePreferences.allowOutgoingEarlyMedia = newValue
|
||||
allowOutgoingEarlyMedia.postValue(newValue)
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun updateDeviceName() {
|
||||
coreContext.postOnCoreThread {
|
||||
|
|
|
|||
|
|
@ -15,44 +15,6 @@
|
|||
android:layout_height="match_parent"
|
||||
android:background="@color/gray_900">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/back"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/top_bar_height"
|
||||
android:adjustViewBounds="true"
|
||||
android:padding="15dp"
|
||||
android:src="@drawable/caret_left"
|
||||
android:contentDescription="@string/content_description_go_back_icon"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:visibility="invisible"
|
||||
app:tint="@color/bc_white" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/call_direction_icon"
|
||||
android:layout_width="12dp"
|
||||
android:layout_height="12dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:src="@drawable/incoming_call"
|
||||
android:contentDescription="@null"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/call_direction_label"
|
||||
app:layout_constraintBottom_toBottomOf="@id/call_direction_label"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/call_header_style"
|
||||
android:id="@+id/call_direction_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:text="@{viewModel.incomingCallTitle, default=@string/call_video_incoming}"
|
||||
app:layout_constraintStart_toEndOf="@id/call_direction_icon"
|
||||
app:layout_constraintTop_toTopOf="@id/back"
|
||||
app:layout_constraintBottom_toBottomOf="@id/back"/>
|
||||
|
||||
<include
|
||||
android:id="@+id/avatar"
|
||||
android:layout_width="@dimen/avatar_in_call_size"
|
||||
|
|
@ -113,6 +75,39 @@
|
|||
app:layout_constraintTop_toTopOf="@id/name_address"
|
||||
app:layout_constraintBottom_toBottomOf="@id/name_address" />
|
||||
|
||||
<org.linphone.ui.call.view.RoundCornersTextureView
|
||||
android:id="@+id/remote_video_surface"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/call_direction_icon"
|
||||
android:layout_width="12dp"
|
||||
android:layout_height="12dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:src="@drawable/incoming_call"
|
||||
android:contentDescription="@null"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/call_direction_label"
|
||||
app:layout_constraintBottom_toBottomOf="@id/call_direction_label"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/call_header_style"
|
||||
android:id="@+id/call_direction_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:text="@{viewModel.incomingCallTitle, default=@string/call_video_incoming}"
|
||||
app:layout_constraintStart_toEndOf="@id/call_direction_icon"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
<include
|
||||
bind:viewModel="@{viewModel}"
|
||||
android:id="@+id/bottom_bar"
|
||||
|
|
@ -123,6 +118,33 @@
|
|||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/default_text_style_300"
|
||||
android:id="@+id/early_media_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:text="@{viewModel.displayedName, default=`John Doe`}"
|
||||
android:textColor="@color/bc_white"
|
||||
android:textSize="22sp"
|
||||
android:visibility="@{viewModel.isIncomingEarlyMedia ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:layout_constraintBottom_toTopOf="@id/early_media_address"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/early_media_address"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:text="@{viewModel.displayedAddress, default=`sip:johndoe@sip.linphone.org`}"
|
||||
android:textColor="@color/bc_white"
|
||||
android:textSize="14sp"
|
||||
android:visibility="@{viewModel.isIncomingEarlyMedia ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:layout_constraintBottom_toTopOf="@id/bottom_bar"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</layout>
|
||||
|
|
@ -98,6 +98,21 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:onClick="@{() -> viewModel.switchCamera()}"
|
||||
android:id="@+id/switch_camera"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/top_bar_height"
|
||||
android:padding="10dp"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:src="@drawable/camera_rotate"
|
||||
android:contentDescription="@string/content_description_change_camera"
|
||||
android:visibility="gone"
|
||||
app:tint="@color/bc_white"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
android:id="@+id/in_progress"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
@ -105,11 +120,25 @@
|
|||
android:indeterminate="true"
|
||||
app:indicatorColor="@color/bc_white"
|
||||
app:indicatorSize="28dp"
|
||||
app:layout_constraintStart_toEndOf="@id/name_address"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/avatar"
|
||||
app:layout_constraintTop_toTopOf="@id/name_address"
|
||||
app:layout_constraintBottom_toBottomOf="@id/name_address" />
|
||||
|
||||
<org.linphone.ui.call.view.RoundCornersTextureView
|
||||
android:id="@+id/local_preview_video_surface"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
app:alignTopRight="true"
|
||||
app:displayMode="black_bars"
|
||||
roundCornersRadius="@dimen/call_round_corners_texture_view_radius"
|
||||
app:layout_constraintBottom_toTopOf="@id/bottom_bar"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHeight_max="@dimen/call_video_preview_max_size"
|
||||
app:layout_constraintWidth_max="@dimen/call_video_preview_max_size" />
|
||||
|
||||
<include
|
||||
bind:viewModel="@{viewModel}"
|
||||
android:id="@+id/bottom_bar"
|
||||
|
|
|
|||
|
|
@ -15,30 +15,6 @@
|
|||
android:layout_height="match_parent"
|
||||
android:background="@color/gray_900">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/call_direction_icon"
|
||||
android:layout_width="12dp"
|
||||
android:layout_height="12dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:src="@drawable/incoming_call"
|
||||
android:contentDescription="@null"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/call_direction_label"
|
||||
app:layout_constraintBottom_toBottomOf="@id/call_direction_label"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/call_header_style"
|
||||
android:id="@+id/call_direction_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:text="@{viewModel.incomingCallTitle, default=@string/call_video_incoming}"
|
||||
app:layout_constraintStart_toEndOf="@id/call_direction_icon"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
android:id="@+id/in_progress"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
@ -92,6 +68,66 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<org.linphone.ui.call.view.RoundCornersTextureView
|
||||
android:id="@+id/remote_video_surface"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/call_direction_icon"
|
||||
android:layout_width="12dp"
|
||||
android:layout_height="12dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:src="@drawable/incoming_call"
|
||||
android:contentDescription="@null"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/call_direction_label"
|
||||
app:layout_constraintBottom_toBottomOf="@id/call_direction_label"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/call_header_style"
|
||||
android:id="@+id/call_direction_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:text="@{viewModel.incomingCallTitle, default=@string/call_video_incoming}"
|
||||
app:layout_constraintStart_toEndOf="@id/call_direction_icon"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/default_text_style_300"
|
||||
android:id="@+id/early_media_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:text="@{viewModel.displayedName, default=`John Doe`}"
|
||||
android:textColor="@color/bc_white"
|
||||
android:textSize="22sp"
|
||||
android:visibility="@{viewModel.isIncomingEarlyMedia ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:layout_constraintBottom_toTopOf="@id/early_media_address"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/early_media_address"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:text="@{viewModel.displayedAddress, default=`sip:johndoe@sip.linphone.org`}"
|
||||
android:textColor="@color/bc_white"
|
||||
android:textSize="14sp"
|
||||
android:visibility="@{viewModel.isIncomingEarlyMedia ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:layout_constraintBottom_toTopOf="@id/bottom_bar"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<include
|
||||
bind:viewModel="@{viewModel}"
|
||||
android:id="@+id/bottom_bar"
|
||||
|
|
|
|||
|
|
@ -39,6 +39,21 @@
|
|||
app:layout_constraintStart_toEndOf="@id/call_direction_icon"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
<ImageView
|
||||
android:onClick="@{() -> viewModel.switchCamera()}"
|
||||
android:id="@+id/switch_camera"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/top_bar_height"
|
||||
android:padding="10dp"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:src="@drawable/camera_rotate"
|
||||
android:contentDescription="@string/content_description_change_camera"
|
||||
android:visibility="gone"
|
||||
app:tint="@color/bc_white"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
android:id="@+id/in_progress"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
@ -91,6 +106,20 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<org.linphone.ui.call.view.RoundCornersTextureView
|
||||
android:id="@+id/local_preview_video_surface"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
app:alignTopRight="true"
|
||||
app:displayMode="black_bars"
|
||||
roundCornersRadius="@dimen/call_round_corners_texture_view_radius"
|
||||
app:layout_constraintBottom_toTopOf="@id/bottom_bar"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHeight_max="@dimen/call_video_preview_max_size"
|
||||
app:layout_constraintWidth_max="@dimen/call_video_preview_max_size" />
|
||||
|
||||
<include
|
||||
bind:viewModel="@{viewModel}"
|
||||
android:id="@+id/bottom_bar"
|
||||
|
|
|
|||
|
|
@ -57,6 +57,21 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:id="@+id/keep_alive_service_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:text="@string/settings_advanced_keep_alive_service_title"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toTopOf="@id/keep_alive_service_switch"
|
||||
app:layout_constraintBottom_toBottomOf="@id/keep_alive_service_switch"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/keep_alive_service_switch"/>
|
||||
|
||||
<com.google.android.material.materialswitch.MaterialSwitch
|
||||
style="@style/material_switch_style"
|
||||
android:id="@+id/keep_alive_service_switch"
|
||||
|
|
@ -174,21 +189,61 @@
|
|||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/media_encryption" />
|
||||
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:id="@+id/push_notifications_title"
|
||||
android:onClick="@{() -> viewModel.toggleAcceptEarlyMedia()}"
|
||||
android:id="@+id/accept_early_media_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:text="@string/settings_advanced_keep_alive_service_title"
|
||||
android:text="@string/settings_advanced_accept_early_media_title"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toTopOf="@id/keep_alive_service_switch"
|
||||
app:layout_constraintBottom_toBottomOf="@id/keep_alive_service_switch"
|
||||
app:layout_constraintTop_toTopOf="@id/accept_early_media_switch"
|
||||
app:layout_constraintBottom_toBottomOf="@id/accept_early_media_switch"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/keep_alive_service_switch"/>
|
||||
app:layout_constraintEnd_toStartOf="@id/accept_early_media_switch"/>
|
||||
|
||||
<com.google.android.material.materialswitch.MaterialSwitch
|
||||
style="@style/material_switch_style"
|
||||
android:id="@+id/accept_early_media_switch"
|
||||
android:onClick="@{() -> viewModel.toggleAcceptEarlyMedia()}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:checked="@{viewModel.acceptEarlyMedia}"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/media_encryption_mandatory_switch" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:onClick="@{() -> viewModel.toggleAllowOutgoingEarlyMedia()}"
|
||||
android:id="@+id/allow_outgoing_early_media_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:text="@string/settings_advanced_allow_outgoing_early_media_title"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toTopOf="@id/allow_outgoing_early_media_switch"
|
||||
app:layout_constraintBottom_toBottomOf="@id/allow_outgoing_early_media_switch"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/allow_outgoing_early_media_switch"/>
|
||||
|
||||
<com.google.android.material.materialswitch.MaterialSwitch
|
||||
style="@style/material_switch_style"
|
||||
android:id="@+id/allow_outgoing_early_media_switch"
|
||||
android:onClick="@{() -> viewModel.toggleAllowOutgoingEarlyMedia()}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:checked="@{viewModel.allowOutgoingEarlyMedia}"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/accept_early_media_switch" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
|
|
@ -201,7 +256,7 @@
|
|||
android:paddingBottom="8dp"
|
||||
android:text="@string/settings_advanced_device_id"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/media_encryption_mandatory_switch"/>
|
||||
app:layout_constraintTop_toBottomOf="@id/allow_outgoing_early_media_switch"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
style="@style/default_text_style"
|
||||
|
|
|
|||
|
|
@ -257,6 +257,8 @@
|
|||
<string name="settings_advanced_upload_server_url">URL du serveur de partage de fichier</string>
|
||||
<string name="settings_advanced_media_encryption_title">Chiffrement du média</string>
|
||||
<string name="settings_advanced_media_encryption_mandatory_title">Rendre le chiffrement du média obligatoire</string>
|
||||
<string name="settings_advanced_accept_early_media_title">Accepter l\'early media</string>
|
||||
<string name="settings_advanced_allow_outgoing_early_media_title">Autoriser l\'early media pour les appels sortants</string>
|
||||
<string name="settings_advanced_remote_provisioning_url">URL de configuration distante</string>
|
||||
<string name="settings_advanced_download_apply_remote_provisioning">Télécharger & appliquer</string>
|
||||
<string name="settings_advanced_audio_devices_title">Périphériques audio</string>
|
||||
|
|
|
|||
|
|
@ -296,6 +296,8 @@
|
|||
<string name="settings_advanced_upload_server_url">File sharing server URL</string>
|
||||
<string name="settings_advanced_media_encryption_title">Media encryption</string>
|
||||
<string name="settings_advanced_media_encryption_mandatory_title">Media encryption mandatory</string>
|
||||
<string name="settings_advanced_accept_early_media_title">Accept early media</string>
|
||||
<string name="settings_advanced_allow_outgoing_early_media_title">Allow outgoing early media</string>
|
||||
<string name="settings_advanced_remote_provisioning_url">Remote provisioning URL</string>
|
||||
<string name="settings_advanced_download_apply_remote_provisioning">Download & apply</string>
|
||||
<string name="settings_advanced_audio_devices_title">Audio devices</string>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue