From 0e5031ab451bd069cb5b59f4e57ce166438acf36 Mon Sep 17 00:00:00 2001 From: Nicholas Tinsley Date: Wed, 21 Dec 2022 13:25:56 -0500 Subject: [PATCH] Revert "Switch to BT mic if available for voice memo recording." This reverts commit 9f6eb142d28a72eac1e0a9cdcc9493d2c47c7bb8. --- .../securesms/audio/AudioRecorder.java | 18 +-- .../audio/BluetoothScoSessionManager.kt | 110 ------------------ 2 files changed, 5 insertions(+), 123 deletions(-) delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/audio/BluetoothScoSessionManager.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/audio/AudioRecorder.java b/app/src/main/java/org/thoughtcrime/securesms/audio/AudioRecorder.java index 54ba18f6eb..74d39c1a59 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/audio/AudioRecorder.java +++ b/app/src/main/java/org/thoughtcrime/securesms/audio/AudioRecorder.java @@ -26,17 +26,15 @@ public class AudioRecorder { private static final ExecutorService executor = SignalExecutors.newCachedSingleThreadExecutor("signal-AudioRecorder"); - private final Context context; - private final AudioRecorderFocusManager audioFocusManager; - private final BluetoothScoSessionManager bluetoothScoSessionManager; + private final Context context; + private final AudioRecorderFocusManager audioFocusManager; private Recorder recorder; private Uri captureUri; public AudioRecorder(@NonNull Context context) { this.context = context; - audioFocusManager = AudioRecorderFocusManager.create(context, focusChange -> stopRecording()); - bluetoothScoSessionManager = new BluetoothScoSessionManager(context); + audioFocusManager = AudioRecorderFocusManager.create(context, focusChange -> stopRecording()); } public void startRecording() { @@ -55,18 +53,13 @@ public class AudioRecorder { .forData(new ParcelFileDescriptor.AutoCloseInputStream(fds[0]), 0) .withMimeType(MediaUtil.AUDIO_AAC) .createForDraftAttachmentAsync(context, () -> Log.i(TAG, "Write successful."), e -> Log.w(TAG, "Error during recording", e)); + recorder = Build.VERSION.SDK_INT >= 26 ? new MediaRecorderWrapper() : new AudioCodec(); int focusResult = audioFocusManager.requestAudioFocus(); if (focusResult != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { Log.w(TAG, "Could not gain audio focus. Received result code " + focusResult); } - if (bluetoothScoSessionManager.isBluetoothScoCapable()) { - Log.i(TAG, "Starting voice memo recording with Bluetooth mic."); - bluetoothScoSessionManager.startBluetooth(recorder, fds[1]); - } else { - Log.i(TAG, "Starting voice memo recording with built-in mic."); - recorder.start(fds[1]); - } + recorder.start(fds[1]); } catch (IOException e) { Log.w(TAG, e); } @@ -86,7 +79,6 @@ public class AudioRecorder { audioFocusManager.abandonAudioFocus(); recorder.stop(); - bluetoothScoSessionManager.stopBluetooth(); try { long size = MediaUtil.getMediaSize(context, captureUri); diff --git a/app/src/main/java/org/thoughtcrime/securesms/audio/BluetoothScoSessionManager.kt b/app/src/main/java/org/thoughtcrime/securesms/audio/BluetoothScoSessionManager.kt deleted file mode 100644 index 4a138d247b..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/audio/BluetoothScoSessionManager.kt +++ /dev/null @@ -1,110 +0,0 @@ -package org.thoughtcrime.securesms.audio - -import android.annotation.SuppressLint -import android.bluetooth.BluetoothAdapter -import android.bluetooth.BluetoothHeadset -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.content.IntentFilter -import android.media.AudioDeviceInfo -import android.media.AudioManager -import android.os.Build -import android.os.ParcelFileDescriptor -import org.signal.core.util.logging.Log -import org.thoughtcrime.securesms.util.ServiceUtil -import java.io.IOException - -/** - * This class manages the SCO (Synchronous Connection Oriented) Bluetooth link for voice memos. - * A consumer of this class should first check if the hardware is prepared to receive input from a bluetooth device using [isBluetoothScoCapable] - * Then they can use [startBluetooth] to initiate a session. - * We send initialize an SCO link and receive its state updates as a system Broadcast. - * Once the connection is established, we start storing audio via the provided [Recorder] - * It is the responsibility of the owner of this object to close the Bluetooth link when recording is finished. - * - * Note: in testing, closing the SCO link does not interrupt an in-progress recording, and a user is free to continue recording on the device's mic. - */ -class BluetoothScoSessionManager(val context: Context) : BroadcastReceiver() { - private val audioManager: AudioManager = ServiceUtil.getAudioManager(context) - private var bluetoothSessionAlive: Boolean = false - private var callback: Recorder? = null - private var fileDescriptor: ParcelFileDescriptor? = null - - private fun register() { - Log.d(TAG, "Registering Bluetooth SCO broadcast receiver.") - val filter = IntentFilter() - filter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED) - context.registerReceiver(this, filter) - } - - private fun unregister() { - Log.d(TAG, "Unregistering Bluetooth SCO broadcast receiver.") - context.unregisterReceiver(this) - } - - fun isBluetoothScoCapable(): Boolean { - if (!audioManager.isBluetoothScoAvailableOffCall) { - return false - } - - return if (Build.VERSION.SDK_INT >= 31) { - audioManager.availableCommunicationDevices.any { it.type == AudioDeviceInfo.TYPE_BLUETOOTH_SCO } - } else if (Build.VERSION.SDK_INT >= 23) { - audioManager.getDevices(AudioManager.GET_DEVICES_INPUTS).any { it.type == AudioDeviceInfo.TYPE_BLUETOOTH_SCO } - } else { - hasBluetoothMicConnectedLegacy() - } - } - - @SuppressLint("MissingPermission") - private fun hasBluetoothMicConnectedLegacy(): Boolean { - val mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter() - return mBluetoothAdapter != null && mBluetoothAdapter.isEnabled && - mBluetoothAdapter.getProfileConnectionState(BluetoothHeadset.HEADSET) == BluetoothHeadset.STATE_CONNECTED - } - - fun startBluetooth(callback: Recorder, fileDescriptor: ParcelFileDescriptor) { - Log.d(TAG, "Starting Bluetooth SCO for voice memo.") - this.callback = callback - this.fileDescriptor = fileDescriptor - register() - audioManager.startBluetoothSco() - } - - fun stopBluetooth() { - if (bluetoothSessionAlive) { - Log.d(TAG, "Stopping Bluetooth SCO for voice memo.") - bluetoothSessionAlive = false - unregister() - if (audioManager.isBluetoothScoOn) { - audioManager.stopBluetoothSco() - } - } - } - - override fun onReceive(context: Context, intent: Intent) { - val action = intent.action ?: return - if (action == AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED) { - val state: Int = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1) - when (state) { - AudioManager.SCO_AUDIO_STATE_CONNECTED -> try { - bluetoothSessionAlive = true - callback?.start(fileDescriptor) - Log.d(TAG, "Bluetooth SCO connected.") - } catch (e: IOException) { - Log.w(TAG, e) - } - AudioManager.SCO_AUDIO_STATE_CONNECTING -> Log.d(TAG, "Bluetooth SCO in connecting state.") - AudioManager.SCO_AUDIO_STATE_DISCONNECTED -> { - Log.d(TAG, "Bluetooth SCO disconnected.") - stopBluetooth() - } - } - } - } - - companion object { - const val TAG = "BluetoothMicManager" - } -}