Split long methods into multiple shorter ones
This commit is contained in:
parent
bab94a207d
commit
18bc99d6b5
|
@ -14,7 +14,6 @@ import android.util.Log;
|
||||||
|
|
||||||
import com.facebook.react.bridge.Promise;
|
import com.facebook.react.bridge.Promise;
|
||||||
import com.facebook.react.bridge.ReactApplicationContext;
|
import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
import com.facebook.react.bridge.ReactContext;
|
|
||||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||||
import com.facebook.react.bridge.ReactMethod;
|
import com.facebook.react.bridge.ReactMethod;
|
||||||
|
|
||||||
|
@ -83,12 +82,21 @@ public class AudioModeModule extends ReactContextBaseJavaModule {
|
||||||
/**
|
/**
|
||||||
* {@link Handler} for running all operations on the main thread.
|
* {@link Handler} for running all operations on the main thread.
|
||||||
*/
|
*/
|
||||||
private final Handler mainThreadHandler;
|
private final Handler mainThreadHandler
|
||||||
|
= new Handler(Looper.getMainLooper());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link Runnable} for running update operation on the main thread.
|
* {@link Runnable} for running update operation on the main thread.
|
||||||
*/
|
*/
|
||||||
private final Runnable mainThreadRunner;
|
private final Runnable mainThreadRunner
|
||||||
|
= new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (mode != -1) {
|
||||||
|
updateAudioRoute(mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Audio mode currently in use.
|
* Audio mode currently in use.
|
||||||
|
@ -108,15 +116,6 @@ public class AudioModeModule extends ReactContextBaseJavaModule {
|
||||||
audioManager
|
audioManager
|
||||||
= (AudioManager)
|
= (AudioManager)
|
||||||
reactContext.getSystemService(Context.AUDIO_SERVICE);
|
reactContext.getSystemService(Context.AUDIO_SERVICE);
|
||||||
mainThreadHandler = new Handler(Looper.getMainLooper());
|
|
||||||
mainThreadRunner = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (mode != -1) {
|
|
||||||
updateAudioRoute(mode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Setup runtime device change detection.
|
// Setup runtime device change detection.
|
||||||
setupAudioRouteChangeDetection();
|
setupAudioRouteChangeDetection();
|
||||||
|
@ -243,7 +242,7 @@ public class AudioModeModule extends ReactContextBaseJavaModule {
|
||||||
* Audio route change detection mechanism for Android API < 23.
|
* Audio route change detection mechanism for Android API < 23.
|
||||||
*/
|
*/
|
||||||
private void setupAudioRouteChangeDetectionPreM() {
|
private void setupAudioRouteChangeDetectionPreM() {
|
||||||
ReactContext reactContext = getReactApplicationContext();
|
Context context = getReactApplicationContext();
|
||||||
|
|
||||||
// Detect changes in wired headset connections.
|
// Detect changes in wired headset connections.
|
||||||
IntentFilter wiredHeadSetFilter = new IntentFilter(ACTION_HEADSET_PLUG);
|
IntentFilter wiredHeadSetFilter = new IntentFilter(ACTION_HEADSET_PLUG);
|
||||||
|
@ -254,14 +253,10 @@ public class AudioModeModule extends ReactContextBaseJavaModule {
|
||||||
onAudioDeviceChange();
|
onAudioDeviceChange();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
reactContext.registerReceiver(wiredHeadsetReceiver, wiredHeadSetFilter);
|
context.registerReceiver(wiredHeadsetReceiver, wiredHeadSetFilter);
|
||||||
|
|
||||||
// Detect Bluetooth device changes.
|
// Detect Bluetooth device changes.
|
||||||
bluetoothHeadsetMonitor
|
bluetoothHeadsetMonitor = new BluetoothHeadsetMonitor(this, context);
|
||||||
= new BluetoothHeadsetMonitor(
|
|
||||||
this,
|
|
||||||
getReactApplicationContext());
|
|
||||||
bluetoothHeadsetMonitor.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,46 +13,26 @@ import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.facebook.react.bridge.ReactContext;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class to detect and handle Bluetooth device changes. It monitors
|
* Helper class to detect and handle Bluetooth device changes. It monitors
|
||||||
* Bluetooth headsets being connected / disconnected and notifies the module
|
* Bluetooth headsets being connected / disconnected and notifies the module
|
||||||
* about device changes when this occurs.
|
* about device changes when this occurs.
|
||||||
*/
|
*/
|
||||||
public class BluetoothHeadsetMonitor {
|
public class BluetoothHeadsetMonitor {
|
||||||
/**
|
|
||||||
* {@link AudioManager} instance used to interact with the Android audio
|
|
||||||
* subsystem.
|
|
||||||
*/
|
|
||||||
private final AudioManager audioManager;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link AudioModeModule} where this monitor reports.
|
* {@link AudioModeModule} where this monitor reports.
|
||||||
*/
|
*/
|
||||||
private final AudioModeModule audioModeModule;
|
private final AudioModeModule audioModeModule;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reference to the Bluetooth adapter, needed for managing
|
* The {@link Context} in which {@link #audioModeModule} executes.
|
||||||
* <tt>BluetoothProfile.HEADSET</tt> devices.
|
|
||||||
*/
|
*/
|
||||||
private BluetoothAdapter bluetoothAdapter;
|
private final Context context;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reference to a proxy object which allows us to query connected devices.
|
* Reference to a proxy object which allows us to query connected devices.
|
||||||
*/
|
*/
|
||||||
private BluetoothHeadset bluetoothHeadset;
|
private BluetoothHeadset headset;
|
||||||
|
|
||||||
/**
|
|
||||||
* Listener for Bluetooth service profiles, allows us to get the proxy
|
|
||||||
* object to {@link BluetoothHeadset}.
|
|
||||||
*/
|
|
||||||
private BluetoothProfile.ServiceListener bluetoothProfileListener;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper for running Bluetooth operations on the main thread.
|
|
||||||
*/
|
|
||||||
private Runnable bluetoothRunnable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag indicating if there are any Bluetooth headset devices currently
|
* Flag indicating if there are any Bluetooth headset devices currently
|
||||||
|
@ -63,23 +43,80 @@ public class BluetoothHeadsetMonitor {
|
||||||
/**
|
/**
|
||||||
* {@link Handler} for running all operations on the main thread.
|
* {@link Handler} for running all operations on the main thread.
|
||||||
*/
|
*/
|
||||||
private final Handler mainThreadHandler;
|
private final Handler mainThreadHandler
|
||||||
|
= new Handler(Looper.getMainLooper());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ReactContext} instance where the main module runs.
|
* Helper for running Bluetooth operations on the main thread.
|
||||||
*/
|
*/
|
||||||
private final ReactContext reactContext;
|
private final Runnable updateDevicesRunnable
|
||||||
|
= new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
headsetAvailable
|
||||||
|
= (headset != null)
|
||||||
|
&& !headset.getConnectedDevices().isEmpty();
|
||||||
|
audioModeModule.onAudioDeviceChange();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public BluetoothHeadsetMonitor(
|
public BluetoothHeadsetMonitor(
|
||||||
AudioModeModule audioModeModule,
|
AudioModeModule audioModeModule,
|
||||||
ReactContext reactContext) {
|
Context context) {
|
||||||
this.audioModeModule = audioModeModule;
|
this.audioModeModule = audioModeModule;
|
||||||
this.reactContext = reactContext;
|
this.context = context;
|
||||||
|
|
||||||
audioManager
|
AudioManager audioManager
|
||||||
= (AudioManager)
|
= (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||||
reactContext.getSystemService(Context.AUDIO_SERVICE);
|
|
||||||
mainThreadHandler = new Handler(Looper.getMainLooper());
|
if (!audioManager.isBluetoothScoAvailableOffCall()) {
|
||||||
|
Log.w(AudioModeModule.TAG, "Bluetooth SCO is not available");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getBluetoothHeadsetProfileProxy()) {
|
||||||
|
registerBluetoothReceiver();
|
||||||
|
|
||||||
|
// Initial detection.
|
||||||
|
updateDevices();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean getBluetoothHeadsetProfileProxy() {
|
||||||
|
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
||||||
|
|
||||||
|
if (adapter == null) {
|
||||||
|
Log.w(AudioModeModule.TAG, "Device doesn't support Bluetooth");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX: The profile listener listens for system services of the given
|
||||||
|
// type being available to the application. That is, if our Bluetooth
|
||||||
|
// adapter has the "headset" profile.
|
||||||
|
BluetoothProfile.ServiceListener listener
|
||||||
|
= new BluetoothProfile.ServiceListener() {
|
||||||
|
@Override
|
||||||
|
public void onServiceConnected(
|
||||||
|
int profile,
|
||||||
|
BluetoothProfile proxy) {
|
||||||
|
if (profile == BluetoothProfile.HEADSET) {
|
||||||
|
headset = (BluetoothHeadset) proxy;
|
||||||
|
updateDevices();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceDisconnected(int profile) {
|
||||||
|
// The logic is the same as the logic of onServiceConnected.
|
||||||
|
onServiceConnected(profile, /* proxy */ null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return
|
||||||
|
adapter.getProfileProxy(
|
||||||
|
context,
|
||||||
|
listener,
|
||||||
|
BluetoothProfile.HEADSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -91,115 +128,55 @@ public class BluetoothHeadsetMonitor {
|
||||||
return headsetAvailable;
|
return headsetAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void onBluetoothReceiverReceive(Context context, Intent intent) {
|
||||||
* Start monitoring Bluetooth device activity.
|
final String action = intent.getAction();
|
||||||
*/
|
|
||||||
public void start() {
|
|
||||||
bluetoothRunnable = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (bluetoothHeadset == null) {
|
|
||||||
headsetAvailable = false;
|
|
||||||
} else {
|
|
||||||
headsetAvailable
|
|
||||||
= !bluetoothHeadset.getConnectedDevices().isEmpty();
|
|
||||||
}
|
|
||||||
audioModeModule.onAudioDeviceChange();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
|
||||||
if (bluetoothAdapter == null) {
|
// XXX: This action will be fired when a Bluetooth headset is
|
||||||
Log.w(AudioModeModule.TAG, "Device doesn't support Bluetooth");
|
// connected or disconnected to the system. This is not related to
|
||||||
return;
|
// audio routing.
|
||||||
|
int state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, -99);
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case BluetoothHeadset.STATE_CONNECTED:
|
||||||
|
case BluetoothHeadset.STATE_DISCONNECTED:
|
||||||
|
Log.d(
|
||||||
|
AudioModeModule.TAG,
|
||||||
|
"BT headset connection state changed: " + state);
|
||||||
|
updateDevices();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (action.equals(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)) {
|
||||||
|
// XXX: This action will be fired when the connection established
|
||||||
|
// with a Bluetooth headset (called a SCO connection) changes state.
|
||||||
|
// When the SCO connection is active we route audio to it.
|
||||||
|
int state
|
||||||
|
= intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -99);
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case AudioManager.SCO_AUDIO_STATE_CONNECTED:
|
||||||
|
case AudioManager.SCO_AUDIO_STATE_DISCONNECTED:
|
||||||
|
Log.d(
|
||||||
|
AudioModeModule.TAG,
|
||||||
|
"BT SCO connection state changed: " + state);
|
||||||
|
updateDevices();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!audioManager.isBluetoothScoAvailableOffCall()) {
|
private void registerBluetoothReceiver() {
|
||||||
Log.w(AudioModeModule.TAG, "Bluetooth SCO is not available");
|
BroadcastReceiver receiver = new BroadcastReceiver() {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX: The profile listener listens for system services of the given
|
|
||||||
// type being available to the application. That is, if our Bluetooth
|
|
||||||
// adapter has the "headset" profile.
|
|
||||||
bluetoothProfileListener = new BluetoothProfile.ServiceListener() {
|
|
||||||
@Override
|
|
||||||
public void onServiceConnected(
|
|
||||||
int profile,
|
|
||||||
BluetoothProfile proxy) {
|
|
||||||
if (profile == BluetoothProfile.HEADSET) {
|
|
||||||
bluetoothHeadset = (BluetoothHeadset) proxy;
|
|
||||||
updateDevices();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onServiceDisconnected(int profile) {
|
|
||||||
if (profile == BluetoothProfile.HEADSET) {
|
|
||||||
bluetoothHeadset = null;
|
|
||||||
updateDevices();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bluetoothAdapter.getProfileProxy(reactContext,
|
|
||||||
bluetoothProfileListener, BluetoothProfile.HEADSET);
|
|
||||||
|
|
||||||
IntentFilter bluetoothFilter = new IntentFilter();
|
|
||||||
bluetoothFilter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
|
|
||||||
bluetoothFilter.addAction(
|
|
||||||
BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
|
|
||||||
BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
final String action = intent.getAction();
|
onBluetoothReceiverReceive(context, intent);
|
||||||
if (action.equals(
|
|
||||||
BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
|
|
||||||
// XXX: This action will be fired when a Bluetooth headset
|
|
||||||
// is connected or disconnected to the system. This is not
|
|
||||||
// related to audio routing.
|
|
||||||
final int state
|
|
||||||
= intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, -99);
|
|
||||||
switch (state) {
|
|
||||||
case BluetoothHeadset.STATE_CONNECTED:
|
|
||||||
case BluetoothHeadset.STATE_DISCONNECTED:
|
|
||||||
Log.d(
|
|
||||||
AudioModeModule.TAG,
|
|
||||||
"BT headset connection state changed: "
|
|
||||||
+ state);
|
|
||||||
updateDevices();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (action.equals(
|
|
||||||
AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)) {
|
|
||||||
// XXX: This action will be fired when the connection
|
|
||||||
// established with a Bluetooth headset (called a SCO
|
|
||||||
// connection) changes state. When the SCO connection is
|
|
||||||
// active we route audio to it.
|
|
||||||
final int state
|
|
||||||
= intent.getIntExtra(
|
|
||||||
AudioManager.EXTRA_SCO_AUDIO_STATE,
|
|
||||||
-99);
|
|
||||||
switch (state) {
|
|
||||||
case AudioManager.SCO_AUDIO_STATE_CONNECTED:
|
|
||||||
case AudioManager.SCO_AUDIO_STATE_DISCONNECTED:
|
|
||||||
Log.d(
|
|
||||||
AudioModeModule.TAG,
|
|
||||||
"BT SCO connection state changed: " + state);
|
|
||||||
updateDevices();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
reactContext.registerReceiver(bluetoothReceiver, bluetoothFilter);
|
IntentFilter filter = new IntentFilter();
|
||||||
|
|
||||||
// Initial detection.
|
filter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
|
||||||
updateDevices();
|
filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
|
||||||
|
context.registerReceiver(receiver, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -207,6 +184,6 @@ public class BluetoothHeadsetMonitor {
|
||||||
* {@link AudioModeModule#onAudioDeviceChange()} callback.
|
* {@link AudioModeModule#onAudioDeviceChange()} callback.
|
||||||
*/
|
*/
|
||||||
private void updateDevices() {
|
private void updateDevices() {
|
||||||
mainThreadHandler.post(bluetoothRunnable);
|
mainThreadHandler.post(updateDevicesRunnable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue