| @@ -54,6 +54,7 @@ import android.text.ClipboardManager; | |||||
| import android.text.InputType; | import android.text.InputType; | ||||
| import android.util.DisplayMetrics; | import android.util.DisplayMetrics; | ||||
| import android.util.Log; | import android.util.Log; | ||||
| import android.util.Pair; | |||||
| import java.lang.Runnable; | import java.lang.Runnable; | ||||
| import java.lang.ref.WeakReference; | import java.lang.ref.WeakReference; | ||||
| import java.lang.reflect.*; | import java.lang.reflect.*; | ||||
| @@ -487,13 +488,34 @@ public class MidiTest extends Activity | |||||
| //============================================================================== | //============================================================================== | ||||
| public class MidiDeviceManager extends MidiManager.DeviceCallback implements MidiManager.OnDeviceOpenedListener | public class MidiDeviceManager extends MidiManager.DeviceCallback implements MidiManager.OnDeviceOpenedListener | ||||
| { | { | ||||
| //============================================================================== | |||||
| private class DummyBluetoothGattCallback extends BluetoothGattCallback | |||||
| { | |||||
| public DummyBluetoothGattCallback() | |||||
| { | |||||
| super(); | |||||
| } | |||||
| public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {} | |||||
| public void onServicesDiscovered(BluetoothGatt gatt, int status) {} | |||||
| public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {} | |||||
| public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {} | |||||
| public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {} | |||||
| public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {} | |||||
| public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {} | |||||
| public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {} | |||||
| public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {} | |||||
| public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {} | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| private class MidiDeviceOpenTask extends java.util.TimerTask | private class MidiDeviceOpenTask extends java.util.TimerTask | ||||
| { | { | ||||
| public MidiDeviceOpenTask (MidiDeviceManager deviceManager, MidiDevice device) | |||||
| public MidiDeviceOpenTask (MidiDeviceManager deviceManager, MidiDevice device, BluetoothGatt gattToUse) | |||||
| { | { | ||||
| owner = deviceManager; | owner = deviceManager; | ||||
| midiDevice = device; | midiDevice = device; | ||||
| btGatt = gattToUse; | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -504,6 +526,14 @@ public class MidiTest extends Activity | |||||
| owner = null; | owner = null; | ||||
| boolean retval = super.cancel(); | boolean retval = super.cancel(); | ||||
| if (btGatt != null) | |||||
| { | |||||
| btGatt.disconnect(); | |||||
| btGatt.close(); | |||||
| btGatt = null; | |||||
| } | |||||
| if (midiDevice != null) | if (midiDevice != null) | ||||
| { | { | ||||
| try | try | ||||
| @@ -539,6 +569,8 @@ public class MidiTest extends Activity | |||||
| return ""; | return ""; | ||||
| } | } | ||||
| public BluetoothGatt getGatt() { return btGatt; } | |||||
| public int getID() | public int getID() | ||||
| { | { | ||||
| return midiDevice.getInfo().getId(); | return midiDevice.getInfo().getId(); | ||||
| @@ -556,6 +588,7 @@ public class MidiTest extends Activity | |||||
| private MidiDeviceManager owner; | private MidiDeviceManager owner; | ||||
| private MidiDevice midiDevice; | private MidiDevice midiDevice; | ||||
| private BluetoothGatt btGatt; | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -570,9 +603,9 @@ public class MidiTest extends Activity | |||||
| } | } | ||||
| openPorts = new HashMap<MidiPortPath, WeakReference<JuceMidiPort>> (); | openPorts = new HashMap<MidiPortPath, WeakReference<JuceMidiPort>> (); | ||||
| midiDevices = new ArrayList<MidiDevice>(); | |||||
| midiDevices = new ArrayList<Pair<MidiDevice,BluetoothGatt>>(); | |||||
| openTasks = new HashMap<Integer, MidiDeviceOpenTask>(); | openTasks = new HashMap<Integer, MidiDeviceOpenTask>(); | ||||
| btDevicesPairing = new HashSet<String>(); | |||||
| btDevicesPairing = new HashMap<String, BluetoothGatt>(); | |||||
| MidiDeviceInfo[] foundDevices = manager.getDevices(); | MidiDeviceInfo[] foundDevices = manager.getDevices(); | ||||
| for (MidiDeviceInfo info : foundDevices) | for (MidiDeviceInfo info : foundDevices) | ||||
| @@ -600,8 +633,18 @@ public class MidiTest extends Activity | |||||
| openPorts = null; | openPorts = null; | ||||
| for (MidiDevice device : midiDevices) | |||||
| device.close(); | |||||
| for (Pair<MidiDevice, BluetoothGatt> device : midiDevices) | |||||
| { | |||||
| if (device.second != null) | |||||
| { | |||||
| device.second.disconnect(); | |||||
| device.second.close(); | |||||
| } | |||||
| device.first.close(); | |||||
| } | |||||
| midiDevices.clear(); | |||||
| super.finalize(); | super.finalize(); | ||||
| } | } | ||||
| @@ -647,30 +690,36 @@ public class MidiTest extends Activity | |||||
| if (openPorts.containsKey (portInfo)) | if (openPorts.containsKey (portInfo)) | ||||
| return null; | return null; | ||||
| MidiDevice device = getMidiDeviceForId (portInfo.deviceId); | |||||
| if (device != null) | |||||
| { | |||||
| JuceMidiPort juceMidiPort = null; | |||||
| Pair<MidiDevice,BluetoothGatt> devicePair = getMidiDevicePairForId (portInfo.deviceId); | |||||
| if (isInput) | |||||
| if (devicePair != null) | |||||
| { | |||||
| MidiDevice device = devicePair.first; | |||||
| if (device != null) | |||||
| { | { | ||||
| MidiOutputPort outputPort = device.openOutputPort (portInfo.portIndex); | |||||
| JuceMidiPort juceMidiPort = null; | |||||
| if (outputPort != null) | |||||
| juceMidiPort = new JuceMidiInputPort(this, outputPort, portInfo, host); | |||||
| } | |||||
| else | |||||
| { | |||||
| MidiInputPort inputPort = device.openInputPort (portInfo.portIndex); | |||||
| if (isInput) | |||||
| { | |||||
| MidiOutputPort outputPort = device.openOutputPort(portInfo.portIndex); | |||||
| if (inputPort != null) | |||||
| juceMidiPort = new JuceMidiOutputPort(this, inputPort, portInfo); | |||||
| } | |||||
| if (outputPort != null) | |||||
| juceMidiPort = new JuceMidiInputPort(this, outputPort, portInfo, host); | |||||
| } | |||||
| else | |||||
| { | |||||
| MidiInputPort inputPort = device.openInputPort(portInfo.portIndex); | |||||
| if (juceMidiPort != null) { | |||||
| openPorts.put(portInfo, new WeakReference<JuceMidiPort>(juceMidiPort)); | |||||
| if (inputPort != null) | |||||
| juceMidiPort = new JuceMidiOutputPort(this, inputPort, portInfo); | |||||
| } | |||||
| return juceMidiPort; | |||||
| if (juceMidiPort != null) | |||||
| { | |||||
| openPorts.put(portInfo, new WeakReference<JuceMidiPort>(juceMidiPort)); | |||||
| return juceMidiPort; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -699,7 +748,7 @@ public class MidiTest extends Activity | |||||
| if (findMidiDeviceForBluetoothAddress (address) != null) | if (findMidiDeviceForBluetoothAddress (address) != null) | ||||
| return 1; | return 1; | ||||
| if (btDevicesPairing.contains (address)) | |||||
| if (btDevicesPairing.containsKey (address)) | |||||
| return 2; | return 2; | ||||
| if (findOpenTaskForBluetoothAddress (address) != null) | if (findOpenTaskForBluetoothAddress (address) != null) | ||||
| @@ -721,7 +770,11 @@ public class MidiTest extends Activity | |||||
| if (getBluetoothDeviceStatus (btAddress) != 0) | if (getBluetoothDeviceStatus (btAddress) != 0) | ||||
| return false; | return false; | ||||
| btDevicesPairing.add (btDevice.getAddress()); | |||||
| BluetoothGatt gatt = btDevice.connectGatt (getApplicationContext(), true, new DummyBluetoothGattCallback()); | |||||
| if (gatt != null) | |||||
| gatt.requestConnectionPriority (BluetoothGatt.CONNECTION_PRIORITY_HIGH); | |||||
| btDevicesPairing.put (btDevice.getAddress(), gatt); | |||||
| manager.openBluetoothDevice(btDevice, this, null); | manager.openBluetoothDevice(btDevice, this, null); | ||||
| } | } | ||||
| @@ -735,7 +788,17 @@ public class MidiTest extends Activity | |||||
| synchronized (MidiDeviceManager.class) | synchronized (MidiDeviceManager.class) | ||||
| { | { | ||||
| btDevicesPairing.remove (address); | |||||
| if (btDevicesPairing.containsKey (address)) | |||||
| { | |||||
| BluetoothGatt gatt = btDevicesPairing.get (address); | |||||
| if (gatt != null) | |||||
| { | |||||
| gatt.disconnect(); | |||||
| gatt.close(); | |||||
| } | |||||
| btDevicesPairing.remove (address); | |||||
| } | |||||
| MidiDeviceOpenTask openTask = findOpenTaskForBluetoothAddress (address); | MidiDeviceOpenTask openTask = findOpenTaskForBluetoothAddress (address); | ||||
| if (openTask != null) | if (openTask != null) | ||||
| @@ -745,9 +808,10 @@ public class MidiTest extends Activity | |||||
| openTasks.remove (deviceID); | openTasks.remove (deviceID); | ||||
| } | } | ||||
| MidiDevice midiDevice = findMidiDeviceForBluetoothAddress (address); | |||||
| if (midiDevice != null) | |||||
| Pair<MidiDevice, BluetoothGatt> midiDevicePair = findMidiDeviceForBluetoothAddress (address); | |||||
| if (midiDevicePair != null) | |||||
| { | { | ||||
| MidiDevice midiDevice = midiDevicePair.first; | |||||
| onDeviceRemoved (midiDevice.getInfo()); | onDeviceRemoved (midiDevice.getInfo()); | ||||
| try { | try { | ||||
| @@ -761,11 +825,11 @@ public class MidiTest extends Activity | |||||
| } | } | ||||
| } | } | ||||
| private MidiDevice findMidiDeviceForBluetoothAddress (String address) | |||||
| private Pair<MidiDevice, BluetoothGatt> findMidiDeviceForBluetoothAddress (String address) | |||||
| { | { | ||||
| for (MidiDevice midiDevice : midiDevices) | |||||
| for (Pair<MidiDevice,BluetoothGatt> midiDevice : midiDevices) | |||||
| { | { | ||||
| MidiDeviceInfo info = midiDevice.getInfo(); | |||||
| MidiDeviceInfo info = midiDevice.first.getInfo(); | |||||
| if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH) | if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH) | ||||
| { | { | ||||
| BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); | BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); | ||||
| @@ -825,24 +889,38 @@ public class MidiTest extends Activity | |||||
| { | { | ||||
| synchronized (MidiDeviceManager.class) | synchronized (MidiDeviceManager.class) | ||||
| { | { | ||||
| MidiDevice device = getMidiDeviceForId (info.getId()); | |||||
| // close all ports that use this device | |||||
| boolean removedPort = true; | |||||
| while (removedPort == true) { | |||||
| removedPort = false; | |||||
| for (MidiPortPath key : openPorts.keySet()) { | |||||
| if (key.deviceId == info.getId()) { | |||||
| openPorts.get(key).get().close(); | |||||
| removedPort = true; | |||||
| break; | |||||
| Pair<MidiDevice, BluetoothGatt> devicePair = getMidiDevicePairForId (info.getId()); | |||||
| if (devicePair != null) | |||||
| { | |||||
| MidiDevice midiDevice = devicePair.first; | |||||
| BluetoothGatt gatt = devicePair.second; | |||||
| // close all ports that use this device | |||||
| boolean removedPort = true; | |||||
| while (removedPort == true) | |||||
| { | |||||
| removedPort = false; | |||||
| for (MidiPortPath key : openPorts.keySet()) | |||||
| { | |||||
| if (key.deviceId == info.getId()) | |||||
| { | |||||
| openPorts.get(key).get().close(); | |||||
| removedPort = true; | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | |||||
| if (device != null) | |||||
| midiDevices.remove (device); | |||||
| if (gatt != null) | |||||
| { | |||||
| gatt.disconnect(); | |||||
| gatt.close(); | |||||
| } | |||||
| midiDevices.remove (devicePair); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -857,6 +935,7 @@ public class MidiTest extends Activity | |||||
| { | { | ||||
| MidiDeviceInfo info = theDevice.getInfo(); | MidiDeviceInfo info = theDevice.getInfo(); | ||||
| int deviceID = info.getId(); | int deviceID = info.getId(); | ||||
| BluetoothGatt gatt = null; | |||||
| if (! openTasks.containsKey (deviceID)) | if (! openTasks.containsKey (deviceID)) | ||||
| { | { | ||||
| @@ -866,8 +945,9 @@ public class MidiTest extends Activity | |||||
| if (btDevice != null) | if (btDevice != null) | ||||
| { | { | ||||
| String btAddress = btDevice.getAddress(); | String btAddress = btDevice.getAddress(); | ||||
| if (btDevicesPairing.contains (btAddress)) | |||||
| if (btDevicesPairing.containsKey (btAddress)) | |||||
| { | { | ||||
| gatt = btDevicesPairing.get (btAddress); | |||||
| btDevicesPairing.remove (btAddress); | btDevicesPairing.remove (btAddress); | ||||
| } | } | ||||
| else | else | ||||
| @@ -875,6 +955,18 @@ public class MidiTest extends Activity | |||||
| // unpair was called in the mean time | // unpair was called in the mean time | ||||
| try | try | ||||
| { | { | ||||
| Pair<MidiDevice, BluetoothGatt> midiDevicePair = findMidiDeviceForBluetoothAddress (btDevice.getAddress()); | |||||
| if (midiDevicePair != null) | |||||
| { | |||||
| gatt = midiDevicePair.second; | |||||
| if (gatt != null) | |||||
| { | |||||
| gatt.disconnect(); | |||||
| gatt.close(); | |||||
| } | |||||
| } | |||||
| theDevice.close(); | theDevice.close(); | ||||
| } | } | ||||
| catch (IOException e) | catch (IOException e) | ||||
| @@ -885,7 +977,7 @@ public class MidiTest extends Activity | |||||
| } | } | ||||
| } | } | ||||
| MidiDeviceOpenTask openTask = new MidiDeviceOpenTask (this, theDevice); | |||||
| MidiDeviceOpenTask openTask = new MidiDeviceOpenTask (this, theDevice, gatt); | |||||
| openTasks.put (deviceID, openTask); | openTasks.put (deviceID, openTask); | ||||
| new java.util.Timer().schedule (openTask, 3000); | new java.util.Timer().schedule (openTask, 3000); | ||||
| @@ -903,13 +995,32 @@ public class MidiTest extends Activity | |||||
| { | { | ||||
| if (! midiDevices.contains(theDevice)) | if (! midiDevices.contains(theDevice)) | ||||
| { | { | ||||
| BluetoothGatt gatt = openTasks.get (deviceID).getGatt(); | |||||
| openTasks.remove (deviceID); | openTasks.remove (deviceID); | ||||
| midiDevices.add (theDevice); | |||||
| midiDevices.add (new Pair<MidiDevice,BluetoothGatt> (theDevice, gatt)); | |||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| // unpair was called in the mean time | // unpair was called in the mean time | ||||
| MidiDeviceInfo info = theDevice.getInfo(); | |||||
| BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); | |||||
| if (btDevice != null) | |||||
| { | |||||
| String btAddress = btDevice.getAddress(); | |||||
| Pair<MidiDevice, BluetoothGatt> midiDevicePair = findMidiDeviceForBluetoothAddress (btDevice.getAddress()); | |||||
| if (midiDevicePair != null) | |||||
| { | |||||
| BluetoothGatt gatt = midiDevicePair.second; | |||||
| if (gatt != null) | |||||
| { | |||||
| gatt.disconnect(); | |||||
| gatt.close(); | |||||
| } | |||||
| } | |||||
| } | |||||
| try | try | ||||
| { | { | ||||
| theDevice.close(); | theDevice.close(); | ||||
| @@ -983,19 +1094,19 @@ public class MidiTest extends Activity | |||||
| MidiDeviceInfo[] infos = new MidiDeviceInfo[midiDevices.size()]; | MidiDeviceInfo[] infos = new MidiDeviceInfo[midiDevices.size()]; | ||||
| int idx = 0; | int idx = 0; | ||||
| for (MidiDevice midiDevice : midiDevices) | |||||
| infos[idx++] = midiDevice.getInfo(); | |||||
| for (Pair<MidiDevice,BluetoothGatt> midiDevice : midiDevices) | |||||
| infos[idx++] = midiDevice.first.getInfo(); | |||||
| return infos; | return infos; | ||||
| } | } | ||||
| } | } | ||||
| private MidiDevice getMidiDeviceForId (int deviceId) | |||||
| private Pair<MidiDevice, BluetoothGatt> getMidiDevicePairForId (int deviceId) | |||||
| { | { | ||||
| synchronized (MidiDeviceManager.class) | synchronized (MidiDeviceManager.class) | ||||
| { | { | ||||
| for (MidiDevice midiDevice : midiDevices) | |||||
| if (midiDevice.getInfo().getId() == deviceId) | |||||
| for (Pair<MidiDevice,BluetoothGatt> midiDevice : midiDevices) | |||||
| if (midiDevice.first.getInfo().getId() == deviceId) | |||||
| return midiDevice; | return midiDevice; | ||||
| } | } | ||||
| @@ -1003,9 +1114,9 @@ public class MidiTest extends Activity | |||||
| } | } | ||||
| private MidiManager manager; | private MidiManager manager; | ||||
| private HashSet<String> btDevicesPairing; | |||||
| private HashMap<String, BluetoothGatt> btDevicesPairing; | |||||
| private HashMap<Integer, MidiDeviceOpenTask> openTasks; | private HashMap<Integer, MidiDeviceOpenTask> openTasks; | ||||
| private ArrayList<MidiDevice> midiDevices; | |||||
| private ArrayList<Pair<MidiDevice, BluetoothGatt>> midiDevices; | |||||
| private MidiDeviceInfo[] deviceInfos; | private MidiDeviceInfo[] deviceInfos; | ||||
| private HashMap<MidiPortPath, WeakReference<JuceMidiPort>> openPorts; | private HashMap<MidiPortPath, WeakReference<JuceMidiPort>> openPorts; | ||||
| } | } | ||||
| @@ -54,6 +54,7 @@ import android.text.ClipboardManager; | |||||
| import android.text.InputType; | import android.text.InputType; | ||||
| import android.util.DisplayMetrics; | import android.util.DisplayMetrics; | ||||
| import android.util.Log; | import android.util.Log; | ||||
| import android.util.Pair; | |||||
| import java.lang.Runnable; | import java.lang.Runnable; | ||||
| import java.lang.ref.WeakReference; | import java.lang.ref.WeakReference; | ||||
| import java.lang.reflect.*; | import java.lang.reflect.*; | ||||
| @@ -487,13 +488,34 @@ public class JuceDemoPlugin extends Activity | |||||
| //============================================================================== | //============================================================================== | ||||
| public class MidiDeviceManager extends MidiManager.DeviceCallback implements MidiManager.OnDeviceOpenedListener | public class MidiDeviceManager extends MidiManager.DeviceCallback implements MidiManager.OnDeviceOpenedListener | ||||
| { | { | ||||
| //============================================================================== | |||||
| private class DummyBluetoothGattCallback extends BluetoothGattCallback | |||||
| { | |||||
| public DummyBluetoothGattCallback() | |||||
| { | |||||
| super(); | |||||
| } | |||||
| public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {} | |||||
| public void onServicesDiscovered(BluetoothGatt gatt, int status) {} | |||||
| public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {} | |||||
| public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {} | |||||
| public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {} | |||||
| public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {} | |||||
| public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {} | |||||
| public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {} | |||||
| public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {} | |||||
| public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {} | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| private class MidiDeviceOpenTask extends java.util.TimerTask | private class MidiDeviceOpenTask extends java.util.TimerTask | ||||
| { | { | ||||
| public MidiDeviceOpenTask (MidiDeviceManager deviceManager, MidiDevice device) | |||||
| public MidiDeviceOpenTask (MidiDeviceManager deviceManager, MidiDevice device, BluetoothGatt gattToUse) | |||||
| { | { | ||||
| owner = deviceManager; | owner = deviceManager; | ||||
| midiDevice = device; | midiDevice = device; | ||||
| btGatt = gattToUse; | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -504,6 +526,14 @@ public class JuceDemoPlugin extends Activity | |||||
| owner = null; | owner = null; | ||||
| boolean retval = super.cancel(); | boolean retval = super.cancel(); | ||||
| if (btGatt != null) | |||||
| { | |||||
| btGatt.disconnect(); | |||||
| btGatt.close(); | |||||
| btGatt = null; | |||||
| } | |||||
| if (midiDevice != null) | if (midiDevice != null) | ||||
| { | { | ||||
| try | try | ||||
| @@ -539,6 +569,8 @@ public class JuceDemoPlugin extends Activity | |||||
| return ""; | return ""; | ||||
| } | } | ||||
| public BluetoothGatt getGatt() { return btGatt; } | |||||
| public int getID() | public int getID() | ||||
| { | { | ||||
| return midiDevice.getInfo().getId(); | return midiDevice.getInfo().getId(); | ||||
| @@ -556,6 +588,7 @@ public class JuceDemoPlugin extends Activity | |||||
| private MidiDeviceManager owner; | private MidiDeviceManager owner; | ||||
| private MidiDevice midiDevice; | private MidiDevice midiDevice; | ||||
| private BluetoothGatt btGatt; | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -570,9 +603,9 @@ public class JuceDemoPlugin extends Activity | |||||
| } | } | ||||
| openPorts = new HashMap<MidiPortPath, WeakReference<JuceMidiPort>> (); | openPorts = new HashMap<MidiPortPath, WeakReference<JuceMidiPort>> (); | ||||
| midiDevices = new ArrayList<MidiDevice>(); | |||||
| midiDevices = new ArrayList<Pair<MidiDevice,BluetoothGatt>>(); | |||||
| openTasks = new HashMap<Integer, MidiDeviceOpenTask>(); | openTasks = new HashMap<Integer, MidiDeviceOpenTask>(); | ||||
| btDevicesPairing = new HashSet<String>(); | |||||
| btDevicesPairing = new HashMap<String, BluetoothGatt>(); | |||||
| MidiDeviceInfo[] foundDevices = manager.getDevices(); | MidiDeviceInfo[] foundDevices = manager.getDevices(); | ||||
| for (MidiDeviceInfo info : foundDevices) | for (MidiDeviceInfo info : foundDevices) | ||||
| @@ -600,8 +633,18 @@ public class JuceDemoPlugin extends Activity | |||||
| openPorts = null; | openPorts = null; | ||||
| for (MidiDevice device : midiDevices) | |||||
| device.close(); | |||||
| for (Pair<MidiDevice, BluetoothGatt> device : midiDevices) | |||||
| { | |||||
| if (device.second != null) | |||||
| { | |||||
| device.second.disconnect(); | |||||
| device.second.close(); | |||||
| } | |||||
| device.first.close(); | |||||
| } | |||||
| midiDevices.clear(); | |||||
| super.finalize(); | super.finalize(); | ||||
| } | } | ||||
| @@ -647,30 +690,36 @@ public class JuceDemoPlugin extends Activity | |||||
| if (openPorts.containsKey (portInfo)) | if (openPorts.containsKey (portInfo)) | ||||
| return null; | return null; | ||||
| MidiDevice device = getMidiDeviceForId (portInfo.deviceId); | |||||
| if (device != null) | |||||
| { | |||||
| JuceMidiPort juceMidiPort = null; | |||||
| Pair<MidiDevice,BluetoothGatt> devicePair = getMidiDevicePairForId (portInfo.deviceId); | |||||
| if (isInput) | |||||
| if (devicePair != null) | |||||
| { | |||||
| MidiDevice device = devicePair.first; | |||||
| if (device != null) | |||||
| { | { | ||||
| MidiOutputPort outputPort = device.openOutputPort (portInfo.portIndex); | |||||
| JuceMidiPort juceMidiPort = null; | |||||
| if (outputPort != null) | |||||
| juceMidiPort = new JuceMidiInputPort(this, outputPort, portInfo, host); | |||||
| } | |||||
| else | |||||
| { | |||||
| MidiInputPort inputPort = device.openInputPort (portInfo.portIndex); | |||||
| if (isInput) | |||||
| { | |||||
| MidiOutputPort outputPort = device.openOutputPort(portInfo.portIndex); | |||||
| if (inputPort != null) | |||||
| juceMidiPort = new JuceMidiOutputPort(this, inputPort, portInfo); | |||||
| } | |||||
| if (outputPort != null) | |||||
| juceMidiPort = new JuceMidiInputPort(this, outputPort, portInfo, host); | |||||
| } | |||||
| else | |||||
| { | |||||
| MidiInputPort inputPort = device.openInputPort(portInfo.portIndex); | |||||
| if (juceMidiPort != null) { | |||||
| openPorts.put(portInfo, new WeakReference<JuceMidiPort>(juceMidiPort)); | |||||
| if (inputPort != null) | |||||
| juceMidiPort = new JuceMidiOutputPort(this, inputPort, portInfo); | |||||
| } | |||||
| return juceMidiPort; | |||||
| if (juceMidiPort != null) | |||||
| { | |||||
| openPorts.put(portInfo, new WeakReference<JuceMidiPort>(juceMidiPort)); | |||||
| return juceMidiPort; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -699,7 +748,7 @@ public class JuceDemoPlugin extends Activity | |||||
| if (findMidiDeviceForBluetoothAddress (address) != null) | if (findMidiDeviceForBluetoothAddress (address) != null) | ||||
| return 1; | return 1; | ||||
| if (btDevicesPairing.contains (address)) | |||||
| if (btDevicesPairing.containsKey (address)) | |||||
| return 2; | return 2; | ||||
| if (findOpenTaskForBluetoothAddress (address) != null) | if (findOpenTaskForBluetoothAddress (address) != null) | ||||
| @@ -721,7 +770,11 @@ public class JuceDemoPlugin extends Activity | |||||
| if (getBluetoothDeviceStatus (btAddress) != 0) | if (getBluetoothDeviceStatus (btAddress) != 0) | ||||
| return false; | return false; | ||||
| btDevicesPairing.add (btDevice.getAddress()); | |||||
| BluetoothGatt gatt = btDevice.connectGatt (getApplicationContext(), true, new DummyBluetoothGattCallback()); | |||||
| if (gatt != null) | |||||
| gatt.requestConnectionPriority (BluetoothGatt.CONNECTION_PRIORITY_HIGH); | |||||
| btDevicesPairing.put (btDevice.getAddress(), gatt); | |||||
| manager.openBluetoothDevice(btDevice, this, null); | manager.openBluetoothDevice(btDevice, this, null); | ||||
| } | } | ||||
| @@ -735,7 +788,17 @@ public class JuceDemoPlugin extends Activity | |||||
| synchronized (MidiDeviceManager.class) | synchronized (MidiDeviceManager.class) | ||||
| { | { | ||||
| btDevicesPairing.remove (address); | |||||
| if (btDevicesPairing.containsKey (address)) | |||||
| { | |||||
| BluetoothGatt gatt = btDevicesPairing.get (address); | |||||
| if (gatt != null) | |||||
| { | |||||
| gatt.disconnect(); | |||||
| gatt.close(); | |||||
| } | |||||
| btDevicesPairing.remove (address); | |||||
| } | |||||
| MidiDeviceOpenTask openTask = findOpenTaskForBluetoothAddress (address); | MidiDeviceOpenTask openTask = findOpenTaskForBluetoothAddress (address); | ||||
| if (openTask != null) | if (openTask != null) | ||||
| @@ -745,9 +808,10 @@ public class JuceDemoPlugin extends Activity | |||||
| openTasks.remove (deviceID); | openTasks.remove (deviceID); | ||||
| } | } | ||||
| MidiDevice midiDevice = findMidiDeviceForBluetoothAddress (address); | |||||
| if (midiDevice != null) | |||||
| Pair<MidiDevice, BluetoothGatt> midiDevicePair = findMidiDeviceForBluetoothAddress (address); | |||||
| if (midiDevicePair != null) | |||||
| { | { | ||||
| MidiDevice midiDevice = midiDevicePair.first; | |||||
| onDeviceRemoved (midiDevice.getInfo()); | onDeviceRemoved (midiDevice.getInfo()); | ||||
| try { | try { | ||||
| @@ -761,11 +825,11 @@ public class JuceDemoPlugin extends Activity | |||||
| } | } | ||||
| } | } | ||||
| private MidiDevice findMidiDeviceForBluetoothAddress (String address) | |||||
| private Pair<MidiDevice, BluetoothGatt> findMidiDeviceForBluetoothAddress (String address) | |||||
| { | { | ||||
| for (MidiDevice midiDevice : midiDevices) | |||||
| for (Pair<MidiDevice,BluetoothGatt> midiDevice : midiDevices) | |||||
| { | { | ||||
| MidiDeviceInfo info = midiDevice.getInfo(); | |||||
| MidiDeviceInfo info = midiDevice.first.getInfo(); | |||||
| if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH) | if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH) | ||||
| { | { | ||||
| BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); | BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); | ||||
| @@ -825,24 +889,38 @@ public class JuceDemoPlugin extends Activity | |||||
| { | { | ||||
| synchronized (MidiDeviceManager.class) | synchronized (MidiDeviceManager.class) | ||||
| { | { | ||||
| MidiDevice device = getMidiDeviceForId (info.getId()); | |||||
| // close all ports that use this device | |||||
| boolean removedPort = true; | |||||
| while (removedPort == true) { | |||||
| removedPort = false; | |||||
| for (MidiPortPath key : openPorts.keySet()) { | |||||
| if (key.deviceId == info.getId()) { | |||||
| openPorts.get(key).get().close(); | |||||
| removedPort = true; | |||||
| break; | |||||
| Pair<MidiDevice, BluetoothGatt> devicePair = getMidiDevicePairForId (info.getId()); | |||||
| if (devicePair != null) | |||||
| { | |||||
| MidiDevice midiDevice = devicePair.first; | |||||
| BluetoothGatt gatt = devicePair.second; | |||||
| // close all ports that use this device | |||||
| boolean removedPort = true; | |||||
| while (removedPort == true) | |||||
| { | |||||
| removedPort = false; | |||||
| for (MidiPortPath key : openPorts.keySet()) | |||||
| { | |||||
| if (key.deviceId == info.getId()) | |||||
| { | |||||
| openPorts.get(key).get().close(); | |||||
| removedPort = true; | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | |||||
| if (device != null) | |||||
| midiDevices.remove (device); | |||||
| if (gatt != null) | |||||
| { | |||||
| gatt.disconnect(); | |||||
| gatt.close(); | |||||
| } | |||||
| midiDevices.remove (devicePair); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -857,6 +935,7 @@ public class JuceDemoPlugin extends Activity | |||||
| { | { | ||||
| MidiDeviceInfo info = theDevice.getInfo(); | MidiDeviceInfo info = theDevice.getInfo(); | ||||
| int deviceID = info.getId(); | int deviceID = info.getId(); | ||||
| BluetoothGatt gatt = null; | |||||
| if (! openTasks.containsKey (deviceID)) | if (! openTasks.containsKey (deviceID)) | ||||
| { | { | ||||
| @@ -866,8 +945,9 @@ public class JuceDemoPlugin extends Activity | |||||
| if (btDevice != null) | if (btDevice != null) | ||||
| { | { | ||||
| String btAddress = btDevice.getAddress(); | String btAddress = btDevice.getAddress(); | ||||
| if (btDevicesPairing.contains (btAddress)) | |||||
| if (btDevicesPairing.containsKey (btAddress)) | |||||
| { | { | ||||
| gatt = btDevicesPairing.get (btAddress); | |||||
| btDevicesPairing.remove (btAddress); | btDevicesPairing.remove (btAddress); | ||||
| } | } | ||||
| else | else | ||||
| @@ -875,6 +955,18 @@ public class JuceDemoPlugin extends Activity | |||||
| // unpair was called in the mean time | // unpair was called in the mean time | ||||
| try | try | ||||
| { | { | ||||
| Pair<MidiDevice, BluetoothGatt> midiDevicePair = findMidiDeviceForBluetoothAddress (btDevice.getAddress()); | |||||
| if (midiDevicePair != null) | |||||
| { | |||||
| gatt = midiDevicePair.second; | |||||
| if (gatt != null) | |||||
| { | |||||
| gatt.disconnect(); | |||||
| gatt.close(); | |||||
| } | |||||
| } | |||||
| theDevice.close(); | theDevice.close(); | ||||
| } | } | ||||
| catch (IOException e) | catch (IOException e) | ||||
| @@ -885,7 +977,7 @@ public class JuceDemoPlugin extends Activity | |||||
| } | } | ||||
| } | } | ||||
| MidiDeviceOpenTask openTask = new MidiDeviceOpenTask (this, theDevice); | |||||
| MidiDeviceOpenTask openTask = new MidiDeviceOpenTask (this, theDevice, gatt); | |||||
| openTasks.put (deviceID, openTask); | openTasks.put (deviceID, openTask); | ||||
| new java.util.Timer().schedule (openTask, 3000); | new java.util.Timer().schedule (openTask, 3000); | ||||
| @@ -903,13 +995,32 @@ public class JuceDemoPlugin extends Activity | |||||
| { | { | ||||
| if (! midiDevices.contains(theDevice)) | if (! midiDevices.contains(theDevice)) | ||||
| { | { | ||||
| BluetoothGatt gatt = openTasks.get (deviceID).getGatt(); | |||||
| openTasks.remove (deviceID); | openTasks.remove (deviceID); | ||||
| midiDevices.add (theDevice); | |||||
| midiDevices.add (new Pair<MidiDevice,BluetoothGatt> (theDevice, gatt)); | |||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| // unpair was called in the mean time | // unpair was called in the mean time | ||||
| MidiDeviceInfo info = theDevice.getInfo(); | |||||
| BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); | |||||
| if (btDevice != null) | |||||
| { | |||||
| String btAddress = btDevice.getAddress(); | |||||
| Pair<MidiDevice, BluetoothGatt> midiDevicePair = findMidiDeviceForBluetoothAddress (btDevice.getAddress()); | |||||
| if (midiDevicePair != null) | |||||
| { | |||||
| BluetoothGatt gatt = midiDevicePair.second; | |||||
| if (gatt != null) | |||||
| { | |||||
| gatt.disconnect(); | |||||
| gatt.close(); | |||||
| } | |||||
| } | |||||
| } | |||||
| try | try | ||||
| { | { | ||||
| theDevice.close(); | theDevice.close(); | ||||
| @@ -983,19 +1094,19 @@ public class JuceDemoPlugin extends Activity | |||||
| MidiDeviceInfo[] infos = new MidiDeviceInfo[midiDevices.size()]; | MidiDeviceInfo[] infos = new MidiDeviceInfo[midiDevices.size()]; | ||||
| int idx = 0; | int idx = 0; | ||||
| for (MidiDevice midiDevice : midiDevices) | |||||
| infos[idx++] = midiDevice.getInfo(); | |||||
| for (Pair<MidiDevice,BluetoothGatt> midiDevice : midiDevices) | |||||
| infos[idx++] = midiDevice.first.getInfo(); | |||||
| return infos; | return infos; | ||||
| } | } | ||||
| } | } | ||||
| private MidiDevice getMidiDeviceForId (int deviceId) | |||||
| private Pair<MidiDevice, BluetoothGatt> getMidiDevicePairForId (int deviceId) | |||||
| { | { | ||||
| synchronized (MidiDeviceManager.class) | synchronized (MidiDeviceManager.class) | ||||
| { | { | ||||
| for (MidiDevice midiDevice : midiDevices) | |||||
| if (midiDevice.getInfo().getId() == deviceId) | |||||
| for (Pair<MidiDevice,BluetoothGatt> midiDevice : midiDevices) | |||||
| if (midiDevice.first.getInfo().getId() == deviceId) | |||||
| return midiDevice; | return midiDevice; | ||||
| } | } | ||||
| @@ -1003,9 +1114,9 @@ public class JuceDemoPlugin extends Activity | |||||
| } | } | ||||
| private MidiManager manager; | private MidiManager manager; | ||||
| private HashSet<String> btDevicesPairing; | |||||
| private HashMap<String, BluetoothGatt> btDevicesPairing; | |||||
| private HashMap<Integer, MidiDeviceOpenTask> openTasks; | private HashMap<Integer, MidiDeviceOpenTask> openTasks; | ||||
| private ArrayList<MidiDevice> midiDevices; | |||||
| private ArrayList<Pair<MidiDevice, BluetoothGatt>> midiDevices; | |||||
| private MidiDeviceInfo[] deviceInfos; | private MidiDeviceInfo[] deviceInfos; | ||||
| private HashMap<MidiPortPath, WeakReference<JuceMidiPort>> openPorts; | private HashMap<MidiPortPath, WeakReference<JuceMidiPort>> openPorts; | ||||
| } | } | ||||
| @@ -54,6 +54,7 @@ import android.text.ClipboardManager; | |||||
| import android.text.InputType; | import android.text.InputType; | ||||
| import android.util.DisplayMetrics; | import android.util.DisplayMetrics; | ||||
| import android.util.Log; | import android.util.Log; | ||||
| import android.util.Pair; | |||||
| import java.lang.Runnable; | import java.lang.Runnable; | ||||
| import java.lang.ref.WeakReference; | import java.lang.ref.WeakReference; | ||||
| import java.lang.reflect.*; | import java.lang.reflect.*; | ||||
| @@ -487,13 +488,34 @@ public class AudioPerformanceTest extends Activity | |||||
| //============================================================================== | //============================================================================== | ||||
| public class MidiDeviceManager extends MidiManager.DeviceCallback implements MidiManager.OnDeviceOpenedListener | public class MidiDeviceManager extends MidiManager.DeviceCallback implements MidiManager.OnDeviceOpenedListener | ||||
| { | { | ||||
| //============================================================================== | |||||
| private class DummyBluetoothGattCallback extends BluetoothGattCallback | |||||
| { | |||||
| public DummyBluetoothGattCallback() | |||||
| { | |||||
| super(); | |||||
| } | |||||
| public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {} | |||||
| public void onServicesDiscovered(BluetoothGatt gatt, int status) {} | |||||
| public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {} | |||||
| public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {} | |||||
| public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {} | |||||
| public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {} | |||||
| public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {} | |||||
| public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {} | |||||
| public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {} | |||||
| public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {} | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| private class MidiDeviceOpenTask extends java.util.TimerTask | private class MidiDeviceOpenTask extends java.util.TimerTask | ||||
| { | { | ||||
| public MidiDeviceOpenTask (MidiDeviceManager deviceManager, MidiDevice device) | |||||
| public MidiDeviceOpenTask (MidiDeviceManager deviceManager, MidiDevice device, BluetoothGatt gattToUse) | |||||
| { | { | ||||
| owner = deviceManager; | owner = deviceManager; | ||||
| midiDevice = device; | midiDevice = device; | ||||
| btGatt = gattToUse; | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -504,6 +526,14 @@ public class AudioPerformanceTest extends Activity | |||||
| owner = null; | owner = null; | ||||
| boolean retval = super.cancel(); | boolean retval = super.cancel(); | ||||
| if (btGatt != null) | |||||
| { | |||||
| btGatt.disconnect(); | |||||
| btGatt.close(); | |||||
| btGatt = null; | |||||
| } | |||||
| if (midiDevice != null) | if (midiDevice != null) | ||||
| { | { | ||||
| try | try | ||||
| @@ -539,6 +569,8 @@ public class AudioPerformanceTest extends Activity | |||||
| return ""; | return ""; | ||||
| } | } | ||||
| public BluetoothGatt getGatt() { return btGatt; } | |||||
| public int getID() | public int getID() | ||||
| { | { | ||||
| return midiDevice.getInfo().getId(); | return midiDevice.getInfo().getId(); | ||||
| @@ -556,6 +588,7 @@ public class AudioPerformanceTest extends Activity | |||||
| private MidiDeviceManager owner; | private MidiDeviceManager owner; | ||||
| private MidiDevice midiDevice; | private MidiDevice midiDevice; | ||||
| private BluetoothGatt btGatt; | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -570,9 +603,9 @@ public class AudioPerformanceTest extends Activity | |||||
| } | } | ||||
| openPorts = new HashMap<MidiPortPath, WeakReference<JuceMidiPort>> (); | openPorts = new HashMap<MidiPortPath, WeakReference<JuceMidiPort>> (); | ||||
| midiDevices = new ArrayList<MidiDevice>(); | |||||
| midiDevices = new ArrayList<Pair<MidiDevice,BluetoothGatt>>(); | |||||
| openTasks = new HashMap<Integer, MidiDeviceOpenTask>(); | openTasks = new HashMap<Integer, MidiDeviceOpenTask>(); | ||||
| btDevicesPairing = new HashSet<String>(); | |||||
| btDevicesPairing = new HashMap<String, BluetoothGatt>(); | |||||
| MidiDeviceInfo[] foundDevices = manager.getDevices(); | MidiDeviceInfo[] foundDevices = manager.getDevices(); | ||||
| for (MidiDeviceInfo info : foundDevices) | for (MidiDeviceInfo info : foundDevices) | ||||
| @@ -600,8 +633,18 @@ public class AudioPerformanceTest extends Activity | |||||
| openPorts = null; | openPorts = null; | ||||
| for (MidiDevice device : midiDevices) | |||||
| device.close(); | |||||
| for (Pair<MidiDevice, BluetoothGatt> device : midiDevices) | |||||
| { | |||||
| if (device.second != null) | |||||
| { | |||||
| device.second.disconnect(); | |||||
| device.second.close(); | |||||
| } | |||||
| device.first.close(); | |||||
| } | |||||
| midiDevices.clear(); | |||||
| super.finalize(); | super.finalize(); | ||||
| } | } | ||||
| @@ -647,30 +690,36 @@ public class AudioPerformanceTest extends Activity | |||||
| if (openPorts.containsKey (portInfo)) | if (openPorts.containsKey (portInfo)) | ||||
| return null; | return null; | ||||
| MidiDevice device = getMidiDeviceForId (portInfo.deviceId); | |||||
| if (device != null) | |||||
| { | |||||
| JuceMidiPort juceMidiPort = null; | |||||
| Pair<MidiDevice,BluetoothGatt> devicePair = getMidiDevicePairForId (portInfo.deviceId); | |||||
| if (isInput) | |||||
| if (devicePair != null) | |||||
| { | |||||
| MidiDevice device = devicePair.first; | |||||
| if (device != null) | |||||
| { | { | ||||
| MidiOutputPort outputPort = device.openOutputPort (portInfo.portIndex); | |||||
| JuceMidiPort juceMidiPort = null; | |||||
| if (outputPort != null) | |||||
| juceMidiPort = new JuceMidiInputPort(this, outputPort, portInfo, host); | |||||
| } | |||||
| else | |||||
| { | |||||
| MidiInputPort inputPort = device.openInputPort (portInfo.portIndex); | |||||
| if (isInput) | |||||
| { | |||||
| MidiOutputPort outputPort = device.openOutputPort(portInfo.portIndex); | |||||
| if (inputPort != null) | |||||
| juceMidiPort = new JuceMidiOutputPort(this, inputPort, portInfo); | |||||
| } | |||||
| if (outputPort != null) | |||||
| juceMidiPort = new JuceMidiInputPort(this, outputPort, portInfo, host); | |||||
| } | |||||
| else | |||||
| { | |||||
| MidiInputPort inputPort = device.openInputPort(portInfo.portIndex); | |||||
| if (juceMidiPort != null) { | |||||
| openPorts.put(portInfo, new WeakReference<JuceMidiPort>(juceMidiPort)); | |||||
| if (inputPort != null) | |||||
| juceMidiPort = new JuceMidiOutputPort(this, inputPort, portInfo); | |||||
| } | |||||
| return juceMidiPort; | |||||
| if (juceMidiPort != null) | |||||
| { | |||||
| openPorts.put(portInfo, new WeakReference<JuceMidiPort>(juceMidiPort)); | |||||
| return juceMidiPort; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -699,7 +748,7 @@ public class AudioPerformanceTest extends Activity | |||||
| if (findMidiDeviceForBluetoothAddress (address) != null) | if (findMidiDeviceForBluetoothAddress (address) != null) | ||||
| return 1; | return 1; | ||||
| if (btDevicesPairing.contains (address)) | |||||
| if (btDevicesPairing.containsKey (address)) | |||||
| return 2; | return 2; | ||||
| if (findOpenTaskForBluetoothAddress (address) != null) | if (findOpenTaskForBluetoothAddress (address) != null) | ||||
| @@ -721,7 +770,11 @@ public class AudioPerformanceTest extends Activity | |||||
| if (getBluetoothDeviceStatus (btAddress) != 0) | if (getBluetoothDeviceStatus (btAddress) != 0) | ||||
| return false; | return false; | ||||
| btDevicesPairing.add (btDevice.getAddress()); | |||||
| BluetoothGatt gatt = btDevice.connectGatt (getApplicationContext(), true, new DummyBluetoothGattCallback()); | |||||
| if (gatt != null) | |||||
| gatt.requestConnectionPriority (BluetoothGatt.CONNECTION_PRIORITY_HIGH); | |||||
| btDevicesPairing.put (btDevice.getAddress(), gatt); | |||||
| manager.openBluetoothDevice(btDevice, this, null); | manager.openBluetoothDevice(btDevice, this, null); | ||||
| } | } | ||||
| @@ -735,7 +788,17 @@ public class AudioPerformanceTest extends Activity | |||||
| synchronized (MidiDeviceManager.class) | synchronized (MidiDeviceManager.class) | ||||
| { | { | ||||
| btDevicesPairing.remove (address); | |||||
| if (btDevicesPairing.containsKey (address)) | |||||
| { | |||||
| BluetoothGatt gatt = btDevicesPairing.get (address); | |||||
| if (gatt != null) | |||||
| { | |||||
| gatt.disconnect(); | |||||
| gatt.close(); | |||||
| } | |||||
| btDevicesPairing.remove (address); | |||||
| } | |||||
| MidiDeviceOpenTask openTask = findOpenTaskForBluetoothAddress (address); | MidiDeviceOpenTask openTask = findOpenTaskForBluetoothAddress (address); | ||||
| if (openTask != null) | if (openTask != null) | ||||
| @@ -745,9 +808,10 @@ public class AudioPerformanceTest extends Activity | |||||
| openTasks.remove (deviceID); | openTasks.remove (deviceID); | ||||
| } | } | ||||
| MidiDevice midiDevice = findMidiDeviceForBluetoothAddress (address); | |||||
| if (midiDevice != null) | |||||
| Pair<MidiDevice, BluetoothGatt> midiDevicePair = findMidiDeviceForBluetoothAddress (address); | |||||
| if (midiDevicePair != null) | |||||
| { | { | ||||
| MidiDevice midiDevice = midiDevicePair.first; | |||||
| onDeviceRemoved (midiDevice.getInfo()); | onDeviceRemoved (midiDevice.getInfo()); | ||||
| try { | try { | ||||
| @@ -761,11 +825,11 @@ public class AudioPerformanceTest extends Activity | |||||
| } | } | ||||
| } | } | ||||
| private MidiDevice findMidiDeviceForBluetoothAddress (String address) | |||||
| private Pair<MidiDevice, BluetoothGatt> findMidiDeviceForBluetoothAddress (String address) | |||||
| { | { | ||||
| for (MidiDevice midiDevice : midiDevices) | |||||
| for (Pair<MidiDevice,BluetoothGatt> midiDevice : midiDevices) | |||||
| { | { | ||||
| MidiDeviceInfo info = midiDevice.getInfo(); | |||||
| MidiDeviceInfo info = midiDevice.first.getInfo(); | |||||
| if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH) | if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH) | ||||
| { | { | ||||
| BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); | BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); | ||||
| @@ -825,24 +889,38 @@ public class AudioPerformanceTest extends Activity | |||||
| { | { | ||||
| synchronized (MidiDeviceManager.class) | synchronized (MidiDeviceManager.class) | ||||
| { | { | ||||
| MidiDevice device = getMidiDeviceForId (info.getId()); | |||||
| // close all ports that use this device | |||||
| boolean removedPort = true; | |||||
| while (removedPort == true) { | |||||
| removedPort = false; | |||||
| for (MidiPortPath key : openPorts.keySet()) { | |||||
| if (key.deviceId == info.getId()) { | |||||
| openPorts.get(key).get().close(); | |||||
| removedPort = true; | |||||
| break; | |||||
| Pair<MidiDevice, BluetoothGatt> devicePair = getMidiDevicePairForId (info.getId()); | |||||
| if (devicePair != null) | |||||
| { | |||||
| MidiDevice midiDevice = devicePair.first; | |||||
| BluetoothGatt gatt = devicePair.second; | |||||
| // close all ports that use this device | |||||
| boolean removedPort = true; | |||||
| while (removedPort == true) | |||||
| { | |||||
| removedPort = false; | |||||
| for (MidiPortPath key : openPorts.keySet()) | |||||
| { | |||||
| if (key.deviceId == info.getId()) | |||||
| { | |||||
| openPorts.get(key).get().close(); | |||||
| removedPort = true; | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | |||||
| if (device != null) | |||||
| midiDevices.remove (device); | |||||
| if (gatt != null) | |||||
| { | |||||
| gatt.disconnect(); | |||||
| gatt.close(); | |||||
| } | |||||
| midiDevices.remove (devicePair); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -857,6 +935,7 @@ public class AudioPerformanceTest extends Activity | |||||
| { | { | ||||
| MidiDeviceInfo info = theDevice.getInfo(); | MidiDeviceInfo info = theDevice.getInfo(); | ||||
| int deviceID = info.getId(); | int deviceID = info.getId(); | ||||
| BluetoothGatt gatt = null; | |||||
| if (! openTasks.containsKey (deviceID)) | if (! openTasks.containsKey (deviceID)) | ||||
| { | { | ||||
| @@ -866,8 +945,9 @@ public class AudioPerformanceTest extends Activity | |||||
| if (btDevice != null) | if (btDevice != null) | ||||
| { | { | ||||
| String btAddress = btDevice.getAddress(); | String btAddress = btDevice.getAddress(); | ||||
| if (btDevicesPairing.contains (btAddress)) | |||||
| if (btDevicesPairing.containsKey (btAddress)) | |||||
| { | { | ||||
| gatt = btDevicesPairing.get (btAddress); | |||||
| btDevicesPairing.remove (btAddress); | btDevicesPairing.remove (btAddress); | ||||
| } | } | ||||
| else | else | ||||
| @@ -875,6 +955,18 @@ public class AudioPerformanceTest extends Activity | |||||
| // unpair was called in the mean time | // unpair was called in the mean time | ||||
| try | try | ||||
| { | { | ||||
| Pair<MidiDevice, BluetoothGatt> midiDevicePair = findMidiDeviceForBluetoothAddress (btDevice.getAddress()); | |||||
| if (midiDevicePair != null) | |||||
| { | |||||
| gatt = midiDevicePair.second; | |||||
| if (gatt != null) | |||||
| { | |||||
| gatt.disconnect(); | |||||
| gatt.close(); | |||||
| } | |||||
| } | |||||
| theDevice.close(); | theDevice.close(); | ||||
| } | } | ||||
| catch (IOException e) | catch (IOException e) | ||||
| @@ -885,7 +977,7 @@ public class AudioPerformanceTest extends Activity | |||||
| } | } | ||||
| } | } | ||||
| MidiDeviceOpenTask openTask = new MidiDeviceOpenTask (this, theDevice); | |||||
| MidiDeviceOpenTask openTask = new MidiDeviceOpenTask (this, theDevice, gatt); | |||||
| openTasks.put (deviceID, openTask); | openTasks.put (deviceID, openTask); | ||||
| new java.util.Timer().schedule (openTask, 3000); | new java.util.Timer().schedule (openTask, 3000); | ||||
| @@ -903,13 +995,32 @@ public class AudioPerformanceTest extends Activity | |||||
| { | { | ||||
| if (! midiDevices.contains(theDevice)) | if (! midiDevices.contains(theDevice)) | ||||
| { | { | ||||
| BluetoothGatt gatt = openTasks.get (deviceID).getGatt(); | |||||
| openTasks.remove (deviceID); | openTasks.remove (deviceID); | ||||
| midiDevices.add (theDevice); | |||||
| midiDevices.add (new Pair<MidiDevice,BluetoothGatt> (theDevice, gatt)); | |||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| // unpair was called in the mean time | // unpair was called in the mean time | ||||
| MidiDeviceInfo info = theDevice.getInfo(); | |||||
| BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); | |||||
| if (btDevice != null) | |||||
| { | |||||
| String btAddress = btDevice.getAddress(); | |||||
| Pair<MidiDevice, BluetoothGatt> midiDevicePair = findMidiDeviceForBluetoothAddress (btDevice.getAddress()); | |||||
| if (midiDevicePair != null) | |||||
| { | |||||
| BluetoothGatt gatt = midiDevicePair.second; | |||||
| if (gatt != null) | |||||
| { | |||||
| gatt.disconnect(); | |||||
| gatt.close(); | |||||
| } | |||||
| } | |||||
| } | |||||
| try | try | ||||
| { | { | ||||
| theDevice.close(); | theDevice.close(); | ||||
| @@ -983,19 +1094,19 @@ public class AudioPerformanceTest extends Activity | |||||
| MidiDeviceInfo[] infos = new MidiDeviceInfo[midiDevices.size()]; | MidiDeviceInfo[] infos = new MidiDeviceInfo[midiDevices.size()]; | ||||
| int idx = 0; | int idx = 0; | ||||
| for (MidiDevice midiDevice : midiDevices) | |||||
| infos[idx++] = midiDevice.getInfo(); | |||||
| for (Pair<MidiDevice,BluetoothGatt> midiDevice : midiDevices) | |||||
| infos[idx++] = midiDevice.first.getInfo(); | |||||
| return infos; | return infos; | ||||
| } | } | ||||
| } | } | ||||
| private MidiDevice getMidiDeviceForId (int deviceId) | |||||
| private Pair<MidiDevice, BluetoothGatt> getMidiDevicePairForId (int deviceId) | |||||
| { | { | ||||
| synchronized (MidiDeviceManager.class) | synchronized (MidiDeviceManager.class) | ||||
| { | { | ||||
| for (MidiDevice midiDevice : midiDevices) | |||||
| if (midiDevice.getInfo().getId() == deviceId) | |||||
| for (Pair<MidiDevice,BluetoothGatt> midiDevice : midiDevices) | |||||
| if (midiDevice.first.getInfo().getId() == deviceId) | |||||
| return midiDevice; | return midiDevice; | ||||
| } | } | ||||
| @@ -1003,9 +1114,9 @@ public class AudioPerformanceTest extends Activity | |||||
| } | } | ||||
| private MidiManager manager; | private MidiManager manager; | ||||
| private HashSet<String> btDevicesPairing; | |||||
| private HashMap<String, BluetoothGatt> btDevicesPairing; | |||||
| private HashMap<Integer, MidiDeviceOpenTask> openTasks; | private HashMap<Integer, MidiDeviceOpenTask> openTasks; | ||||
| private ArrayList<MidiDevice> midiDevices; | |||||
| private ArrayList<Pair<MidiDevice, BluetoothGatt>> midiDevices; | |||||
| private MidiDeviceInfo[] deviceInfos; | private MidiDeviceInfo[] deviceInfos; | ||||
| private HashMap<MidiPortPath, WeakReference<JuceMidiPort>> openPorts; | private HashMap<MidiPortPath, WeakReference<JuceMidiPort>> openPorts; | ||||
| } | } | ||||
| @@ -309,13 +309,34 @@ | |||||
| //============================================================================== | //============================================================================== | ||||
| public class MidiDeviceManager extends MidiManager.DeviceCallback implements MidiManager.OnDeviceOpenedListener | public class MidiDeviceManager extends MidiManager.DeviceCallback implements MidiManager.OnDeviceOpenedListener | ||||
| { | { | ||||
| //============================================================================== | |||||
| private class DummyBluetoothGattCallback extends BluetoothGattCallback | |||||
| { | |||||
| public DummyBluetoothGattCallback() | |||||
| { | |||||
| super(); | |||||
| } | |||||
| public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {} | |||||
| public void onServicesDiscovered(BluetoothGatt gatt, int status) {} | |||||
| public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {} | |||||
| public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {} | |||||
| public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {} | |||||
| public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {} | |||||
| public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {} | |||||
| public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {} | |||||
| public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {} | |||||
| public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {} | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| private class MidiDeviceOpenTask extends java.util.TimerTask | private class MidiDeviceOpenTask extends java.util.TimerTask | ||||
| { | { | ||||
| public MidiDeviceOpenTask (MidiDeviceManager deviceManager, MidiDevice device) | |||||
| public MidiDeviceOpenTask (MidiDeviceManager deviceManager, MidiDevice device, BluetoothGatt gattToUse) | |||||
| { | { | ||||
| owner = deviceManager; | owner = deviceManager; | ||||
| midiDevice = device; | midiDevice = device; | ||||
| btGatt = gattToUse; | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -326,6 +347,14 @@ | |||||
| owner = null; | owner = null; | ||||
| boolean retval = super.cancel(); | boolean retval = super.cancel(); | ||||
| if (btGatt != null) | |||||
| { | |||||
| btGatt.disconnect(); | |||||
| btGatt.close(); | |||||
| btGatt = null; | |||||
| } | |||||
| if (midiDevice != null) | if (midiDevice != null) | ||||
| { | { | ||||
| try | try | ||||
| @@ -361,6 +390,8 @@ | |||||
| return ""; | return ""; | ||||
| } | } | ||||
| public BluetoothGatt getGatt() { return btGatt; } | |||||
| public int getID() | public int getID() | ||||
| { | { | ||||
| return midiDevice.getInfo().getId(); | return midiDevice.getInfo().getId(); | ||||
| @@ -378,6 +409,7 @@ | |||||
| private MidiDeviceManager owner; | private MidiDeviceManager owner; | ||||
| private MidiDevice midiDevice; | private MidiDevice midiDevice; | ||||
| private BluetoothGatt btGatt; | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -392,9 +424,9 @@ | |||||
| } | } | ||||
| openPorts = new HashMap<MidiPortPath, WeakReference<JuceMidiPort>> (); | openPorts = new HashMap<MidiPortPath, WeakReference<JuceMidiPort>> (); | ||||
| midiDevices = new ArrayList<MidiDevice>(); | |||||
| midiDevices = new ArrayList<Pair<MidiDevice,BluetoothGatt>>(); | |||||
| openTasks = new HashMap<Integer, MidiDeviceOpenTask>(); | openTasks = new HashMap<Integer, MidiDeviceOpenTask>(); | ||||
| btDevicesPairing = new HashSet<String>(); | |||||
| btDevicesPairing = new HashMap<String, BluetoothGatt>(); | |||||
| MidiDeviceInfo[] foundDevices = manager.getDevices(); | MidiDeviceInfo[] foundDevices = manager.getDevices(); | ||||
| for (MidiDeviceInfo info : foundDevices) | for (MidiDeviceInfo info : foundDevices) | ||||
| @@ -422,8 +454,18 @@ | |||||
| openPorts = null; | openPorts = null; | ||||
| for (MidiDevice device : midiDevices) | |||||
| device.close(); | |||||
| for (Pair<MidiDevice, BluetoothGatt> device : midiDevices) | |||||
| { | |||||
| if (device.second != null) | |||||
| { | |||||
| device.second.disconnect(); | |||||
| device.second.close(); | |||||
| } | |||||
| device.first.close(); | |||||
| } | |||||
| midiDevices.clear(); | |||||
| super.finalize(); | super.finalize(); | ||||
| } | } | ||||
| @@ -469,30 +511,36 @@ | |||||
| if (openPorts.containsKey (portInfo)) | if (openPorts.containsKey (portInfo)) | ||||
| return null; | return null; | ||||
| MidiDevice device = getMidiDeviceForId (portInfo.deviceId); | |||||
| if (device != null) | |||||
| { | |||||
| JuceMidiPort juceMidiPort = null; | |||||
| Pair<MidiDevice,BluetoothGatt> devicePair = getMidiDevicePairForId (portInfo.deviceId); | |||||
| if (isInput) | |||||
| if (devicePair != null) | |||||
| { | |||||
| MidiDevice device = devicePair.first; | |||||
| if (device != null) | |||||
| { | { | ||||
| MidiOutputPort outputPort = device.openOutputPort (portInfo.portIndex); | |||||
| JuceMidiPort juceMidiPort = null; | |||||
| if (outputPort != null) | |||||
| juceMidiPort = new JuceMidiInputPort(this, outputPort, portInfo, host); | |||||
| } | |||||
| else | |||||
| { | |||||
| MidiInputPort inputPort = device.openInputPort (portInfo.portIndex); | |||||
| if (isInput) | |||||
| { | |||||
| MidiOutputPort outputPort = device.openOutputPort(portInfo.portIndex); | |||||
| if (inputPort != null) | |||||
| juceMidiPort = new JuceMidiOutputPort(this, inputPort, portInfo); | |||||
| } | |||||
| if (outputPort != null) | |||||
| juceMidiPort = new JuceMidiInputPort(this, outputPort, portInfo, host); | |||||
| } | |||||
| else | |||||
| { | |||||
| MidiInputPort inputPort = device.openInputPort(portInfo.portIndex); | |||||
| if (juceMidiPort != null) { | |||||
| openPorts.put(portInfo, new WeakReference<JuceMidiPort>(juceMidiPort)); | |||||
| if (inputPort != null) | |||||
| juceMidiPort = new JuceMidiOutputPort(this, inputPort, portInfo); | |||||
| } | |||||
| return juceMidiPort; | |||||
| if (juceMidiPort != null) | |||||
| { | |||||
| openPorts.put(portInfo, new WeakReference<JuceMidiPort>(juceMidiPort)); | |||||
| return juceMidiPort; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -521,7 +569,7 @@ | |||||
| if (findMidiDeviceForBluetoothAddress (address) != null) | if (findMidiDeviceForBluetoothAddress (address) != null) | ||||
| return 1; | return 1; | ||||
| if (btDevicesPairing.contains (address)) | |||||
| if (btDevicesPairing.containsKey (address)) | |||||
| return 2; | return 2; | ||||
| if (findOpenTaskForBluetoothAddress (address) != null) | if (findOpenTaskForBluetoothAddress (address) != null) | ||||
| @@ -543,7 +591,11 @@ | |||||
| if (getBluetoothDeviceStatus (btAddress) != 0) | if (getBluetoothDeviceStatus (btAddress) != 0) | ||||
| return false; | return false; | ||||
| btDevicesPairing.add (btDevice.getAddress()); | |||||
| BluetoothGatt gatt = btDevice.connectGatt (getApplicationContext(), true, new DummyBluetoothGattCallback()); | |||||
| if (gatt != null) | |||||
| gatt.requestConnectionPriority (BluetoothGatt.CONNECTION_PRIORITY_HIGH); | |||||
| btDevicesPairing.put (btDevice.getAddress(), gatt); | |||||
| manager.openBluetoothDevice(btDevice, this, null); | manager.openBluetoothDevice(btDevice, this, null); | ||||
| } | } | ||||
| @@ -557,7 +609,17 @@ | |||||
| synchronized (MidiDeviceManager.class) | synchronized (MidiDeviceManager.class) | ||||
| { | { | ||||
| btDevicesPairing.remove (address); | |||||
| if (btDevicesPairing.containsKey (address)) | |||||
| { | |||||
| BluetoothGatt gatt = btDevicesPairing.get (address); | |||||
| if (gatt != null) | |||||
| { | |||||
| gatt.disconnect(); | |||||
| gatt.close(); | |||||
| } | |||||
| btDevicesPairing.remove (address); | |||||
| } | |||||
| MidiDeviceOpenTask openTask = findOpenTaskForBluetoothAddress (address); | MidiDeviceOpenTask openTask = findOpenTaskForBluetoothAddress (address); | ||||
| if (openTask != null) | if (openTask != null) | ||||
| @@ -567,9 +629,10 @@ | |||||
| openTasks.remove (deviceID); | openTasks.remove (deviceID); | ||||
| } | } | ||||
| MidiDevice midiDevice = findMidiDeviceForBluetoothAddress (address); | |||||
| if (midiDevice != null) | |||||
| Pair<MidiDevice, BluetoothGatt> midiDevicePair = findMidiDeviceForBluetoothAddress (address); | |||||
| if (midiDevicePair != null) | |||||
| { | { | ||||
| MidiDevice midiDevice = midiDevicePair.first; | |||||
| onDeviceRemoved (midiDevice.getInfo()); | onDeviceRemoved (midiDevice.getInfo()); | ||||
| try { | try { | ||||
| @@ -583,11 +646,11 @@ | |||||
| } | } | ||||
| } | } | ||||
| private MidiDevice findMidiDeviceForBluetoothAddress (String address) | |||||
| private Pair<MidiDevice, BluetoothGatt> findMidiDeviceForBluetoothAddress (String address) | |||||
| { | { | ||||
| for (MidiDevice midiDevice : midiDevices) | |||||
| for (Pair<MidiDevice,BluetoothGatt> midiDevice : midiDevices) | |||||
| { | { | ||||
| MidiDeviceInfo info = midiDevice.getInfo(); | |||||
| MidiDeviceInfo info = midiDevice.first.getInfo(); | |||||
| if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH) | if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH) | ||||
| { | { | ||||
| BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); | BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); | ||||
| @@ -647,24 +710,38 @@ | |||||
| { | { | ||||
| synchronized (MidiDeviceManager.class) | synchronized (MidiDeviceManager.class) | ||||
| { | { | ||||
| MidiDevice device = getMidiDeviceForId (info.getId()); | |||||
| // close all ports that use this device | |||||
| boolean removedPort = true; | |||||
| while (removedPort == true) { | |||||
| removedPort = false; | |||||
| for (MidiPortPath key : openPorts.keySet()) { | |||||
| if (key.deviceId == info.getId()) { | |||||
| openPorts.get(key).get().close(); | |||||
| removedPort = true; | |||||
| break; | |||||
| Pair<MidiDevice, BluetoothGatt> devicePair = getMidiDevicePairForId (info.getId()); | |||||
| if (devicePair != null) | |||||
| { | |||||
| MidiDevice midiDevice = devicePair.first; | |||||
| BluetoothGatt gatt = devicePair.second; | |||||
| // close all ports that use this device | |||||
| boolean removedPort = true; | |||||
| while (removedPort == true) | |||||
| { | |||||
| removedPort = false; | |||||
| for (MidiPortPath key : openPorts.keySet()) | |||||
| { | |||||
| if (key.deviceId == info.getId()) | |||||
| { | |||||
| openPorts.get(key).get().close(); | |||||
| removedPort = true; | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | |||||
| if (device != null) | |||||
| midiDevices.remove (device); | |||||
| if (gatt != null) | |||||
| { | |||||
| gatt.disconnect(); | |||||
| gatt.close(); | |||||
| } | |||||
| midiDevices.remove (devicePair); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -679,6 +756,7 @@ | |||||
| { | { | ||||
| MidiDeviceInfo info = theDevice.getInfo(); | MidiDeviceInfo info = theDevice.getInfo(); | ||||
| int deviceID = info.getId(); | int deviceID = info.getId(); | ||||
| BluetoothGatt gatt = null; | |||||
| if (! openTasks.containsKey (deviceID)) | if (! openTasks.containsKey (deviceID)) | ||||
| { | { | ||||
| @@ -688,8 +766,9 @@ | |||||
| if (btDevice != null) | if (btDevice != null) | ||||
| { | { | ||||
| String btAddress = btDevice.getAddress(); | String btAddress = btDevice.getAddress(); | ||||
| if (btDevicesPairing.contains (btAddress)) | |||||
| if (btDevicesPairing.containsKey (btAddress)) | |||||
| { | { | ||||
| gatt = btDevicesPairing.get (btAddress); | |||||
| btDevicesPairing.remove (btAddress); | btDevicesPairing.remove (btAddress); | ||||
| } | } | ||||
| else | else | ||||
| @@ -697,6 +776,18 @@ | |||||
| // unpair was called in the mean time | // unpair was called in the mean time | ||||
| try | try | ||||
| { | { | ||||
| Pair<MidiDevice, BluetoothGatt> midiDevicePair = findMidiDeviceForBluetoothAddress (btDevice.getAddress()); | |||||
| if (midiDevicePair != null) | |||||
| { | |||||
| gatt = midiDevicePair.second; | |||||
| if (gatt != null) | |||||
| { | |||||
| gatt.disconnect(); | |||||
| gatt.close(); | |||||
| } | |||||
| } | |||||
| theDevice.close(); | theDevice.close(); | ||||
| } | } | ||||
| catch (IOException e) | catch (IOException e) | ||||
| @@ -707,7 +798,7 @@ | |||||
| } | } | ||||
| } | } | ||||
| MidiDeviceOpenTask openTask = new MidiDeviceOpenTask (this, theDevice); | |||||
| MidiDeviceOpenTask openTask = new MidiDeviceOpenTask (this, theDevice, gatt); | |||||
| openTasks.put (deviceID, openTask); | openTasks.put (deviceID, openTask); | ||||
| new java.util.Timer().schedule (openTask, 3000); | new java.util.Timer().schedule (openTask, 3000); | ||||
| @@ -725,13 +816,32 @@ | |||||
| { | { | ||||
| if (! midiDevices.contains(theDevice)) | if (! midiDevices.contains(theDevice)) | ||||
| { | { | ||||
| BluetoothGatt gatt = openTasks.get (deviceID).getGatt(); | |||||
| openTasks.remove (deviceID); | openTasks.remove (deviceID); | ||||
| midiDevices.add (theDevice); | |||||
| midiDevices.add (new Pair<MidiDevice,BluetoothGatt> (theDevice, gatt)); | |||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| // unpair was called in the mean time | // unpair was called in the mean time | ||||
| MidiDeviceInfo info = theDevice.getInfo(); | |||||
| BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); | |||||
| if (btDevice != null) | |||||
| { | |||||
| String btAddress = btDevice.getAddress(); | |||||
| Pair<MidiDevice, BluetoothGatt> midiDevicePair = findMidiDeviceForBluetoothAddress (btDevice.getAddress()); | |||||
| if (midiDevicePair != null) | |||||
| { | |||||
| BluetoothGatt gatt = midiDevicePair.second; | |||||
| if (gatt != null) | |||||
| { | |||||
| gatt.disconnect(); | |||||
| gatt.close(); | |||||
| } | |||||
| } | |||||
| } | |||||
| try | try | ||||
| { | { | ||||
| theDevice.close(); | theDevice.close(); | ||||
| @@ -805,19 +915,19 @@ | |||||
| MidiDeviceInfo[] infos = new MidiDeviceInfo[midiDevices.size()]; | MidiDeviceInfo[] infos = new MidiDeviceInfo[midiDevices.size()]; | ||||
| int idx = 0; | int idx = 0; | ||||
| for (MidiDevice midiDevice : midiDevices) | |||||
| infos[idx++] = midiDevice.getInfo(); | |||||
| for (Pair<MidiDevice,BluetoothGatt> midiDevice : midiDevices) | |||||
| infos[idx++] = midiDevice.first.getInfo(); | |||||
| return infos; | return infos; | ||||
| } | } | ||||
| } | } | ||||
| private MidiDevice getMidiDeviceForId (int deviceId) | |||||
| private Pair<MidiDevice, BluetoothGatt> getMidiDevicePairForId (int deviceId) | |||||
| { | { | ||||
| synchronized (MidiDeviceManager.class) | synchronized (MidiDeviceManager.class) | ||||
| { | { | ||||
| for (MidiDevice midiDevice : midiDevices) | |||||
| if (midiDevice.getInfo().getId() == deviceId) | |||||
| for (Pair<MidiDevice,BluetoothGatt> midiDevice : midiDevices) | |||||
| if (midiDevice.first.getInfo().getId() == deviceId) | |||||
| return midiDevice; | return midiDevice; | ||||
| } | } | ||||
| @@ -825,9 +935,9 @@ | |||||
| } | } | ||||
| private MidiManager manager; | private MidiManager manager; | ||||
| private HashSet<String> btDevicesPairing; | |||||
| private HashMap<String, BluetoothGatt> btDevicesPairing; | |||||
| private HashMap<Integer, MidiDeviceOpenTask> openTasks; | private HashMap<Integer, MidiDeviceOpenTask> openTasks; | ||||
| private ArrayList<MidiDevice> midiDevices; | |||||
| private ArrayList<Pair<MidiDevice, BluetoothGatt>> midiDevices; | |||||
| private MidiDeviceInfo[] deviceInfos; | private MidiDeviceInfo[] deviceInfos; | ||||
| private HashMap<MidiPortPath, WeakReference<JuceMidiPort>> openPorts; | private HashMap<MidiPortPath, WeakReference<JuceMidiPort>> openPorts; | ||||
| } | } | ||||
| @@ -54,6 +54,7 @@ import android.text.ClipboardManager; | |||||
| import android.text.InputType; | import android.text.InputType; | ||||
| import android.util.DisplayMetrics; | import android.util.DisplayMetrics; | ||||
| import android.util.Log; | import android.util.Log; | ||||
| import android.util.Pair; | |||||
| import java.lang.Runnable; | import java.lang.Runnable; | ||||
| import java.lang.ref.WeakReference; | import java.lang.ref.WeakReference; | ||||
| import java.lang.reflect.*; | import java.lang.reflect.*; | ||||