mirror of
https://gitlab.linphone.org/BC/public/linphone-android.git
synced 2026-01-25 07:48:08 +00:00
Added audio device picker in advanced settings
This commit is contained in:
parent
d48f7697df
commit
4f6c5c7f48
6 changed files with 237 additions and 2 deletions
|
|
@ -23,8 +23,11 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import androidx.annotation.UiThread
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import org.linphone.R
|
||||
import org.linphone.databinding.SettingsAdvancedFragmentBinding
|
||||
import org.linphone.ui.main.fragment.GenericMainFragment
|
||||
import org.linphone.ui.main.settings.viewmodel.SettingsViewModel
|
||||
|
|
@ -39,6 +42,24 @@ class SettingsAdvancedFragment : GenericMainFragment() {
|
|||
|
||||
private lateinit var viewModel: SettingsViewModel
|
||||
|
||||
private val inputAudioDeviceDropdownListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||
viewModel.setInputAudioDevice(position)
|
||||
}
|
||||
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {
|
||||
}
|
||||
}
|
||||
|
||||
private val outputAudioDeviceDropdownListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||
viewModel.setOutputAudioDevice(position)
|
||||
}
|
||||
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
|
|
@ -62,6 +83,14 @@ class SettingsAdvancedFragment : GenericMainFragment() {
|
|||
goBack()
|
||||
}
|
||||
|
||||
viewModel.inputAudioDeviceIndex.observe(viewLifecycleOwner) {
|
||||
setupInputAudioDevicePicker()
|
||||
}
|
||||
|
||||
viewModel.outputAudioDeviceIndex.observe(viewLifecycleOwner) {
|
||||
setupOutputAudioDevicePicker()
|
||||
}
|
||||
|
||||
startPostponedEnterTransition()
|
||||
}
|
||||
|
||||
|
|
@ -70,4 +99,30 @@ class SettingsAdvancedFragment : GenericMainFragment() {
|
|||
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
private fun setupInputAudioDevicePicker() {
|
||||
val index = viewModel.inputAudioDeviceIndex.value ?: 0
|
||||
val adapter = ArrayAdapter(
|
||||
requireContext(),
|
||||
R.layout.drop_down_item,
|
||||
viewModel.inputAudioDeviceLabels
|
||||
)
|
||||
adapter.setDropDownViewResource(R.layout.generic_dropdown_cell)
|
||||
binding.inputAudioDevice.adapter = adapter
|
||||
binding.inputAudioDevice.onItemSelectedListener = inputAudioDeviceDropdownListener
|
||||
binding.inputAudioDevice.setSelection(index)
|
||||
}
|
||||
|
||||
private fun setupOutputAudioDevicePicker() {
|
||||
val index = viewModel.outputAudioDeviceIndex.value ?: 0
|
||||
val adapter = ArrayAdapter(
|
||||
requireContext(),
|
||||
R.layout.drop_down_item,
|
||||
viewModel.outputAudioDeviceLabels
|
||||
)
|
||||
adapter.setDropDownViewResource(R.layout.generic_dropdown_cell)
|
||||
binding.outputAudioDevice.adapter = adapter
|
||||
binding.outputAudioDevice.onItemSelectedListener = outputAudioDeviceDropdownListener
|
||||
binding.outputAudioDevice.setSelection(index)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,11 +21,15 @@ package org.linphone.ui.main.settings.viewmodel
|
|||
|
||||
import android.os.Vibrator
|
||||
import androidx.annotation.UiThread
|
||||
import androidx.annotation.WorkerThread
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.LinphoneApplication.Companion.corePreferences
|
||||
import org.linphone.R
|
||||
import org.linphone.core.AudioDevice
|
||||
import org.linphone.core.Conference
|
||||
import org.linphone.core.Core
|
||||
import org.linphone.core.CoreListenerStub
|
||||
import org.linphone.core.FriendList
|
||||
import org.linphone.core.VFS
|
||||
import org.linphone.core.tools.Log
|
||||
|
|
@ -148,8 +152,27 @@ class SettingsViewModel @UiThread constructor() : GenericViewModel() {
|
|||
|
||||
val remoteProvisioningUrl = MutableLiveData<String>()
|
||||
|
||||
val inputAudioDeviceIndex = MutableLiveData<Int>()
|
||||
val inputAudioDeviceLabels = arrayListOf<String>()
|
||||
private val inputAudioDeviceValues = arrayListOf<AudioDevice>()
|
||||
|
||||
val outputAudioDeviceIndex = MutableLiveData<Int>()
|
||||
val outputAudioDeviceLabels = arrayListOf<String>()
|
||||
private val outputAudioDeviceValues = arrayListOf<AudioDevice>()
|
||||
|
||||
private val coreListener = object : CoreListenerStub() {
|
||||
override fun onAudioDevicesListUpdated(core: Core) {
|
||||
Log.i(
|
||||
"$TAG Audio devices list has changed, update available input/output audio devices list"
|
||||
)
|
||||
setupAudioDevices()
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
coreContext.postOnCoreThread { core ->
|
||||
core.addListener(coreListener)
|
||||
|
||||
showConversationsSettings.postValue(!corePreferences.disableChat)
|
||||
showMeetingsSettings.postValue(!corePreferences.disableMeetings)
|
||||
ldapAvailable.postValue(core.ldapAvailable())
|
||||
|
|
@ -197,9 +220,19 @@ class SettingsViewModel @UiThread constructor() : GenericViewModel() {
|
|||
keepAliveThirdPartyAccountsService.postValue(corePreferences.keepServiceAlive)
|
||||
|
||||
remoteProvisioningUrl.postValue(core.provisioningUri)
|
||||
|
||||
setupAudioDevices()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
coreContext.postOnCoreThread { core ->
|
||||
core.removeListener(coreListener)
|
||||
}
|
||||
|
||||
super.onCleared()
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun toggleSecurityExpand() {
|
||||
expandSecurity.value = expandSecurity.value == false
|
||||
|
|
@ -463,4 +496,58 @@ class SettingsViewModel @UiThread constructor() : GenericViewModel() {
|
|||
Log.i("$TAG Core has been restarted")
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun setInputAudioDevice(index: Int) {
|
||||
coreContext.postOnCoreThread { core ->
|
||||
val audioDevice = inputAudioDeviceValues[index]
|
||||
core.defaultInputAudioDevice = audioDevice
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun setOutputAudioDevice(index: Int) {
|
||||
coreContext.postOnCoreThread { core ->
|
||||
val audioDevice = outputAudioDeviceValues[index]
|
||||
core.defaultOutputAudioDevice = audioDevice
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private fun setupAudioDevices() {
|
||||
val core = coreContext.core
|
||||
|
||||
inputAudioDeviceLabels.clear()
|
||||
inputAudioDeviceValues.clear()
|
||||
outputAudioDeviceLabels.clear()
|
||||
outputAudioDeviceValues.clear()
|
||||
|
||||
var inputIndex = 0
|
||||
val defaultInputAudioDevice = core.defaultInputAudioDevice
|
||||
Log.i("$TAG Current default input audio device is [${defaultInputAudioDevice?.id}]")
|
||||
for (audioDevice in core.extendedAudioDevices) {
|
||||
if (audioDevice.hasCapability(AudioDevice.Capabilities.CapabilityRecord)) {
|
||||
inputAudioDeviceLabels.add(audioDevice.id)
|
||||
inputAudioDeviceValues.add(audioDevice)
|
||||
if (audioDevice.id == defaultInputAudioDevice?.id) {
|
||||
inputAudioDeviceIndex.postValue(inputIndex)
|
||||
}
|
||||
inputIndex += 1
|
||||
}
|
||||
}
|
||||
|
||||
var outputIndex = 0
|
||||
val defaultOutputAudioDevice = core.defaultOutputAudioDevice
|
||||
Log.i("$TAG Current default output audio device is [${defaultOutputAudioDevice?.id}]")
|
||||
for (audioDevice in core.extendedAudioDevices) {
|
||||
if (audioDevice.hasCapability(AudioDevice.Capabilities.CapabilityPlay)) {
|
||||
outputAudioDeviceLabels.add(audioDevice.id)
|
||||
outputAudioDeviceValues.add(audioDevice)
|
||||
if (audioDevice.id == defaultOutputAudioDevice?.id) {
|
||||
outputAudioDeviceIndex.postValue(outputIndex)
|
||||
}
|
||||
outputIndex += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,4 +9,6 @@
|
|||
android:gravity="center_vertical"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
|
@ -103,7 +103,6 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:text="@={viewModel.remoteProvisioningUrl}"
|
||||
|
|
@ -121,7 +120,7 @@
|
|||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/tertiary_button_label_style"
|
||||
android:id="@+id/show_config_file"
|
||||
android:id="@+id/download_and_apply"
|
||||
android:onClick="@{() -> viewModel.downloadAndApplyRemoteProvisioning()}"
|
||||
android:enabled="@{viewModel.remoteProvisioningUrl.length() != 0, default=false}"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
@ -141,6 +140,94 @@
|
|||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/remote_provisioning"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/header_style"
|
||||
android:id="@+id/input_audio_device_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:text="@string/settings_advanced_input_audio_device_title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/download_and_apply"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatSpinner
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/input_audio_device"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/gray_main2_600"
|
||||
android:gravity="center_vertical"
|
||||
android:overlapAnchor="false"
|
||||
android:dropDownVerticalOffset="25dp"
|
||||
android:spinnerMode="dropdown"
|
||||
android:popupBackground="@drawable/shape_squircle_white_background"
|
||||
android:background="@drawable/edit_text_background"
|
||||
app:layout_constraintTop_toBottomOf="@id/input_audio_device_label"
|
||||
app:layout_constraintStart_toStartOf="@id/input_audio_device_label"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/input_audio_device_caret"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:src="@drawable/caret_down"
|
||||
android:contentDescription="@null"
|
||||
app:layout_constraintTop_toTopOf="@id/input_audio_device"
|
||||
app:layout_constraintBottom_toBottomOf="@id/input_audio_device"
|
||||
app:layout_constraintEnd_toEndOf="@id/input_audio_device"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/header_style"
|
||||
android:id="@+id/output_audio_device_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:text="@string/settings_advanced_output_audio_device_title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/input_audio_device"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatSpinner
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/output_audio_device"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/gray_main2_600"
|
||||
android:gravity="center_vertical"
|
||||
android:overlapAnchor="false"
|
||||
android:dropDownVerticalOffset="25dp"
|
||||
android:spinnerMode="dropdown"
|
||||
android:popupBackground="@drawable/shape_squircle_white_background"
|
||||
android:background="@drawable/edit_text_background"
|
||||
app:layout_constraintTop_toBottomOf="@id/output_audio_device_label"
|
||||
app:layout_constraintStart_toStartOf="@id/output_audio_device_label"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/output_audio_device_caret"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:src="@drawable/caret_down"
|
||||
android:contentDescription="@null"
|
||||
app:layout_constraintTop_toTopOf="@id/output_audio_device"
|
||||
app:layout_constraintBottom_toBottomOf="@id/output_audio_device"
|
||||
app:layout_constraintEnd_toEndOf="@id/output_audio_device"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
|
|
|||
|
|
@ -278,6 +278,8 @@
|
|||
<string name="settings_advanced_keep_alive_service_title">Garder l\'app en vie via un Service</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_input_audio_device_title">Périphérique de capture par défaut</string>
|
||||
<string name="settings_advanced_output_audio_device_title">Périphérique d\'écoute par défaut</string>
|
||||
|
||||
<!-- Account profile & settings -->
|
||||
<string name="manage_account_title">Votre compte</string>
|
||||
|
|
|
|||
|
|
@ -313,6 +313,8 @@
|
|||
<string name="settings_advanced_keep_alive_service_title">Keep app alive using Service</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_input_audio_device_title">Default input audio device</string>
|
||||
<string name="settings_advanced_output_audio_device_title">Default output audio device</string>
|
||||
|
||||
<!-- Account profile & settings -->
|
||||
<string name="manage_account_title">Manage account</string>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue