Split long methods into multiple shorter ones

This commit is contained in:
Lyubomir Marinov 2017-01-26 23:35:56 -06:00
parent bab94a207d
commit 18bc99d6b5
2 changed files with 125 additions and 153 deletions

View File

@ -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();
} }
/** /**

View File

@ -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);
} }
} }