Improve voice note Bluetooth state handling.

This commit is contained in:
Nicholas
2023-06-21 12:23:59 -04:00
committed by Nicholas Tinsley
parent ecf576e9b9
commit 5cb10cd054
3 changed files with 30 additions and 11 deletions

View File

@@ -25,14 +25,14 @@ sealed interface BluetoothVoiceNoteUtil {
fun destroy()
companion object {
fun create(context: Context, listener: () -> Unit, bluetoothPermissionDeniedHandler: () -> Unit): BluetoothVoiceNoteUtil {
fun create(context: Context, listener: (Boolean) -> Unit, bluetoothPermissionDeniedHandler: () -> Unit): BluetoothVoiceNoteUtil {
return if (Build.VERSION.SDK_INT >= 31) BluetoothVoiceNoteUtil31(listener) else BluetoothVoiceNoteUtilLegacy(context, listener, bluetoothPermissionDeniedHandler)
}
}
}
@RequiresApi(31)
private class BluetoothVoiceNoteUtil31(val listener: () -> Unit) : BluetoothVoiceNoteUtil {
private class BluetoothVoiceNoteUtil31(val listener: (Boolean) -> Unit) : BluetoothVoiceNoteUtil {
override fun connectBluetoothScoConnection() {
val audioManager = ApplicationDependencies.getAndroidCallAudioManager()
val device: AudioDeviceInfo? = audioManager.connectedBluetoothDevice
@@ -40,13 +40,15 @@ private class BluetoothVoiceNoteUtil31(val listener: () -> Unit) : BluetoothVoic
val result: Boolean = audioManager.setCommunicationDevice(device)
if (result) {
Log.d(TAG, "Successfully set Bluetooth device as active communication device.")
listener(true)
} else {
Log.d(TAG, "Found Bluetooth device but failed to set it as active communication device.")
listener(false)
}
} else {
Log.d(TAG, "Could not find Bluetooth device in list of communications devices, falling back to current input.")
listener(false)
}
listener()
}
override fun disconnectBluetoothScoConnection() {
@@ -64,15 +66,23 @@ private class BluetoothVoiceNoteUtil31(val listener: () -> Unit) : BluetoothVoic
* @param listener This will be executed on the main thread after the Bluetooth connection connects, or if it doesn't.
* @param bluetoothPermissionDeniedHandler called when we detect the Bluetooth permission has been denied to our app.
*/
private class BluetoothVoiceNoteUtilLegacy(val context: Context, val listener: () -> Unit, val bluetoothPermissionDeniedHandler: () -> Unit) : BluetoothVoiceNoteUtil {
private class BluetoothVoiceNoteUtilLegacy(val context: Context, val listener: (Boolean) -> Unit, val bluetoothPermissionDeniedHandler: () -> Unit) : BluetoothVoiceNoteUtil {
private val commandAndControlThread: HandlerThread = SignalExecutors.getAndStartHandlerThread("voice-note-audio", ThreadUtil.PRIORITY_IMPORTANT_BACKGROUND_THREAD)
private val uiThreadHandler = Handler(context.mainLooper)
private val audioHandler: SignalAudioHandler = SignalAudioHandler(commandAndControlThread.looper)
private val deviceUpdatedListener: AudioDeviceUpdatedListener = object : AudioDeviceUpdatedListener {
override fun onAudioDeviceUpdated() {
if (signalBluetoothManager.state == SignalBluetoothManager.State.CONNECTED) {
Log.d(TAG, "Bluetooth SCO connected. Starting voice note recording on UI thread.")
uiThreadHandler.post { listener() }
when (signalBluetoothManager.state) {
SignalBluetoothManager.State.CONNECTED -> {
Log.d(TAG, "Bluetooth SCO connected. Starting voice note recording on UI thread.")
uiThreadHandler.post { listener(true) }
}
SignalBluetoothManager.State.ERROR,
SignalBluetoothManager.State.PERMISSION_DENIED -> {
Log.w(TAG, "Unable to complete Bluetooth connection due to ${signalBluetoothManager.state}. Starting voice note recording anyway on UI thread.")
uiThreadHandler.post { listener(false) }
}
else -> Log.d(TAG, "Current Bluetooth connection state: ${signalBluetoothManager.state}.")
}
}
}
@@ -105,7 +115,7 @@ private class BluetoothVoiceNoteUtilLegacy(val context: Context, val listener: (
bluetoothPermissionDeniedHandler()
hasWarnedAboutBluetooth = true
}
listener()
listener(false)
}
}
}

View File

@@ -58,6 +58,7 @@ import androidx.annotation.ColorRes;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.annotation.WorkerThread;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.SearchView;
@@ -304,7 +305,6 @@ import org.whispersystems.signalservice.api.SignalSessionLock;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
@@ -513,7 +513,7 @@ public class ConversationParentFragment extends Fragment
voiceNoteMediaController = new VoiceNoteMediaController(requireActivity(), true);
voiceRecorderWakeLock = new VoiceRecorderWakeLock(requireActivity());
bluetoothVoiceNoteUtil = BluetoothVoiceNoteUtil.Companion.create(requireContext(), this::beginRecording, this::onBluetoothPermissionDenied);
bluetoothVoiceNoteUtil = BluetoothVoiceNoteUtil.Companion.create(requireContext(), this::onBluetoothConnectionAttempt, this::onBluetoothPermissionDenied);
// TODO [alex] LargeScreenSupport -- Should be removed once we move to multi-pane layout.
new FullscreenHelper(requireActivity()).showSystemUI();
@@ -3306,6 +3306,11 @@ public class ConversationParentFragment extends Fragment
}
}
private Unit onBluetoothConnectionAttempt(Boolean success) {
beginRecording();
return Unit.INSTANCE;
}
private Unit beginRecording() {
Vibrator vibrator = ServiceUtil.getVibrator(requireContext());
vibrator.vibrate(20);

View File

@@ -47,7 +47,7 @@ class VoiceMessageRecordingDelegate(
private val voiceRecorderWakeLock = VoiceRecorderWakeLock(fragment.requireActivity())
private val bluetoothVoiceNoteUtil = BluetoothVoiceNoteUtil.create(
fragment.requireContext(),
this::beginRecording,
this::onBluetoothConnectionAttempt,
this::onBluetoothPermissionDenied
)
@@ -104,6 +104,10 @@ class VoiceMessageRecordingDelegate(
bluetoothVoiceNoteUtil.connectBluetoothScoConnection()
}
private fun onBluetoothConnectionAttempt(success: Boolean) {
beginRecording()
}
@Suppress("DEPRECATION")
private fun beginRecording() {
val vibrator = ServiceUtil.getVibrator(fragment.requireContext())