@@ -179,9 +179,9 @@ public class JuceDemo extends Activity | |||
return address; | |||
} | |||
public boolean isBluetoothDevicePaired (String address) | |||
public int getBluetoothDeviceStatus (String address) | |||
{ | |||
return false; | |||
return 0; | |||
} | |||
public void startStopScan (boolean shouldStart) | |||
@@ -194,9 +194,9 @@ public class MidiTest extends Activity | |||
return btDevice.getName(); | |||
} | |||
public boolean isBluetoothDevicePaired (String address) | |||
public int getBluetoothDeviceStatus (String address) | |||
{ | |||
return getAndroidMidiDeviceManager().isBluetoothDevicePaired (address); | |||
return getAndroidMidiDeviceManager().getBluetoothDeviceStatus (address); | |||
} | |||
public void startStopScan (boolean shouldStart) | |||
@@ -487,7 +487,78 @@ public class MidiTest extends Activity | |||
//============================================================================== | |||
public class MidiDeviceManager extends MidiManager.DeviceCallback implements MidiManager.OnDeviceOpenedListener | |||
{ | |||
//============================================================================== | |||
private class MidiDeviceOpenTask extends java.util.TimerTask | |||
{ | |||
public MidiDeviceOpenTask (MidiDeviceManager deviceManager, MidiDevice device) | |||
{ | |||
owner = deviceManager; | |||
midiDevice = device; | |||
} | |||
@Override | |||
public boolean cancel() | |||
{ | |||
synchronized (MidiDeviceOpenTask.class) | |||
{ | |||
owner = null; | |||
boolean retval = super.cancel(); | |||
if (midiDevice != null) | |||
{ | |||
try | |||
{ | |||
midiDevice.close(); | |||
} | |||
catch (IOException e) | |||
{} | |||
midiDevice = null; | |||
} | |||
return retval; | |||
} | |||
} | |||
public String getBluetoothAddress() | |||
{ | |||
synchronized (MidiDeviceOpenTask.class) | |||
{ | |||
if (midiDevice != null) | |||
{ | |||
MidiDeviceInfo info = midiDevice.getInfo(); | |||
if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH) | |||
{ | |||
BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); | |||
if (btDevice != null) | |||
return btDevice.getAddress(); | |||
} | |||
} | |||
} | |||
return ""; | |||
} | |||
public int getID() | |||
{ | |||
return midiDevice.getInfo().getId(); | |||
} | |||
@Override | |||
public void run() | |||
{ | |||
synchronized (MidiDeviceOpenTask.class) | |||
{ | |||
if (owner != null && midiDevice != null) | |||
owner.onDeviceOpenedDelayed (midiDevice); | |||
} | |||
} | |||
private MidiDeviceManager owner; | |||
private MidiDevice midiDevice; | |||
} | |||
//============================================================================== | |||
public MidiDeviceManager() | |||
{ | |||
manager = (MidiManager) getSystemService (MIDI_SERVICE); | |||
@@ -500,6 +571,8 @@ public class MidiTest extends Activity | |||
openPorts = new HashMap<MidiPortPath, WeakReference<JuceMidiPort>> (); | |||
midiDevices = new ArrayList<MidiDevice>(); | |||
openTasks = new HashMap<Integer, MidiDeviceOpenTask>(); | |||
btDevicesPairing = new HashSet<String>(); | |||
MidiDeviceInfo[] foundDevices = manager.getDevices(); | |||
for (MidiDeviceInfo info : foundDevices) | |||
@@ -512,6 +585,16 @@ public class MidiTest extends Activity | |||
{ | |||
manager.unregisterDeviceCallback (this); | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
btDevicesPairing.clear(); | |||
for (Integer deviceID : openTasks.keySet()) | |||
openTasks.get (deviceID).cancel(); | |||
openTasks = null; | |||
} | |||
for (MidiPortPath key : openPorts.keySet()) | |||
openPorts.get (key).get().close(); | |||
@@ -606,21 +689,62 @@ public class MidiTest extends Activity | |||
return openMidiPortWithJuceIndex (index, 0, false); | |||
} | |||
public boolean isBluetoothDevicePaired (String address) | |||
/* 0: unpaired, 1: paired, 2: pairing */ | |||
public int getBluetoothDeviceStatus (String address) | |||
{ | |||
return (findMidiDeviceForBluetoothAddress (address) != null); | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
if (! address.isEmpty()) | |||
{ | |||
if (findMidiDeviceForBluetoothAddress (address) != null) | |||
return 1; | |||
if (btDevicesPairing.contains (address)) | |||
return 2; | |||
if (findOpenTaskForBluetoothAddress (address) != null) | |||
return 2; | |||
} | |||
} | |||
return 0; | |||
} | |||
public boolean pairBluetoothDevice (BluetoothDevice btDevice) | |||
{ | |||
manager.openBluetoothDevice(btDevice, this, null); | |||
String btAddress = btDevice.getAddress(); | |||
if (btAddress.isEmpty()) | |||
return false; | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
if (getBluetoothDeviceStatus (btAddress) != 0) | |||
return false; | |||
btDevicesPairing.add (btDevice.getAddress()); | |||
manager.openBluetoothDevice(btDevice, this, null); | |||
} | |||
return true; | |||
} | |||
public void unpairBluetoothDevice (String address) | |||
{ | |||
if (address.isEmpty()) | |||
return; | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
btDevicesPairing.remove (address); | |||
MidiDeviceOpenTask openTask = findOpenTaskForBluetoothAddress (address); | |||
if (openTask != null) | |||
{ | |||
int deviceID = openTask.getID(); | |||
openTask.cancel(); | |||
openTasks.remove (deviceID); | |||
} | |||
MidiDevice midiDevice = findMidiDeviceForBluetoothAddress (address); | |||
if (midiDevice != null) | |||
{ | |||
@@ -653,6 +777,18 @@ public class MidiTest extends Activity | |||
return null; | |||
} | |||
private MidiDeviceOpenTask findOpenTaskForBluetoothAddress (String address) | |||
{ | |||
for (Integer deviceID : openTasks.keySet()) | |||
{ | |||
MidiDeviceOpenTask openTask = openTasks.get (deviceID); | |||
if (openTask.getBluetoothAddress().equals (address)) | |||
return openTask; | |||
} | |||
return null; | |||
} | |||
public void removePort (MidiPortPath path) | |||
{ | |||
openPorts.remove (path); | |||
@@ -719,9 +855,68 @@ public class MidiTest extends Activity | |||
{ | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
// make sure it's not already there | |||
if (! midiDevices.contains(theDevice)) | |||
midiDevices.add (theDevice); | |||
MidiDeviceInfo info = theDevice.getInfo(); | |||
int deviceID = info.getId(); | |||
if (! openTasks.containsKey (deviceID)) | |||
{ | |||
if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH) | |||
{ | |||
BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); | |||
if (btDevice != null) | |||
{ | |||
String btAddress = btDevice.getAddress(); | |||
if (btDevicesPairing.contains (btAddress)) | |||
{ | |||
btDevicesPairing.remove (btAddress); | |||
} | |||
else | |||
{ | |||
// unpair was called in the mean time | |||
try | |||
{ | |||
theDevice.close(); | |||
} | |||
catch (IOException e) | |||
{} | |||
return; | |||
} | |||
} | |||
} | |||
MidiDeviceOpenTask openTask = new MidiDeviceOpenTask (this, theDevice); | |||
openTasks.put (deviceID, openTask); | |||
new java.util.Timer().schedule (openTask, 3000); | |||
} | |||
} | |||
} | |||
public void onDeviceOpenedDelayed (MidiDevice theDevice) | |||
{ | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
int deviceID = theDevice.getInfo().getId(); | |||
if (openTasks.containsKey (deviceID)) | |||
{ | |||
if (! midiDevices.contains(theDevice)) | |||
{ | |||
openTasks.remove (deviceID); | |||
midiDevices.add (theDevice); | |||
} | |||
} | |||
else | |||
{ | |||
// unpair was called in the mean time | |||
try | |||
{ | |||
theDevice.close(); | |||
} | |||
catch (IOException e) | |||
{} | |||
} | |||
} | |||
} | |||
@@ -808,6 +1003,8 @@ public class MidiTest extends Activity | |||
} | |||
private MidiManager manager; | |||
private HashSet<String> btDevicesPairing; | |||
private HashMap<Integer, MidiDeviceOpenTask> openTasks; | |||
private ArrayList<MidiDevice> midiDevices; | |||
private MidiDeviceInfo[] deviceInfos; | |||
private HashMap<MidiPortPath, WeakReference<JuceMidiPort>> openPorts; | |||
@@ -179,9 +179,9 @@ public class JUCENetworkGraphicsDemo extends Activity | |||
return address; | |||
} | |||
public boolean isBluetoothDevicePaired (String address) | |||
public int getBluetoothDeviceStatus (String address) | |||
{ | |||
return false; | |||
return 0; | |||
} | |||
public void startStopScan (boolean shouldStart) | |||
@@ -179,9 +179,9 @@ public class OSCReceiver extends Activity | |||
return address; | |||
} | |||
public boolean isBluetoothDevicePaired (String address) | |||
public int getBluetoothDeviceStatus (String address) | |||
{ | |||
return false; | |||
return 0; | |||
} | |||
public void startStopScan (boolean shouldStart) | |||
@@ -179,9 +179,9 @@ public class OSCSender extends Activity | |||
return address; | |||
} | |||
public boolean isBluetoothDevicePaired (String address) | |||
public int getBluetoothDeviceStatus (String address) | |||
{ | |||
return false; | |||
return 0; | |||
} | |||
public void startStopScan (boolean shouldStart) | |||
@@ -194,9 +194,9 @@ public class JuceDemoPlugin extends Activity | |||
return btDevice.getName(); | |||
} | |||
public boolean isBluetoothDevicePaired (String address) | |||
public int getBluetoothDeviceStatus (String address) | |||
{ | |||
return getAndroidMidiDeviceManager().isBluetoothDevicePaired (address); | |||
return getAndroidMidiDeviceManager().getBluetoothDeviceStatus (address); | |||
} | |||
public void startStopScan (boolean shouldStart) | |||
@@ -487,7 +487,78 @@ public class JuceDemoPlugin extends Activity | |||
//============================================================================== | |||
public class MidiDeviceManager extends MidiManager.DeviceCallback implements MidiManager.OnDeviceOpenedListener | |||
{ | |||
//============================================================================== | |||
private class MidiDeviceOpenTask extends java.util.TimerTask | |||
{ | |||
public MidiDeviceOpenTask (MidiDeviceManager deviceManager, MidiDevice device) | |||
{ | |||
owner = deviceManager; | |||
midiDevice = device; | |||
} | |||
@Override | |||
public boolean cancel() | |||
{ | |||
synchronized (MidiDeviceOpenTask.class) | |||
{ | |||
owner = null; | |||
boolean retval = super.cancel(); | |||
if (midiDevice != null) | |||
{ | |||
try | |||
{ | |||
midiDevice.close(); | |||
} | |||
catch (IOException e) | |||
{} | |||
midiDevice = null; | |||
} | |||
return retval; | |||
} | |||
} | |||
public String getBluetoothAddress() | |||
{ | |||
synchronized (MidiDeviceOpenTask.class) | |||
{ | |||
if (midiDevice != null) | |||
{ | |||
MidiDeviceInfo info = midiDevice.getInfo(); | |||
if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH) | |||
{ | |||
BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); | |||
if (btDevice != null) | |||
return btDevice.getAddress(); | |||
} | |||
} | |||
} | |||
return ""; | |||
} | |||
public int getID() | |||
{ | |||
return midiDevice.getInfo().getId(); | |||
} | |||
@Override | |||
public void run() | |||
{ | |||
synchronized (MidiDeviceOpenTask.class) | |||
{ | |||
if (owner != null && midiDevice != null) | |||
owner.onDeviceOpenedDelayed (midiDevice); | |||
} | |||
} | |||
private MidiDeviceManager owner; | |||
private MidiDevice midiDevice; | |||
} | |||
//============================================================================== | |||
public MidiDeviceManager() | |||
{ | |||
manager = (MidiManager) getSystemService (MIDI_SERVICE); | |||
@@ -500,6 +571,8 @@ public class JuceDemoPlugin extends Activity | |||
openPorts = new HashMap<MidiPortPath, WeakReference<JuceMidiPort>> (); | |||
midiDevices = new ArrayList<MidiDevice>(); | |||
openTasks = new HashMap<Integer, MidiDeviceOpenTask>(); | |||
btDevicesPairing = new HashSet<String>(); | |||
MidiDeviceInfo[] foundDevices = manager.getDevices(); | |||
for (MidiDeviceInfo info : foundDevices) | |||
@@ -512,6 +585,16 @@ public class JuceDemoPlugin extends Activity | |||
{ | |||
manager.unregisterDeviceCallback (this); | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
btDevicesPairing.clear(); | |||
for (Integer deviceID : openTasks.keySet()) | |||
openTasks.get (deviceID).cancel(); | |||
openTasks = null; | |||
} | |||
for (MidiPortPath key : openPorts.keySet()) | |||
openPorts.get (key).get().close(); | |||
@@ -606,21 +689,62 @@ public class JuceDemoPlugin extends Activity | |||
return openMidiPortWithJuceIndex (index, 0, false); | |||
} | |||
public boolean isBluetoothDevicePaired (String address) | |||
/* 0: unpaired, 1: paired, 2: pairing */ | |||
public int getBluetoothDeviceStatus (String address) | |||
{ | |||
return (findMidiDeviceForBluetoothAddress (address) != null); | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
if (! address.isEmpty()) | |||
{ | |||
if (findMidiDeviceForBluetoothAddress (address) != null) | |||
return 1; | |||
if (btDevicesPairing.contains (address)) | |||
return 2; | |||
if (findOpenTaskForBluetoothAddress (address) != null) | |||
return 2; | |||
} | |||
} | |||
return 0; | |||
} | |||
public boolean pairBluetoothDevice (BluetoothDevice btDevice) | |||
{ | |||
manager.openBluetoothDevice(btDevice, this, null); | |||
String btAddress = btDevice.getAddress(); | |||
if (btAddress.isEmpty()) | |||
return false; | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
if (getBluetoothDeviceStatus (btAddress) != 0) | |||
return false; | |||
btDevicesPairing.add (btDevice.getAddress()); | |||
manager.openBluetoothDevice(btDevice, this, null); | |||
} | |||
return true; | |||
} | |||
public void unpairBluetoothDevice (String address) | |||
{ | |||
if (address.isEmpty()) | |||
return; | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
btDevicesPairing.remove (address); | |||
MidiDeviceOpenTask openTask = findOpenTaskForBluetoothAddress (address); | |||
if (openTask != null) | |||
{ | |||
int deviceID = openTask.getID(); | |||
openTask.cancel(); | |||
openTasks.remove (deviceID); | |||
} | |||
MidiDevice midiDevice = findMidiDeviceForBluetoothAddress (address); | |||
if (midiDevice != null) | |||
{ | |||
@@ -653,6 +777,18 @@ public class JuceDemoPlugin extends Activity | |||
return null; | |||
} | |||
private MidiDeviceOpenTask findOpenTaskForBluetoothAddress (String address) | |||
{ | |||
for (Integer deviceID : openTasks.keySet()) | |||
{ | |||
MidiDeviceOpenTask openTask = openTasks.get (deviceID); | |||
if (openTask.getBluetoothAddress().equals (address)) | |||
return openTask; | |||
} | |||
return null; | |||
} | |||
public void removePort (MidiPortPath path) | |||
{ | |||
openPorts.remove (path); | |||
@@ -719,9 +855,68 @@ public class JuceDemoPlugin extends Activity | |||
{ | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
// make sure it's not already there | |||
if (! midiDevices.contains(theDevice)) | |||
midiDevices.add (theDevice); | |||
MidiDeviceInfo info = theDevice.getInfo(); | |||
int deviceID = info.getId(); | |||
if (! openTasks.containsKey (deviceID)) | |||
{ | |||
if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH) | |||
{ | |||
BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); | |||
if (btDevice != null) | |||
{ | |||
String btAddress = btDevice.getAddress(); | |||
if (btDevicesPairing.contains (btAddress)) | |||
{ | |||
btDevicesPairing.remove (btAddress); | |||
} | |||
else | |||
{ | |||
// unpair was called in the mean time | |||
try | |||
{ | |||
theDevice.close(); | |||
} | |||
catch (IOException e) | |||
{} | |||
return; | |||
} | |||
} | |||
} | |||
MidiDeviceOpenTask openTask = new MidiDeviceOpenTask (this, theDevice); | |||
openTasks.put (deviceID, openTask); | |||
new java.util.Timer().schedule (openTask, 3000); | |||
} | |||
} | |||
} | |||
public void onDeviceOpenedDelayed (MidiDevice theDevice) | |||
{ | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
int deviceID = theDevice.getInfo().getId(); | |||
if (openTasks.containsKey (deviceID)) | |||
{ | |||
if (! midiDevices.contains(theDevice)) | |||
{ | |||
openTasks.remove (deviceID); | |||
midiDevices.add (theDevice); | |||
} | |||
} | |||
else | |||
{ | |||
// unpair was called in the mean time | |||
try | |||
{ | |||
theDevice.close(); | |||
} | |||
catch (IOException e) | |||
{} | |||
} | |||
} | |||
} | |||
@@ -808,6 +1003,8 @@ public class JuceDemoPlugin extends Activity | |||
} | |||
private MidiManager manager; | |||
private HashSet<String> btDevicesPairing; | |||
private HashMap<Integer, MidiDeviceOpenTask> openTasks; | |||
private ArrayList<MidiDevice> midiDevices; | |||
private MidiDeviceInfo[] deviceInfos; | |||
private HashMap<MidiPortPath, WeakReference<JuceMidiPort>> openPorts; | |||
@@ -194,9 +194,9 @@ public class AudioPerformanceTest extends Activity | |||
return btDevice.getName(); | |||
} | |||
public boolean isBluetoothDevicePaired (String address) | |||
public int getBluetoothDeviceStatus (String address) | |||
{ | |||
return getAndroidMidiDeviceManager().isBluetoothDevicePaired (address); | |||
return getAndroidMidiDeviceManager().getBluetoothDeviceStatus (address); | |||
} | |||
public void startStopScan (boolean shouldStart) | |||
@@ -487,7 +487,78 @@ public class AudioPerformanceTest extends Activity | |||
//============================================================================== | |||
public class MidiDeviceManager extends MidiManager.DeviceCallback implements MidiManager.OnDeviceOpenedListener | |||
{ | |||
//============================================================================== | |||
private class MidiDeviceOpenTask extends java.util.TimerTask | |||
{ | |||
public MidiDeviceOpenTask (MidiDeviceManager deviceManager, MidiDevice device) | |||
{ | |||
owner = deviceManager; | |||
midiDevice = device; | |||
} | |||
@Override | |||
public boolean cancel() | |||
{ | |||
synchronized (MidiDeviceOpenTask.class) | |||
{ | |||
owner = null; | |||
boolean retval = super.cancel(); | |||
if (midiDevice != null) | |||
{ | |||
try | |||
{ | |||
midiDevice.close(); | |||
} | |||
catch (IOException e) | |||
{} | |||
midiDevice = null; | |||
} | |||
return retval; | |||
} | |||
} | |||
public String getBluetoothAddress() | |||
{ | |||
synchronized (MidiDeviceOpenTask.class) | |||
{ | |||
if (midiDevice != null) | |||
{ | |||
MidiDeviceInfo info = midiDevice.getInfo(); | |||
if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH) | |||
{ | |||
BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); | |||
if (btDevice != null) | |||
return btDevice.getAddress(); | |||
} | |||
} | |||
} | |||
return ""; | |||
} | |||
public int getID() | |||
{ | |||
return midiDevice.getInfo().getId(); | |||
} | |||
@Override | |||
public void run() | |||
{ | |||
synchronized (MidiDeviceOpenTask.class) | |||
{ | |||
if (owner != null && midiDevice != null) | |||
owner.onDeviceOpenedDelayed (midiDevice); | |||
} | |||
} | |||
private MidiDeviceManager owner; | |||
private MidiDevice midiDevice; | |||
} | |||
//============================================================================== | |||
public MidiDeviceManager() | |||
{ | |||
manager = (MidiManager) getSystemService (MIDI_SERVICE); | |||
@@ -500,6 +571,8 @@ public class AudioPerformanceTest extends Activity | |||
openPorts = new HashMap<MidiPortPath, WeakReference<JuceMidiPort>> (); | |||
midiDevices = new ArrayList<MidiDevice>(); | |||
openTasks = new HashMap<Integer, MidiDeviceOpenTask>(); | |||
btDevicesPairing = new HashSet<String>(); | |||
MidiDeviceInfo[] foundDevices = manager.getDevices(); | |||
for (MidiDeviceInfo info : foundDevices) | |||
@@ -512,6 +585,16 @@ public class AudioPerformanceTest extends Activity | |||
{ | |||
manager.unregisterDeviceCallback (this); | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
btDevicesPairing.clear(); | |||
for (Integer deviceID : openTasks.keySet()) | |||
openTasks.get (deviceID).cancel(); | |||
openTasks = null; | |||
} | |||
for (MidiPortPath key : openPorts.keySet()) | |||
openPorts.get (key).get().close(); | |||
@@ -606,21 +689,62 @@ public class AudioPerformanceTest extends Activity | |||
return openMidiPortWithJuceIndex (index, 0, false); | |||
} | |||
public boolean isBluetoothDevicePaired (String address) | |||
/* 0: unpaired, 1: paired, 2: pairing */ | |||
public int getBluetoothDeviceStatus (String address) | |||
{ | |||
return (findMidiDeviceForBluetoothAddress (address) != null); | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
if (! address.isEmpty()) | |||
{ | |||
if (findMidiDeviceForBluetoothAddress (address) != null) | |||
return 1; | |||
if (btDevicesPairing.contains (address)) | |||
return 2; | |||
if (findOpenTaskForBluetoothAddress (address) != null) | |||
return 2; | |||
} | |||
} | |||
return 0; | |||
} | |||
public boolean pairBluetoothDevice (BluetoothDevice btDevice) | |||
{ | |||
manager.openBluetoothDevice(btDevice, this, null); | |||
String btAddress = btDevice.getAddress(); | |||
if (btAddress.isEmpty()) | |||
return false; | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
if (getBluetoothDeviceStatus (btAddress) != 0) | |||
return false; | |||
btDevicesPairing.add (btDevice.getAddress()); | |||
manager.openBluetoothDevice(btDevice, this, null); | |||
} | |||
return true; | |||
} | |||
public void unpairBluetoothDevice (String address) | |||
{ | |||
if (address.isEmpty()) | |||
return; | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
btDevicesPairing.remove (address); | |||
MidiDeviceOpenTask openTask = findOpenTaskForBluetoothAddress (address); | |||
if (openTask != null) | |||
{ | |||
int deviceID = openTask.getID(); | |||
openTask.cancel(); | |||
openTasks.remove (deviceID); | |||
} | |||
MidiDevice midiDevice = findMidiDeviceForBluetoothAddress (address); | |||
if (midiDevice != null) | |||
{ | |||
@@ -653,6 +777,18 @@ public class AudioPerformanceTest extends Activity | |||
return null; | |||
} | |||
private MidiDeviceOpenTask findOpenTaskForBluetoothAddress (String address) | |||
{ | |||
for (Integer deviceID : openTasks.keySet()) | |||
{ | |||
MidiDeviceOpenTask openTask = openTasks.get (deviceID); | |||
if (openTask.getBluetoothAddress().equals (address)) | |||
return openTask; | |||
} | |||
return null; | |||
} | |||
public void removePort (MidiPortPath path) | |||
{ | |||
openPorts.remove (path); | |||
@@ -719,9 +855,68 @@ public class AudioPerformanceTest extends Activity | |||
{ | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
// make sure it's not already there | |||
if (! midiDevices.contains(theDevice)) | |||
midiDevices.add (theDevice); | |||
MidiDeviceInfo info = theDevice.getInfo(); | |||
int deviceID = info.getId(); | |||
if (! openTasks.containsKey (deviceID)) | |||
{ | |||
if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH) | |||
{ | |||
BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); | |||
if (btDevice != null) | |||
{ | |||
String btAddress = btDevice.getAddress(); | |||
if (btDevicesPairing.contains (btAddress)) | |||
{ | |||
btDevicesPairing.remove (btAddress); | |||
} | |||
else | |||
{ | |||
// unpair was called in the mean time | |||
try | |||
{ | |||
theDevice.close(); | |||
} | |||
catch (IOException e) | |||
{} | |||
return; | |||
} | |||
} | |||
} | |||
MidiDeviceOpenTask openTask = new MidiDeviceOpenTask (this, theDevice); | |||
openTasks.put (deviceID, openTask); | |||
new java.util.Timer().schedule (openTask, 3000); | |||
} | |||
} | |||
} | |||
public void onDeviceOpenedDelayed (MidiDevice theDevice) | |||
{ | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
int deviceID = theDevice.getInfo().getId(); | |||
if (openTasks.containsKey (deviceID)) | |||
{ | |||
if (! midiDevices.contains(theDevice)) | |||
{ | |||
openTasks.remove (deviceID); | |||
midiDevices.add (theDevice); | |||
} | |||
} | |||
else | |||
{ | |||
// unpair was called in the mean time | |||
try | |||
{ | |||
theDevice.close(); | |||
} | |||
catch (IOException e) | |||
{} | |||
} | |||
} | |||
} | |||
@@ -808,6 +1003,8 @@ public class AudioPerformanceTest extends Activity | |||
} | |||
private MidiManager manager; | |||
private HashSet<String> btDevicesPairing; | |||
private HashMap<Integer, MidiDeviceOpenTask> openTasks; | |||
private ArrayList<MidiDevice> midiDevices; | |||
private MidiDeviceInfo[] deviceInfos; | |||
private HashMap<MidiPortPath, WeakReference<JuceMidiPort>> openPorts; | |||
@@ -28,7 +28,7 @@ | |||
METHOD (pairBluetoothMidiDevice, "pairBluetoothMidiDevice", "(Ljava/lang/String;)Z") \ | |||
METHOD (unpairBluetoothMidiDevice, "unpairBluetoothMidiDevice", "(Ljava/lang/String;)V") \ | |||
METHOD (getHumanReadableStringForBluetoothAddress, "getHumanReadableStringForBluetoothAddress", "(Ljava/lang/String;)Ljava/lang/String;") \ | |||
METHOD (isBluetoothDevicePaired, "isBluetoothDevicePaired", "(Ljava/lang/String;)Z") \ | |||
METHOD (getBluetoothDeviceStatus, "getBluetoothDeviceStatus", "(Ljava/lang/String;)I") \ | |||
METHOD (startStopScan, "startStopScan", "(Z)V") | |||
DECLARE_JNI_CLASS (AndroidBluetoothManager, JUCE_ANDROID_ACTIVITY_CLASSPATH "$BluetoothManager"); | |||
@@ -121,17 +121,24 @@ struct AndroidBluetoothMidiInterface | |||
} | |||
//============================================================================== | |||
static bool isBluetoothDevicePaired (const String& address) | |||
enum PairStatus | |||
{ | |||
unpaired = 0, | |||
paired = 1, | |||
pairing = 2 | |||
}; | |||
static PairStatus isBluetoothDevicePaired (const String& address) | |||
{ | |||
JNIEnv* env = getEnv(); | |||
LocalRef<jobject> btManager (android.activity.callObjectMethod (JuceAppActivity.getAndroidBluetoothManager)); | |||
if (btManager.get() == nullptr) | |||
return false; | |||
return unpaired; | |||
return env->CallBooleanMethod (btManager.get(), AndroidBluetoothManager.isBluetoothDevicePaired, | |||
javaString (address).get()); | |||
return static_cast<PairStatus> (env->CallIntMethod (btManager.get(), AndroidBluetoothManager.getBluetoothDeviceStatus, | |||
javaString (address).get())); | |||
} | |||
}; | |||
@@ -350,9 +357,19 @@ private: | |||
address != bluetoothAddresses.end(); ++address) | |||
{ | |||
String name = AndroidBluetoothMidiInterface::getHumanReadableStringForBluetoothAddress (*address); | |||
DeviceStatus status = AndroidBluetoothMidiInterface::isBluetoothDevicePaired (*address) | |||
? AndroidBluetoothMidiDevice::connected | |||
: AndroidBluetoothMidiDevice::disconnected; | |||
DeviceStatus status; | |||
switch (AndroidBluetoothMidiInterface::isBluetoothDevicePaired (*address)) | |||
{ | |||
case AndroidBluetoothMidiInterface::pairing: | |||
status = AndroidBluetoothMidiDevice::connecting; | |||
break; | |||
case AndroidBluetoothMidiInterface::paired: | |||
status = AndroidBluetoothMidiDevice::connected; | |||
break; | |||
default: | |||
status = AndroidBluetoothMidiDevice::disconnected; | |||
} | |||
newDevices.add (AndroidBluetoothMidiDevice (name, *address, status)); | |||
} | |||
@@ -16,9 +16,9 @@ | |||
return btDevice.getName(); | |||
} | |||
public boolean isBluetoothDevicePaired (String address) | |||
public int getBluetoothDeviceStatus (String address) | |||
{ | |||
return getAndroidMidiDeviceManager().isBluetoothDevicePaired (address); | |||
return getAndroidMidiDeviceManager().getBluetoothDeviceStatus (address); | |||
} | |||
public void startStopScan (boolean shouldStart) | |||
@@ -309,7 +309,78 @@ | |||
//============================================================================== | |||
public class MidiDeviceManager extends MidiManager.DeviceCallback implements MidiManager.OnDeviceOpenedListener | |||
{ | |||
//============================================================================== | |||
private class MidiDeviceOpenTask extends java.util.TimerTask | |||
{ | |||
public MidiDeviceOpenTask (MidiDeviceManager deviceManager, MidiDevice device) | |||
{ | |||
owner = deviceManager; | |||
midiDevice = device; | |||
} | |||
@Override | |||
public boolean cancel() | |||
{ | |||
synchronized (MidiDeviceOpenTask.class) | |||
{ | |||
owner = null; | |||
boolean retval = super.cancel(); | |||
if (midiDevice != null) | |||
{ | |||
try | |||
{ | |||
midiDevice.close(); | |||
} | |||
catch (IOException e) | |||
{} | |||
midiDevice = null; | |||
} | |||
return retval; | |||
} | |||
} | |||
public String getBluetoothAddress() | |||
{ | |||
synchronized (MidiDeviceOpenTask.class) | |||
{ | |||
if (midiDevice != null) | |||
{ | |||
MidiDeviceInfo info = midiDevice.getInfo(); | |||
if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH) | |||
{ | |||
BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); | |||
if (btDevice != null) | |||
return btDevice.getAddress(); | |||
} | |||
} | |||
} | |||
return ""; | |||
} | |||
public int getID() | |||
{ | |||
return midiDevice.getInfo().getId(); | |||
} | |||
@Override | |||
public void run() | |||
{ | |||
synchronized (MidiDeviceOpenTask.class) | |||
{ | |||
if (owner != null && midiDevice != null) | |||
owner.onDeviceOpenedDelayed (midiDevice); | |||
} | |||
} | |||
private MidiDeviceManager owner; | |||
private MidiDevice midiDevice; | |||
} | |||
//============================================================================== | |||
public MidiDeviceManager() | |||
{ | |||
manager = (MidiManager) getSystemService (MIDI_SERVICE); | |||
@@ -322,6 +393,8 @@ | |||
openPorts = new HashMap<MidiPortPath, WeakReference<JuceMidiPort>> (); | |||
midiDevices = new ArrayList<MidiDevice>(); | |||
openTasks = new HashMap<Integer, MidiDeviceOpenTask>(); | |||
btDevicesPairing = new HashSet<String>(); | |||
MidiDeviceInfo[] foundDevices = manager.getDevices(); | |||
for (MidiDeviceInfo info : foundDevices) | |||
@@ -334,6 +407,16 @@ | |||
{ | |||
manager.unregisterDeviceCallback (this); | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
btDevicesPairing.clear(); | |||
for (Integer deviceID : openTasks.keySet()) | |||
openTasks.get (deviceID).cancel(); | |||
openTasks = null; | |||
} | |||
for (MidiPortPath key : openPorts.keySet()) | |||
openPorts.get (key).get().close(); | |||
@@ -428,21 +511,62 @@ | |||
return openMidiPortWithJuceIndex (index, 0, false); | |||
} | |||
public boolean isBluetoothDevicePaired (String address) | |||
/* 0: unpaired, 1: paired, 2: pairing */ | |||
public int getBluetoothDeviceStatus (String address) | |||
{ | |||
return (findMidiDeviceForBluetoothAddress (address) != null); | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
if (! address.isEmpty()) | |||
{ | |||
if (findMidiDeviceForBluetoothAddress (address) != null) | |||
return 1; | |||
if (btDevicesPairing.contains (address)) | |||
return 2; | |||
if (findOpenTaskForBluetoothAddress (address) != null) | |||
return 2; | |||
} | |||
} | |||
return 0; | |||
} | |||
public boolean pairBluetoothDevice (BluetoothDevice btDevice) | |||
{ | |||
manager.openBluetoothDevice(btDevice, this, null); | |||
String btAddress = btDevice.getAddress(); | |||
if (btAddress.isEmpty()) | |||
return false; | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
if (getBluetoothDeviceStatus (btAddress) != 0) | |||
return false; | |||
btDevicesPairing.add (btDevice.getAddress()); | |||
manager.openBluetoothDevice(btDevice, this, null); | |||
} | |||
return true; | |||
} | |||
public void unpairBluetoothDevice (String address) | |||
{ | |||
if (address.isEmpty()) | |||
return; | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
btDevicesPairing.remove (address); | |||
MidiDeviceOpenTask openTask = findOpenTaskForBluetoothAddress (address); | |||
if (openTask != null) | |||
{ | |||
int deviceID = openTask.getID(); | |||
openTask.cancel(); | |||
openTasks.remove (deviceID); | |||
} | |||
MidiDevice midiDevice = findMidiDeviceForBluetoothAddress (address); | |||
if (midiDevice != null) | |||
{ | |||
@@ -475,6 +599,18 @@ | |||
return null; | |||
} | |||
private MidiDeviceOpenTask findOpenTaskForBluetoothAddress (String address) | |||
{ | |||
for (Integer deviceID : openTasks.keySet()) | |||
{ | |||
MidiDeviceOpenTask openTask = openTasks.get (deviceID); | |||
if (openTask.getBluetoothAddress().equals (address)) | |||
return openTask; | |||
} | |||
return null; | |||
} | |||
public void removePort (MidiPortPath path) | |||
{ | |||
openPorts.remove (path); | |||
@@ -541,9 +677,68 @@ | |||
{ | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
// make sure it's not already there | |||
if (! midiDevices.contains(theDevice)) | |||
midiDevices.add (theDevice); | |||
MidiDeviceInfo info = theDevice.getInfo(); | |||
int deviceID = info.getId(); | |||
if (! openTasks.containsKey (deviceID)) | |||
{ | |||
if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH) | |||
{ | |||
BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); | |||
if (btDevice != null) | |||
{ | |||
String btAddress = btDevice.getAddress(); | |||
if (btDevicesPairing.contains (btAddress)) | |||
{ | |||
btDevicesPairing.remove (btAddress); | |||
} | |||
else | |||
{ | |||
// unpair was called in the mean time | |||
try | |||
{ | |||
theDevice.close(); | |||
} | |||
catch (IOException e) | |||
{} | |||
return; | |||
} | |||
} | |||
} | |||
MidiDeviceOpenTask openTask = new MidiDeviceOpenTask (this, theDevice); | |||
openTasks.put (deviceID, openTask); | |||
new java.util.Timer().schedule (openTask, 3000); | |||
} | |||
} | |||
} | |||
public void onDeviceOpenedDelayed (MidiDevice theDevice) | |||
{ | |||
synchronized (MidiDeviceManager.class) | |||
{ | |||
int deviceID = theDevice.getInfo().getId(); | |||
if (openTasks.containsKey (deviceID)) | |||
{ | |||
if (! midiDevices.contains(theDevice)) | |||
{ | |||
openTasks.remove (deviceID); | |||
midiDevices.add (theDevice); | |||
} | |||
} | |||
else | |||
{ | |||
// unpair was called in the mean time | |||
try | |||
{ | |||
theDevice.close(); | |||
} | |||
catch (IOException e) | |||
{} | |||
} | |||
} | |||
} | |||
@@ -630,6 +825,8 @@ | |||
} | |||
private MidiManager manager; | |||
private HashSet<String> btDevicesPairing; | |||
private HashMap<Integer, MidiDeviceOpenTask> openTasks; | |||
private ArrayList<MidiDevice> midiDevices; | |||
private MidiDeviceInfo[] deviceInfos; | |||
private HashMap<MidiPortPath, WeakReference<JuceMidiPort>> openPorts; | |||
@@ -16,9 +16,9 @@ | |||
return address; | |||
} | |||
public boolean isBluetoothDevicePaired (String address) | |||
public int getBluetoothDeviceStatus (String address) | |||
{ | |||
return false; | |||
return 0; | |||
} | |||
public void startStopScan (boolean shouldStart) | |||