Launch 'MagicBluetoothManager' independently

This change is needed to make the 'MagicBluetoothManager' startable
after the from Android SDK 31 introduced BLUETOOTH_CONNECT is granted by
the user.

Before this change the 'MagicBluetoothManager' was only started in
'MagicAudioManager#start'. Now the new method
'MagicAudioManager#startBluetoothManager' can be used to start the
'MagicBluetoothManager'.

This change is also a preperation to fix #1309 and #2114.

See: #2132, #1309, #2124

Signed-off-by: Tim Krüger <t@timkrueger.me>
This commit is contained in:
Tim Krüger 2022-06-15 13:38:36 +02:00
parent 4821b02729
commit dedbe40cc0
No known key found for this signature in database
GPG Key ID: FECE3A7222C52A4E
2 changed files with 27 additions and 14 deletions

View File

@ -2,6 +2,8 @@
* Nextcloud Talk application * Nextcloud Talk application
* *
* @author Mario Danic * @author Mario Danic
* @author Tim Krüger
* Copyright (C) 2022 Tim Krüger <t@timkrueger.me>
* Copyright (C) 2017 Mario Danic <mario@lovelyhq.com> * Copyright (C) 2017 Mario Danic <mario@lovelyhq.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -52,15 +54,12 @@ import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
/**
* MagicAudioManager manages all audio related parts of the AppRTC demo.
*/
public class MagicAudioManager { public class MagicAudioManager {
private static final String TAG = "MagicAudioManager"; private static final String TAG = MagicAudioManager.class.getCanonicalName();
private final Context magicContext; private final Context magicContext;
private final MagicBluetoothManager bluetoothManager; private final MagicBluetoothManager bluetoothManager;
private boolean useProximitySensor; private final boolean useProximitySensor;
private AudioManager audioManager; private final AudioManager audioManager;
private AudioManagerListener audioManagerListener; private AudioManagerListener audioManagerListener;
private AudioManagerState amState; private AudioManagerState amState;
private int savedAudioMode = AudioManager.MODE_INVALID; private int savedAudioMode = AudioManager.MODE_INVALID;
@ -75,10 +74,10 @@ public class MagicAudioManager {
private Set<AudioDevice> audioDevices = new HashSet<>(); private Set<AudioDevice> audioDevices = new HashSet<>();
private BroadcastReceiver wiredHeadsetReceiver; private final BroadcastReceiver wiredHeadsetReceiver;
private AudioManager.OnAudioFocusChangeListener audioFocusChangeListener; private AudioManager.OnAudioFocusChangeListener audioFocusChangeListener;
private PowerManagerUtils powerManagerUtils; private final PowerManagerUtils powerManagerUtils;
private MagicAudioManager(Context context, boolean useProximitySensor) { private MagicAudioManager(Context context, boolean useProximitySensor) {
Log.d(TAG, "ctor"); Log.d(TAG, "ctor");
@ -112,7 +111,13 @@ public class MagicAudioManager {
* Construction. * Construction.
*/ */
public static MagicAudioManager create(Context context, boolean useProximitySensor) { public static MagicAudioManager create(Context context, boolean useProximitySensor) {
return new MagicAudioManager(context, useProximitySensor); return new MagicAudioManager(context, useProximitySensor);
}
public void startBluetoothManager() {
// Initialize and start Bluetooth if a BT device is available or initiate
// detection of new (enabled) BT devices.
bluetoothManager.start();
} }
/** /**
@ -228,9 +233,7 @@ public class MagicAudioManager {
currentAudioDevice = AudioDevice.NONE; currentAudioDevice = AudioDevice.NONE;
audioDevices.clear(); audioDevices.clear();
// Initialize and start Bluetooth if a BT device is available or initiate startBluetoothManager();
// detection of new (enabled) BT devices.
bluetoothManager.start();
// Do initial selection of audio device. This setting can later be changed // Do initial selection of audio device. This setting can later be changed
// either by adding/removing a BT or wired headset or by covering/uncovering // either by adding/removing a BT or wired headset or by covering/uncovering
@ -256,7 +259,9 @@ public class MagicAudioManager {
unregisterReceiver(wiredHeadsetReceiver); unregisterReceiver(wiredHeadsetReceiver);
bluetoothManager.stop(); if(bluetoothManager.started()) {
bluetoothManager.stop();
}
// Restore previously stored audio states. // Restore previously stored audio states.
setSpeakerphoneOn(savedIsSpeakerPhoneOn); setSpeakerphoneOn(savedIsSpeakerPhoneOn);

View File

@ -2,6 +2,8 @@
* Nextcloud Talk application * Nextcloud Talk application
* *
* @author Mario Danic * @author Mario Danic
* @author Tim Krüger
* Copyright (C) 2022 Tim Krüger <t@timkrueger.me>
* Copyright (C) 2017 Mario Danic <mario@lovelyhq.com> * Copyright (C) 2017 Mario Danic <mario@lovelyhq.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -57,7 +59,7 @@ import java.util.Set;
import androidx.core.app.ActivityCompat; import androidx.core.app.ActivityCompat;
public class MagicBluetoothManager { public class MagicBluetoothManager {
private static final String TAG = "MagicBluetoothManager"; private static final String TAG = MagicBluetoothManager.class.getCanonicalName();
// Timeout interval for starting or stopping audio to a Bluetooth SCO device. // Timeout interval for starting or stopping audio to a Bluetooth SCO device.
private static final int BLUETOOTH_SCO_TIMEOUT_MS = 4000; private static final int BLUETOOTH_SCO_TIMEOUT_MS = 4000;
@ -78,6 +80,7 @@ public class MagicBluetoothManager {
// startScoAudio() or stopScoAudio() because we're not guaranteed to get a // startScoAudio() or stopScoAudio() because we're not guaranteed to get a
// callback after those calls. // callback after those calls.
private final Runnable bluetoothTimeoutRunnable = this::bluetoothTimeout; private final Runnable bluetoothTimeoutRunnable = this::bluetoothTimeout;
private boolean started = false;
protected MagicBluetoothManager(Context context, MagicAudioManager audioManager) { protected MagicBluetoothManager(Context context, MagicAudioManager audioManager) {
Log.d(TAG, "ctor"); Log.d(TAG, "ctor");
@ -165,6 +168,7 @@ public class MagicBluetoothManager {
+ stateToString(bluetoothAdapter.getProfileConnectionState(BluetoothProfile.HEADSET))); + stateToString(bluetoothAdapter.getProfileConnectionState(BluetoothProfile.HEADSET)));
Log.d(TAG, "Bluetooth proxy for headset profile has started"); Log.d(TAG, "Bluetooth proxy for headset profile has started");
bluetoothState = State.HEADSET_UNAVAILABLE; bluetoothState = State.HEADSET_UNAVAILABLE;
started = true;
Log.d(TAG, "start done: BT state=" + bluetoothState); Log.d(TAG, "start done: BT state=" + bluetoothState);
} }
@ -454,6 +458,10 @@ public class MagicBluetoothManager {
} }
} }
public boolean started() {
return started;
}
// Bluetooth connection state. // Bluetooth connection state.
public enum State { public enum State {
// Bluetooth is not available; no adapter or Bluetooth is off. // Bluetooth is not available; no adapter or Bluetooth is off.