mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-23 12:38:33 +00:00
Prevent launching multiple audio device dialogs during call.
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
package org.thoughtcrime.securesms.components.webrtc
|
package org.thoughtcrime.securesms.components.webrtc
|
||||||
|
|
||||||
import android.content.DialogInterface
|
import android.content.DialogInterface
|
||||||
import android.os.Bundle
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
@@ -59,21 +58,26 @@ class WebRtcAudioOutputBottomSheet : ComposeBottomSheetDialogFragment(), DialogI
|
|||||||
dismiss()
|
dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun show(fm: FragmentManager, tag: String?, audioRoutes: List<AudioOutputOption>, selectedDeviceId: Int, onClick: (AudioOutputOption) -> Unit) {
|
fun show(fm: FragmentManager, tag: String?, audioRoutes: List<AudioOutputOption>, selectedDeviceId: Int, onClick: (AudioOutputOption) -> Unit, onDismiss: (DialogInterface) -> Unit) {
|
||||||
super.showNow(fm, tag)
|
super.showNow(fm, tag)
|
||||||
viewModel.audioRoutes = audioRoutes
|
viewModel.audioRoutes = audioRoutes
|
||||||
viewModel.defaultDeviceId = selectedDeviceId
|
viewModel.defaultDeviceId = selectedDeviceId
|
||||||
viewModel.onClick = onClick
|
viewModel.onClick = onClick
|
||||||
|
viewModel.onDismiss = onDismiss
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDismiss(dialog: DialogInterface) {
|
||||||
|
super.onDismiss(dialog)
|
||||||
|
viewModel.onDismiss(dialog)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "WebRtcAudioOutputBottomSheet"
|
const val TAG = "WebRtcAudioOutputBottomSheet"
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun show(fragmentManager: FragmentManager, audioRoutes: List<AudioOutputOption>, selectedDeviceId: Int, onClick: (AudioOutputOption) -> Unit): WebRtcAudioOutputBottomSheet {
|
fun show(fragmentManager: FragmentManager, audioRoutes: List<AudioOutputOption>, selectedDeviceId: Int, onClick: (AudioOutputOption) -> Unit, onDismiss: (DialogInterface) -> Unit): WebRtcAudioOutputBottomSheet {
|
||||||
val bottomSheet = WebRtcAudioOutputBottomSheet()
|
val bottomSheet = WebRtcAudioOutputBottomSheet()
|
||||||
val args = Bundle()
|
bottomSheet.show(fragmentManager, BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG, audioRoutes, selectedDeviceId, onClick, onDismiss)
|
||||||
bottomSheet.show(fragmentManager, BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG, audioRoutes, selectedDeviceId, onClick)
|
|
||||||
return bottomSheet
|
return bottomSheet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -134,6 +138,7 @@ class AudioOutputViewModel : ViewModel() {
|
|||||||
var audioRoutes: List<AudioOutputOption> = emptyList()
|
var audioRoutes: List<AudioOutputOption> = emptyList()
|
||||||
var defaultDeviceId: Int = -1
|
var defaultDeviceId: Int = -1
|
||||||
var onClick: (AudioOutputOption) -> Unit = {}
|
var onClick: (AudioOutputOption) -> Unit = {}
|
||||||
|
var onDismiss: (DialogInterface) -> Unit = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getDrawableResourceForDeviceType(deviceType: SignalAudioManager.AudioDevice): Int {
|
private fun getDrawableResourceForDeviceType(deviceType: SignalAudioManager.AudioDevice): Int {
|
||||||
|
|||||||
@@ -27,9 +27,14 @@ class WebRtcAudioOutputToggleButton @JvmOverloads constructor(context: Context,
|
|||||||
private var picker: DialogInterface? = null
|
private var picker: DialogInterface? = null
|
||||||
|
|
||||||
private val clickListenerLegacy: OnClickListener = OnClickListener {
|
private val clickListenerLegacy: OnClickListener = OnClickListener {
|
||||||
|
if (picker != null) {
|
||||||
|
Log.d(TAG, "Tried to launch new audio device picker but one is already present.")
|
||||||
|
return@OnClickListener
|
||||||
|
}
|
||||||
|
|
||||||
val outputs = outputState.getOutputs()
|
val outputs = outputState.getOutputs()
|
||||||
if (outputs.size >= SHOW_PICKER_THRESHOLD || !outputState.isEarpieceAvailable) {
|
if (outputs.size >= SHOW_PICKER_THRESHOLD || !outputState.isEarpieceAvailable) {
|
||||||
picker = WebRtcAudioPickerLegacy(audioOutputChangedListener, outputState, this).showPicker(context, outputs)
|
picker = WebRtcAudioPickerLegacy(audioOutputChangedListener, outputState, this).showPicker(context, outputs) { picker = null }
|
||||||
} else {
|
} else {
|
||||||
val audioOutput = outputState.peekNext()
|
val audioOutput = outputState.peekNext()
|
||||||
audioOutputChangedListener.audioOutputChanged(WebRtcAudioDevice(audioOutput, null))
|
audioOutputChangedListener.audioOutputChanged(WebRtcAudioDevice(audioOutput, null))
|
||||||
@@ -39,9 +44,14 @@ class WebRtcAudioOutputToggleButton @JvmOverloads constructor(context: Context,
|
|||||||
|
|
||||||
@RequiresApi(31)
|
@RequiresApi(31)
|
||||||
private val clickListener31 = OnClickListener {
|
private val clickListener31 = OnClickListener {
|
||||||
|
if (picker != null) {
|
||||||
|
Log.d(TAG, "Tried to launch new audio device picker but one is already present.")
|
||||||
|
return@OnClickListener
|
||||||
|
}
|
||||||
|
|
||||||
val fragmentActivity = context.fragmentActivity()
|
val fragmentActivity = context.fragmentActivity()
|
||||||
if (fragmentActivity != null) {
|
if (fragmentActivity != null) {
|
||||||
picker = WebRtcAudioPicker31(audioOutputChangedListener, outputState, this).showPicker(fragmentActivity, SHOW_PICKER_THRESHOLD)
|
picker = WebRtcAudioPicker31(audioOutputChangedListener, outputState, this).showPicker(fragmentActivity, SHOW_PICKER_THRESHOLD) { picker = null }
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "WebRtcAudioOutputToggleButton instantiated from a context that does not inherit from FragmentActivity.")
|
Log.e(TAG, "WebRtcAudioOutputToggleButton instantiated from a context that does not inherit from FragmentActivity.")
|
||||||
Toast.makeText(context, R.string.WebRtcAudioOutputToggleButton_fragment_activity_error, Toast.LENGTH_LONG).show()
|
Toast.makeText(context, R.string.WebRtcAudioOutputToggleButton_fragment_activity_error, Toast.LENGTH_LONG).show()
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager
|
|||||||
@RequiresApi(31)
|
@RequiresApi(31)
|
||||||
class WebRtcAudioPicker31(private val audioOutputChangedListener: OnAudioOutputChangedListener, private val outputState: ToggleButtonOutputState, private val stateUpdater: AudioStateUpdater) {
|
class WebRtcAudioPicker31(private val audioOutputChangedListener: OnAudioOutputChangedListener, private val outputState: ToggleButtonOutputState, private val stateUpdater: AudioStateUpdater) {
|
||||||
|
|
||||||
fun showPicker(fragmentActivity: FragmentActivity, threshold: Int): DialogInterface? {
|
fun showPicker(fragmentActivity: FragmentActivity, threshold: Int, onDismiss: (DialogInterface) -> Unit): DialogInterface? {
|
||||||
val am = ApplicationDependencies.getAndroidCallAudioManager()
|
val am = ApplicationDependencies.getAndroidCallAudioManager()
|
||||||
if (am.availableCommunicationDevices.isEmpty()) {
|
if (am.availableCommunicationDevices.isEmpty()) {
|
||||||
Toast.makeText(fragmentActivity, R.string.WebRtcAudioOutputToggleButton_no_eligible_audio_i_o_detected, Toast.LENGTH_LONG).show()
|
Toast.makeText(fragmentActivity, R.string.WebRtcAudioOutputToggleButton_no_eligible_audio_i_o_detected, Toast.LENGTH_LONG).show()
|
||||||
@@ -36,7 +36,7 @@ class WebRtcAudioPicker31(private val audioOutputChangedListener: OnAudioOutputC
|
|||||||
onAudioDeviceSelected(devices[(index + 1) % devices.size])
|
onAudioDeviceSelected(devices[(index + 1) % devices.size])
|
||||||
return null
|
return null
|
||||||
} else {
|
} else {
|
||||||
return WebRtcAudioOutputBottomSheet.show(fragmentActivity.supportFragmentManager, devices, currentDeviceId, onAudioDeviceSelected)
|
return WebRtcAudioOutputBottomSheet.show(fragmentActivity.supportFragmentManager, devices, currentDeviceId, onAudioDeviceSelected, onDismiss)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import org.thoughtcrime.securesms.R
|
|||||||
*/
|
*/
|
||||||
class WebRtcAudioPickerLegacy(private val audioOutputChangedListener: OnAudioOutputChangedListener, private val outputState: ToggleButtonOutputState, private val stateUpdater: AudioStateUpdater) {
|
class WebRtcAudioPickerLegacy(private val audioOutputChangedListener: OnAudioOutputChangedListener, private val outputState: ToggleButtonOutputState, private val stateUpdater: AudioStateUpdater) {
|
||||||
|
|
||||||
fun showPicker(context: Context, availableModes: List<WebRtcAudioOutput?>): DialogInterface? {
|
fun showPicker(context: Context, availableModes: List<WebRtcAudioOutput?>, dismissListener: DialogInterface.OnDismissListener): DialogInterface? {
|
||||||
val rv = RecyclerView(context)
|
val rv = RecyclerView(context)
|
||||||
val adapter = AudioOutputAdapter(
|
val adapter = AudioOutputAdapter(
|
||||||
fun(audioDevice: WebRtcAudioDevice) {
|
fun(audioDevice: WebRtcAudioDevice) {
|
||||||
@@ -30,6 +30,7 @@ class WebRtcAudioPickerLegacy(private val audioOutputChangedListener: OnAudioOut
|
|||||||
.setTitle(R.string.WebRtcAudioOutputToggle__audio_output)
|
.setTitle(R.string.WebRtcAudioOutputToggle__audio_output)
|
||||||
.setView(rv)
|
.setView(rv)
|
||||||
.setCancelable(true)
|
.setCancelable(true)
|
||||||
|
.setOnDismissListener(dismissListener)
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user