From f4c67f6fa7bc0337f557e52fb6bf5c437a8093ec Mon Sep 17 00:00:00 2001 From: ed Date: Mon, 3 Dec 2018 17:02:26 +0000 Subject: [PATCH] Whitespace --- .../java/com/roli/juce/JuceMidiSupport.java | 2150 ++++++++--------- .../java/com/roli/juce/FragmentOverlay.java | 116 +- .../java/com/roli/juce/JuceHTTPStream.java | 814 +++---- .../java/com/roli/juce/ComponentPeerView.java | 986 ++++---- .../java/com/roli/juce/JuceWebView.java | 214 +- .../java/com/roli/juce/JuceOpenGLView.java | 112 +- .../CameraCaptureSessionCaptureCallback.java | 130 +- .../CameraCaptureSessionStateCallback.java | 106 +- .../roli/juce/CameraDeviceStateCallback.java | 85 +- .../juce/JuceOrientationEventListener.java | 48 +- .../roli/juce/MediaControllerCallback.java | 106 +- .../com/roli/juce/MediaSessionCallback.java | 156 +- .../com/roli/juce/SystemVolumeObserver.java | 74 +- 13 files changed, 2548 insertions(+), 2549 deletions(-) diff --git a/modules/juce_audio_devices/native/java/com/roli/juce/JuceMidiSupport.java b/modules/juce_audio_devices/native/java/com/roli/juce/JuceMidiSupport.java index 5aba09c8ca..cfe99180f9 100644 --- a/modules/juce_audio_devices/native/java/com/roli/juce/JuceMidiSupport.java +++ b/modules/juce_audio_devices/native/java/com/roli/juce/JuceMidiSupport.java @@ -1,1075 +1,1075 @@ -package com.roli.juce; - - -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothGatt; -import android.bluetooth.BluetoothGattCallback; -import android.bluetooth.BluetoothGattCharacteristic; -import android.bluetooth.BluetoothGattDescriptor; -import android.bluetooth.BluetoothProfile; -import android.bluetooth.le.BluetoothLeScanner; -import android.bluetooth.le.ScanFilter; -import android.bluetooth.le.ScanResult; -import android.bluetooth.le.ScanSettings; -import android.content.Context; -import android.media.midi.MidiDevice; -import android.media.midi.MidiDeviceInfo; -import android.media.midi.MidiDeviceStatus; -import android.media.midi.MidiInputPort; -import android.media.midi.MidiManager; -import android.bluetooth.le.ScanCallback; -import android.bluetooth.BluetoothDevice; -import android.media.midi.MidiOutputPort; -import android.media.midi.MidiReceiver; -import android.os.ParcelUuid; -import android.util.Log; -import android.util.Pair; - -import java.io.IOException; -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; - -import static android.content.Context.MIDI_SERVICE; - -public class JuceMidiSupport -{ - //============================================================================== - public interface JuceMidiPort - { - boolean isInputPort (); - - // start, stop does nothing on an output port - void start (); - - void stop (); - - void close (); - - // send will do nothing on an input port - void sendMidi (byte[] msg, int offset, int count); - } - - //============================================================================== - public static class BluetoothManager extends ScanCallback - { - BluetoothManager (Context contextToUse) - { - appContext = contextToUse; - } - - public String[] getMidiBluetoothAddresses () - { - return bluetoothMidiDevices.toArray (new String[bluetoothMidiDevices.size ()]); - } - - public String getHumanReadableStringForBluetoothAddress (String address) - { - BluetoothDevice btDevice = BluetoothAdapter.getDefaultAdapter ().getRemoteDevice (address); - return btDevice.getName (); - } - - public int getBluetoothDeviceStatus (String address) - { - return getAndroidMidiDeviceManager (appContext).getBluetoothDeviceStatus (address); - } - - public void startStopScan (boolean shouldStart) - { - BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter (); - - if (bluetoothAdapter == null) - { - Log.d ("JUCE", "BluetoothManager error: could not get default Bluetooth adapter"); - return; - } - - BluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner (); - - if (bluetoothLeScanner == null) - { - Log.d ("JUCE", "BluetoothManager error: could not get Bluetooth LE scanner"); - return; - } - - if (shouldStart) - { - ScanFilter.Builder scanFilterBuilder = new ScanFilter.Builder (); - scanFilterBuilder.setServiceUuid (ParcelUuid.fromString (bluetoothLEMidiServiceUUID)); - - ScanSettings.Builder scanSettingsBuilder = new ScanSettings.Builder (); - scanSettingsBuilder.setCallbackType (ScanSettings.CALLBACK_TYPE_ALL_MATCHES) - .setScanMode (ScanSettings.SCAN_MODE_LOW_POWER) - .setScanMode (ScanSettings.MATCH_MODE_STICKY); - - bluetoothLeScanner.startScan (Arrays.asList (scanFilterBuilder.build ()), - scanSettingsBuilder.build (), - this); - } else - { - bluetoothLeScanner.stopScan (this); - } - } - - public boolean pairBluetoothMidiDevice (String address) - { - BluetoothDevice btDevice = BluetoothAdapter.getDefaultAdapter ().getRemoteDevice (address); - - if (btDevice == null) - { - Log.d ("JUCE", "failed to create buletooth device from address"); - return false; - } - - return getAndroidMidiDeviceManager (appContext).pairBluetoothDevice (btDevice); - } - - public void unpairBluetoothMidiDevice (String address) - { - getAndroidMidiDeviceManager (appContext).unpairBluetoothDevice (address); - } - - public void onScanFailed (int errorCode) - { - } - - public void onScanResult (int callbackType, ScanResult result) - { - if (callbackType == ScanSettings.CALLBACK_TYPE_ALL_MATCHES - || callbackType == ScanSettings.CALLBACK_TYPE_FIRST_MATCH) - { - BluetoothDevice device = result.getDevice (); - - if (device != null) - bluetoothMidiDevices.add (device.getAddress ()); - } - - if (callbackType == ScanSettings.CALLBACK_TYPE_MATCH_LOST) - { - Log.d ("JUCE", "ScanSettings.CALLBACK_TYPE_MATCH_LOST"); - BluetoothDevice device = result.getDevice (); - - if (device != null) - { - bluetoothMidiDevices.remove (device.getAddress ()); - unpairBluetoothMidiDevice (device.getAddress ()); - } - } - } - - public void onBatchScanResults (List results) - { - for (ScanResult result : results) - onScanResult (ScanSettings.CALLBACK_TYPE_ALL_MATCHES, result); - } - - private BluetoothLeScanner scanner; - private static final String bluetoothLEMidiServiceUUID = "03B80E5A-EDE8-4B33-A751-6CE34EC4C700"; - - private HashSet bluetoothMidiDevices = new HashSet (); - private Context appContext = null; - } - - public static class JuceMidiInputPort extends MidiReceiver implements JuceMidiPort - { - private native void handleReceive (long host, byte[] msg, int offset, int count, long timestamp); - - public JuceMidiInputPort (MidiDeviceManager mm, MidiOutputPort actualPort, MidiPortPath portPathToUse, long hostToUse) - { - owner = mm; - androidPort = actualPort; - portPath = portPathToUse; - juceHost = hostToUse; - isConnected = false; - } - - @Override - protected void finalize () throws Throwable - { - close (); - super.finalize (); - } - - @Override - public boolean isInputPort () - { - return true; - } - - @Override - public void start () - { - if (owner != null && androidPort != null && !isConnected) - { - androidPort.connect (this); - isConnected = true; - } - } - - @Override - public void stop () - { - if (owner != null && androidPort != null && isConnected) - { - androidPort.disconnect (this); - isConnected = false; - } - } - - @Override - public void close () - { - if (androidPort != null) - { - try - { - androidPort.close (); - } catch (IOException exception) - { - Log.d ("JUCE", "IO Exception while closing port"); - } - } - - if (owner != null) - owner.removePort (portPath); - - owner = null; - androidPort = null; - } - - @Override - public void onSend (byte[] msg, int offset, int count, long timestamp) - { - if (count > 0) - handleReceive (juceHost, msg, offset, count, timestamp); - } - - @Override - public void onFlush () - {} - - @Override - public void sendMidi (byte[] msg, int offset, int count) - { - } - - MidiDeviceManager owner; - MidiOutputPort androidPort; - MidiPortPath portPath; - long juceHost; - boolean isConnected; - } - - public static class JuceMidiOutputPort implements JuceMidiPort - { - public JuceMidiOutputPort (MidiDeviceManager mm, MidiInputPort actualPort, MidiPortPath portPathToUse) - { - owner = mm; - androidPort = actualPort; - portPath = portPathToUse; - } - - @Override - protected void finalize () throws Throwable - { - close (); - super.finalize (); - } - - @Override - public boolean isInputPort () - { - return false; - } - - @Override - public void start () - { - } - - @Override - public void stop () - { - } - - @Override - public void sendMidi (byte[] msg, int offset, int count) - { - if (androidPort != null) - { - try - { - androidPort.send (msg, offset, count); - } catch (IOException exception) - { - Log.d ("JUCE", "send midi had IO exception"); - } - } - } - - @Override - public void close () - { - if (androidPort != null) - { - try - { - androidPort.close (); - } catch (IOException exception) - { - Log.d ("JUCE", "IO Exception while closing port"); - } - } - - if (owner != null) - owner.removePort (portPath); - - owner = null; - androidPort = null; - } - - MidiDeviceManager owner; - MidiInputPort androidPort; - MidiPortPath portPath; - } - - private static class MidiPortPath extends Object - { - public MidiPortPath (int deviceIdToUse, boolean direction, int androidIndex) - { - deviceId = deviceIdToUse; - isInput = direction; - portIndex = androidIndex; - - } - - public int deviceId; - public int portIndex; - public boolean isInput; - - @Override - public int hashCode () - { - Integer i = new Integer ((deviceId * 128) + (portIndex < 128 ? portIndex : 127)); - return i.hashCode () * (isInput ? -1 : 1); - } - - @Override - public boolean equals (Object obj) - { - if (obj == null) - return false; - - if (getClass () != obj.getClass ()) - return false; - - MidiPortPath other = (MidiPortPath) obj; - return (portIndex == other.portIndex && isInput == other.isInput && deviceId == other.deviceId); - } - } - - //============================================================================== - public static class MidiDeviceManager extends MidiManager.DeviceCallback implements MidiManager.OnDeviceOpenedListener - { - //============================================================================== - private class DummyBluetoothGattCallback extends BluetoothGattCallback - { - public DummyBluetoothGattCallback (MidiDeviceManager mm) - { - super (); - owner = mm; - } - - public void onConnectionStateChange (BluetoothGatt gatt, int status, int newState) - { - if (newState == BluetoothProfile.STATE_CONNECTED) - { - gatt.requestConnectionPriority (BluetoothGatt.CONNECTION_PRIORITY_HIGH); - owner.pairBluetoothDeviceStepTwo (gatt.getDevice ()); - } - } - - 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 MidiDeviceManager owner; - } - - //============================================================================== - private class MidiDeviceOpenTask extends java.util.TimerTask - { - public MidiDeviceOpenTask (MidiDeviceManager deviceManager, MidiDevice device, BluetoothGatt gattToUse) - { - owner = deviceManager; - midiDevice = device; - btGatt = gattToUse; - } - - @Override - public boolean cancel () - { - synchronized (MidiDeviceOpenTask.class) - { - owner = null; - boolean retval = super.cancel (); - - if (btGatt != null) - { - btGatt.disconnect (); - btGatt.close (); - - btGatt = null; - } - - 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 BluetoothGatt getGatt () { return btGatt; } - - 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; - private BluetoothGatt btGatt; - } - - //============================================================================== - public MidiDeviceManager (Context contextToUse) - { - appContext = contextToUse; - manager = (MidiManager) appContext.getSystemService (MIDI_SERVICE); - - if (manager == null) - { - Log.d ("JUCE", "MidiDeviceManager error: could not get MidiManager system service"); - return; - } - - openPorts = new HashMap> (); - midiDevices = new ArrayList> (); - openTasks = new HashMap (); - btDevicesPairing = new HashMap (); - - MidiDeviceInfo[] foundDevices = manager.getDevices (); - for (MidiDeviceInfo info : foundDevices) - onDeviceAdded (info); - - manager.registerDeviceCallback (this, null); - } - - protected void finalize () throws Throwable - { - 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 (); - - openPorts = null; - - for (Pair device : midiDevices) - { - if (device.second != null) - { - device.second.disconnect (); - device.second.close (); - } - - device.first.close (); - } - - midiDevices.clear (); - - super.finalize (); - } - - public String[] getJuceAndroidMidiInputDevices () - { - return getJuceAndroidMidiDevices (MidiDeviceInfo.PortInfo.TYPE_OUTPUT); - } - - public String[] getJuceAndroidMidiOutputDevices () - { - return getJuceAndroidMidiDevices (MidiDeviceInfo.PortInfo.TYPE_INPUT); - } - - private String[] getJuceAndroidMidiDevices (int portType) - { - // only update the list when JUCE asks for a new list - synchronized (MidiDeviceManager.class) - { - deviceInfos = getDeviceInfos (); - } - - ArrayList portNames = new ArrayList (); - - int index = 0; - for (MidiPortPath portInfo = getPortPathForJuceIndex (portType, index); portInfo != null; portInfo = getPortPathForJuceIndex (portType, ++index)) - portNames.add (getPortName (portInfo)); - - String[] names = new String[portNames.size ()]; - return portNames.toArray (names); - } - - private JuceMidiPort openMidiPortWithJuceIndex (int index, long host, boolean isInput) - { - synchronized (MidiDeviceManager.class) - { - int portTypeToFind = (isInput ? MidiDeviceInfo.PortInfo.TYPE_OUTPUT : MidiDeviceInfo.PortInfo.TYPE_INPUT); - MidiPortPath portInfo = getPortPathForJuceIndex (portTypeToFind, index); - - if (portInfo != null) - { - // ports must be opened exclusively! - if (openPorts.containsKey (portInfo)) - return null; - - Pair devicePair = getMidiDevicePairForId (portInfo.deviceId); - - if (devicePair != null) - { - MidiDevice device = devicePair.first; - if (device != null) - { - JuceMidiPort juceMidiPort = null; - - if (isInput) - { - MidiOutputPort outputPort = device.openOutputPort (portInfo.portIndex); - - if (outputPort != null) - juceMidiPort = new JuceMidiInputPort (this, outputPort, portInfo, host); - } else - { - MidiInputPort inputPort = device.openInputPort (portInfo.portIndex); - - if (inputPort != null) - juceMidiPort = new JuceMidiOutputPort (this, inputPort, portInfo); - } - - if (juceMidiPort != null) - { - openPorts.put (portInfo, new WeakReference (juceMidiPort)); - - return juceMidiPort; - } - } - } - } - } - - return null; - } - - public JuceMidiPort openMidiInputPortWithJuceIndex (int index, long host) - { - return openMidiPortWithJuceIndex (index, host, true); - } - - public JuceMidiPort openMidiOutputPortWithJuceIndex (int index) - { - return openMidiPortWithJuceIndex (index, 0, false); - } - - /* 0: unpaired, 1: paired, 2: pairing */ - public int getBluetoothDeviceStatus (String address) - { - synchronized (MidiDeviceManager.class) - { - if (!address.isEmpty ()) - { - if (findMidiDeviceForBluetoothAddress (address) != null) - return 1; - - if (btDevicesPairing.containsKey (address)) - return 2; - - if (findOpenTaskForBluetoothAddress (address) != null) - return 2; - } - } - - return 0; - } - - public boolean pairBluetoothDevice (BluetoothDevice btDevice) - { - String btAddress = btDevice.getAddress (); - if (btAddress.isEmpty ()) - return false; - - synchronized (MidiDeviceManager.class) - { - if (getBluetoothDeviceStatus (btAddress) != 0) - return false; - - - btDevicesPairing.put (btDevice.getAddress (), null); - BluetoothGatt gatt = btDevice.connectGatt (appContext.getApplicationContext (), true, new DummyBluetoothGattCallback (this)); - - if (gatt != null) - { - btDevicesPairing.put (btDevice.getAddress (), gatt); - } else - { - pairBluetoothDeviceStepTwo (btDevice); - } - } - - return true; - } - - public void pairBluetoothDeviceStepTwo (BluetoothDevice btDevice) - { - manager.openBluetoothDevice (btDevice, this, null); - } - - public void unpairBluetoothDevice (String address) - { - if (address.isEmpty ()) - return; - - synchronized (MidiDeviceManager.class) - { - if (btDevicesPairing.containsKey (address)) - { - BluetoothGatt gatt = btDevicesPairing.get (address); - if (gatt != null) - { - gatt.disconnect (); - gatt.close (); - } - - btDevicesPairing.remove (address); - } - - MidiDeviceOpenTask openTask = findOpenTaskForBluetoothAddress (address); - if (openTask != null) - { - int deviceID = openTask.getID (); - openTask.cancel (); - openTasks.remove (deviceID); - } - - Pair midiDevicePair = findMidiDeviceForBluetoothAddress (address); - if (midiDevicePair != null) - { - MidiDevice midiDevice = midiDevicePair.first; - onDeviceRemoved (midiDevice.getInfo ()); - - try - { - midiDevice.close (); - } catch (IOException exception) - { - Log.d ("JUCE", "IOException while closing midi device"); - } - } - } - } - - private Pair findMidiDeviceForBluetoothAddress (String address) - { - for (Pair midiDevice : midiDevices) - { - MidiDeviceInfo info = midiDevice.first.getInfo (); - if (info.getType () == MidiDeviceInfo.TYPE_BLUETOOTH) - { - BluetoothDevice btDevice = (BluetoothDevice) info.getProperties ().get (info.PROPERTY_BLUETOOTH_DEVICE); - if (btDevice != null && btDevice.getAddress ().equals (address)) - return midiDevice; - } - } - - 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); - } - - public String getInputPortNameForJuceIndex (int index) - { - MidiPortPath portInfo = getPortPathForJuceIndex (MidiDeviceInfo.PortInfo.TYPE_OUTPUT, index); - if (portInfo != null) - return getPortName (portInfo); - - return ""; - } - - public String getOutputPortNameForJuceIndex (int index) - { - MidiPortPath portInfo = getPortPathForJuceIndex (MidiDeviceInfo.PortInfo.TYPE_INPUT, index); - if (portInfo != null) - return getPortName (portInfo); - - return ""; - } - - public void onDeviceAdded (MidiDeviceInfo info) - { - // only add standard midi devices - if (info.getType () == info.TYPE_BLUETOOTH) - return; - - manager.openDevice (info, this, null); - } - - public void onDeviceRemoved (MidiDeviceInfo info) - { - synchronized (MidiDeviceManager.class) - { - Pair 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 (gatt != null) - { - gatt.disconnect (); - gatt.close (); - } - - midiDevices.remove (devicePair); - } - } - } - - public void onDeviceStatusChanged (MidiDeviceStatus status) - { - } - - @Override - public void onDeviceOpened (MidiDevice theDevice) - { - synchronized (MidiDeviceManager.class) - { - MidiDeviceInfo info = theDevice.getInfo (); - int deviceID = info.getId (); - BluetoothGatt gatt = null; - boolean isBluetooth = false; - - if (!openTasks.containsKey (deviceID)) - { - if (info.getType () == MidiDeviceInfo.TYPE_BLUETOOTH) - { - isBluetooth = true; - BluetoothDevice btDevice = (BluetoothDevice) info.getProperties ().get (info.PROPERTY_BLUETOOTH_DEVICE); - if (btDevice != null) - { - String btAddress = btDevice.getAddress (); - if (btDevicesPairing.containsKey (btAddress)) - { - gatt = btDevicesPairing.get (btAddress); - btDevicesPairing.remove (btAddress); - } else - { - // unpair was called in the mean time - try - { - Pair midiDevicePair = findMidiDeviceForBluetoothAddress (btDevice.getAddress ()); - if (midiDevicePair != null) - { - gatt = midiDevicePair.second; - - if (gatt != null) - { - gatt.disconnect (); - gatt.close (); - } - } - - theDevice.close (); - } catch (IOException e) - { - } - - return; - } - } - } - - MidiDeviceOpenTask openTask = new MidiDeviceOpenTask (this, theDevice, gatt); - openTasks.put (deviceID, openTask); - - new java.util.Timer ().schedule (openTask, (isBluetooth ? 2000 : 100)); - } - } - } - - public void onDeviceOpenedDelayed (MidiDevice theDevice) - { - synchronized (MidiDeviceManager.class) - { - int deviceID = theDevice.getInfo ().getId (); - - if (openTasks.containsKey (deviceID)) - { - if (!midiDevices.contains (theDevice)) - { - BluetoothGatt gatt = openTasks.get (deviceID).getGatt (); - openTasks.remove (deviceID); - midiDevices.add (new Pair (theDevice, gatt)); - } - } else - { - // 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 midiDevicePair = findMidiDeviceForBluetoothAddress (btDevice.getAddress ()); - if (midiDevicePair != null) - { - BluetoothGatt gatt = midiDevicePair.second; - - if (gatt != null) - { - gatt.disconnect (); - gatt.close (); - } - } - } - - try - { - theDevice.close (); - } catch (IOException e) - { - } - } - } - } - - public String getPortName (MidiPortPath path) - { - int portTypeToFind = (path.isInput ? MidiDeviceInfo.PortInfo.TYPE_INPUT : MidiDeviceInfo.PortInfo.TYPE_OUTPUT); - - synchronized (MidiDeviceManager.class) - { - for (MidiDeviceInfo info : deviceInfos) - { - int localIndex = 0; - if (info.getId () == path.deviceId) - { - for (MidiDeviceInfo.PortInfo portInfo : info.getPorts ()) - { - int portType = portInfo.getType (); - if (portType == portTypeToFind) - { - int portIndex = portInfo.getPortNumber (); - if (portIndex == path.portIndex) - { - String portName = portInfo.getName (); - if (portName.isEmpty ()) - portName = (String) info.getProperties ().get (info.PROPERTY_NAME); - - return portName; - } - } - } - } - } - } - - return ""; - } - - public MidiPortPath getPortPathForJuceIndex (int portType, int juceIndex) - { - int portIdx = 0; - for (MidiDeviceInfo info : deviceInfos) - { - for (MidiDeviceInfo.PortInfo portInfo : info.getPorts ()) - { - if (portInfo.getType () == portType) - { - if (portIdx == juceIndex) - return new MidiPortPath (info.getId (), - (portType == MidiDeviceInfo.PortInfo.TYPE_INPUT), - portInfo.getPortNumber ()); - - portIdx++; - } - } - } - - return null; - } - - private MidiDeviceInfo[] getDeviceInfos () - { - synchronized (MidiDeviceManager.class) - { - MidiDeviceInfo[] infos = new MidiDeviceInfo[midiDevices.size ()]; - - int idx = 0; - for (Pair midiDevice : midiDevices) - infos[idx++] = midiDevice.first.getInfo (); - - return infos; - } - } - - private Pair getMidiDevicePairForId (int deviceId) - { - synchronized (MidiDeviceManager.class) - { - for (Pair midiDevice : midiDevices) - if (midiDevice.first.getInfo ().getId () == deviceId) - return midiDevice; - } - - return null; - } - - private MidiManager manager; - private HashMap btDevicesPairing; - private HashMap openTasks; - private ArrayList> midiDevices; - private MidiDeviceInfo[] deviceInfos; - private HashMap> openPorts; - private Context appContext = null; - } - - public static MidiDeviceManager getAndroidMidiDeviceManager (Context context) - { - if (context.getSystemService (MIDI_SERVICE) == null) - return null; - - synchronized (JuceMidiSupport.class) - { - if (midiDeviceManager == null) - midiDeviceManager = new MidiDeviceManager (context); - } - - return midiDeviceManager; - } - - public static BluetoothManager getAndroidBluetoothManager (Context context) - { - BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter (); - - if (adapter == null) - return null; - - if (adapter.getBluetoothLeScanner () == null) - return null; - - synchronized (JuceMidiSupport.class) - { - if (bluetoothManager == null) - bluetoothManager = new BluetoothManager (context); - } - - return bluetoothManager; - } - - private static MidiDeviceManager midiDeviceManager = null; - private static BluetoothManager bluetoothManager = null; -} \ No newline at end of file +package com.roli.juce; + + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.le.BluetoothLeScanner; +import android.bluetooth.le.ScanFilter; +import android.bluetooth.le.ScanResult; +import android.bluetooth.le.ScanSettings; +import android.content.Context; +import android.media.midi.MidiDevice; +import android.media.midi.MidiDeviceInfo; +import android.media.midi.MidiDeviceStatus; +import android.media.midi.MidiInputPort; +import android.media.midi.MidiManager; +import android.bluetooth.le.ScanCallback; +import android.bluetooth.BluetoothDevice; +import android.media.midi.MidiOutputPort; +import android.media.midi.MidiReceiver; +import android.os.ParcelUuid; +import android.util.Log; +import android.util.Pair; + +import java.io.IOException; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; + +import static android.content.Context.MIDI_SERVICE; + +public class JuceMidiSupport +{ + //============================================================================== + public interface JuceMidiPort + { + boolean isInputPort (); + + // start, stop does nothing on an output port + void start (); + + void stop (); + + void close (); + + // send will do nothing on an input port + void sendMidi (byte[] msg, int offset, int count); + } + + //============================================================================== + public static class BluetoothManager extends ScanCallback + { + BluetoothManager (Context contextToUse) + { + appContext = contextToUse; + } + + public String[] getMidiBluetoothAddresses () + { + return bluetoothMidiDevices.toArray (new String[bluetoothMidiDevices.size ()]); + } + + public String getHumanReadableStringForBluetoothAddress (String address) + { + BluetoothDevice btDevice = BluetoothAdapter.getDefaultAdapter ().getRemoteDevice (address); + return btDevice.getName (); + } + + public int getBluetoothDeviceStatus (String address) + { + return getAndroidMidiDeviceManager (appContext).getBluetoothDeviceStatus (address); + } + + public void startStopScan (boolean shouldStart) + { + BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter (); + + if (bluetoothAdapter == null) + { + Log.d ("JUCE", "BluetoothManager error: could not get default Bluetooth adapter"); + return; + } + + BluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner (); + + if (bluetoothLeScanner == null) + { + Log.d ("JUCE", "BluetoothManager error: could not get Bluetooth LE scanner"); + return; + } + + if (shouldStart) + { + ScanFilter.Builder scanFilterBuilder = new ScanFilter.Builder (); + scanFilterBuilder.setServiceUuid (ParcelUuid.fromString (bluetoothLEMidiServiceUUID)); + + ScanSettings.Builder scanSettingsBuilder = new ScanSettings.Builder (); + scanSettingsBuilder.setCallbackType (ScanSettings.CALLBACK_TYPE_ALL_MATCHES) + .setScanMode (ScanSettings.SCAN_MODE_LOW_POWER) + .setScanMode (ScanSettings.MATCH_MODE_STICKY); + + bluetoothLeScanner.startScan (Arrays.asList (scanFilterBuilder.build ()), + scanSettingsBuilder.build (), + this); + } else + { + bluetoothLeScanner.stopScan (this); + } + } + + public boolean pairBluetoothMidiDevice (String address) + { + BluetoothDevice btDevice = BluetoothAdapter.getDefaultAdapter ().getRemoteDevice (address); + + if (btDevice == null) + { + Log.d ("JUCE", "failed to create buletooth device from address"); + return false; + } + + return getAndroidMidiDeviceManager (appContext).pairBluetoothDevice (btDevice); + } + + public void unpairBluetoothMidiDevice (String address) + { + getAndroidMidiDeviceManager (appContext).unpairBluetoothDevice (address); + } + + public void onScanFailed (int errorCode) + { + } + + public void onScanResult (int callbackType, ScanResult result) + { + if (callbackType == ScanSettings.CALLBACK_TYPE_ALL_MATCHES + || callbackType == ScanSettings.CALLBACK_TYPE_FIRST_MATCH) + { + BluetoothDevice device = result.getDevice (); + + if (device != null) + bluetoothMidiDevices.add (device.getAddress ()); + } + + if (callbackType == ScanSettings.CALLBACK_TYPE_MATCH_LOST) + { + Log.d ("JUCE", "ScanSettings.CALLBACK_TYPE_MATCH_LOST"); + BluetoothDevice device = result.getDevice (); + + if (device != null) + { + bluetoothMidiDevices.remove (device.getAddress ()); + unpairBluetoothMidiDevice (device.getAddress ()); + } + } + } + + public void onBatchScanResults (List results) + { + for (ScanResult result : results) + onScanResult (ScanSettings.CALLBACK_TYPE_ALL_MATCHES, result); + } + + private BluetoothLeScanner scanner; + private static final String bluetoothLEMidiServiceUUID = "03B80E5A-EDE8-4B33-A751-6CE34EC4C700"; + + private HashSet bluetoothMidiDevices = new HashSet (); + private Context appContext = null; + } + + public static class JuceMidiInputPort extends MidiReceiver implements JuceMidiPort + { + private native void handleReceive (long host, byte[] msg, int offset, int count, long timestamp); + + public JuceMidiInputPort (MidiDeviceManager mm, MidiOutputPort actualPort, MidiPortPath portPathToUse, long hostToUse) + { + owner = mm; + androidPort = actualPort; + portPath = portPathToUse; + juceHost = hostToUse; + isConnected = false; + } + + @Override + protected void finalize () throws Throwable + { + close (); + super.finalize (); + } + + @Override + public boolean isInputPort () + { + return true; + } + + @Override + public void start () + { + if (owner != null && androidPort != null && !isConnected) + { + androidPort.connect (this); + isConnected = true; + } + } + + @Override + public void stop () + { + if (owner != null && androidPort != null && isConnected) + { + androidPort.disconnect (this); + isConnected = false; + } + } + + @Override + public void close () + { + if (androidPort != null) + { + try + { + androidPort.close (); + } catch (IOException exception) + { + Log.d ("JUCE", "IO Exception while closing port"); + } + } + + if (owner != null) + owner.removePort (portPath); + + owner = null; + androidPort = null; + } + + @Override + public void onSend (byte[] msg, int offset, int count, long timestamp) + { + if (count > 0) + handleReceive (juceHost, msg, offset, count, timestamp); + } + + @Override + public void onFlush () + {} + + @Override + public void sendMidi (byte[] msg, int offset, int count) + { + } + + MidiDeviceManager owner; + MidiOutputPort androidPort; + MidiPortPath portPath; + long juceHost; + boolean isConnected; + } + + public static class JuceMidiOutputPort implements JuceMidiPort + { + public JuceMidiOutputPort (MidiDeviceManager mm, MidiInputPort actualPort, MidiPortPath portPathToUse) + { + owner = mm; + androidPort = actualPort; + portPath = portPathToUse; + } + + @Override + protected void finalize () throws Throwable + { + close (); + super.finalize (); + } + + @Override + public boolean isInputPort () + { + return false; + } + + @Override + public void start () + { + } + + @Override + public void stop () + { + } + + @Override + public void sendMidi (byte[] msg, int offset, int count) + { + if (androidPort != null) + { + try + { + androidPort.send (msg, offset, count); + } catch (IOException exception) + { + Log.d ("JUCE", "send midi had IO exception"); + } + } + } + + @Override + public void close () + { + if (androidPort != null) + { + try + { + androidPort.close (); + } catch (IOException exception) + { + Log.d ("JUCE", "IO Exception while closing port"); + } + } + + if (owner != null) + owner.removePort (portPath); + + owner = null; + androidPort = null; + } + + MidiDeviceManager owner; + MidiInputPort androidPort; + MidiPortPath portPath; + } + + private static class MidiPortPath extends Object + { + public MidiPortPath (int deviceIdToUse, boolean direction, int androidIndex) + { + deviceId = deviceIdToUse; + isInput = direction; + portIndex = androidIndex; + + } + + public int deviceId; + public int portIndex; + public boolean isInput; + + @Override + public int hashCode () + { + Integer i = new Integer ((deviceId * 128) + (portIndex < 128 ? portIndex : 127)); + return i.hashCode () * (isInput ? -1 : 1); + } + + @Override + public boolean equals (Object obj) + { + if (obj == null) + return false; + + if (getClass () != obj.getClass ()) + return false; + + MidiPortPath other = (MidiPortPath) obj; + return (portIndex == other.portIndex && isInput == other.isInput && deviceId == other.deviceId); + } + } + + //============================================================================== + public static class MidiDeviceManager extends MidiManager.DeviceCallback implements MidiManager.OnDeviceOpenedListener + { + //============================================================================== + private class DummyBluetoothGattCallback extends BluetoothGattCallback + { + public DummyBluetoothGattCallback (MidiDeviceManager mm) + { + super (); + owner = mm; + } + + public void onConnectionStateChange (BluetoothGatt gatt, int status, int newState) + { + if (newState == BluetoothProfile.STATE_CONNECTED) + { + gatt.requestConnectionPriority (BluetoothGatt.CONNECTION_PRIORITY_HIGH); + owner.pairBluetoothDeviceStepTwo (gatt.getDevice ()); + } + } + + 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 MidiDeviceManager owner; + } + + //============================================================================== + private class MidiDeviceOpenTask extends java.util.TimerTask + { + public MidiDeviceOpenTask (MidiDeviceManager deviceManager, MidiDevice device, BluetoothGatt gattToUse) + { + owner = deviceManager; + midiDevice = device; + btGatt = gattToUse; + } + + @Override + public boolean cancel () + { + synchronized (MidiDeviceOpenTask.class) + { + owner = null; + boolean retval = super.cancel (); + + if (btGatt != null) + { + btGatt.disconnect (); + btGatt.close (); + + btGatt = null; + } + + 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 BluetoothGatt getGatt () { return btGatt; } + + 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; + private BluetoothGatt btGatt; + } + + //============================================================================== + public MidiDeviceManager (Context contextToUse) + { + appContext = contextToUse; + manager = (MidiManager) appContext.getSystemService (MIDI_SERVICE); + + if (manager == null) + { + Log.d ("JUCE", "MidiDeviceManager error: could not get MidiManager system service"); + return; + } + + openPorts = new HashMap> (); + midiDevices = new ArrayList> (); + openTasks = new HashMap (); + btDevicesPairing = new HashMap (); + + MidiDeviceInfo[] foundDevices = manager.getDevices (); + for (MidiDeviceInfo info : foundDevices) + onDeviceAdded (info); + + manager.registerDeviceCallback (this, null); + } + + protected void finalize () throws Throwable + { + 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 (); + + openPorts = null; + + for (Pair device : midiDevices) + { + if (device.second != null) + { + device.second.disconnect (); + device.second.close (); + } + + device.first.close (); + } + + midiDevices.clear (); + + super.finalize (); + } + + public String[] getJuceAndroidMidiInputDevices () + { + return getJuceAndroidMidiDevices (MidiDeviceInfo.PortInfo.TYPE_OUTPUT); + } + + public String[] getJuceAndroidMidiOutputDevices () + { + return getJuceAndroidMidiDevices (MidiDeviceInfo.PortInfo.TYPE_INPUT); + } + + private String[] getJuceAndroidMidiDevices (int portType) + { + // only update the list when JUCE asks for a new list + synchronized (MidiDeviceManager.class) + { + deviceInfos = getDeviceInfos (); + } + + ArrayList portNames = new ArrayList (); + + int index = 0; + for (MidiPortPath portInfo = getPortPathForJuceIndex (portType, index); portInfo != null; portInfo = getPortPathForJuceIndex (portType, ++index)) + portNames.add (getPortName (portInfo)); + + String[] names = new String[portNames.size ()]; + return portNames.toArray (names); + } + + private JuceMidiPort openMidiPortWithJuceIndex (int index, long host, boolean isInput) + { + synchronized (MidiDeviceManager.class) + { + int portTypeToFind = (isInput ? MidiDeviceInfo.PortInfo.TYPE_OUTPUT : MidiDeviceInfo.PortInfo.TYPE_INPUT); + MidiPortPath portInfo = getPortPathForJuceIndex (portTypeToFind, index); + + if (portInfo != null) + { + // ports must be opened exclusively! + if (openPorts.containsKey (portInfo)) + return null; + + Pair devicePair = getMidiDevicePairForId (portInfo.deviceId); + + if (devicePair != null) + { + MidiDevice device = devicePair.first; + if (device != null) + { + JuceMidiPort juceMidiPort = null; + + if (isInput) + { + MidiOutputPort outputPort = device.openOutputPort (portInfo.portIndex); + + if (outputPort != null) + juceMidiPort = new JuceMidiInputPort (this, outputPort, portInfo, host); + } else + { + MidiInputPort inputPort = device.openInputPort (portInfo.portIndex); + + if (inputPort != null) + juceMidiPort = new JuceMidiOutputPort (this, inputPort, portInfo); + } + + if (juceMidiPort != null) + { + openPorts.put (portInfo, new WeakReference (juceMidiPort)); + + return juceMidiPort; + } + } + } + } + } + + return null; + } + + public JuceMidiPort openMidiInputPortWithJuceIndex (int index, long host) + { + return openMidiPortWithJuceIndex (index, host, true); + } + + public JuceMidiPort openMidiOutputPortWithJuceIndex (int index) + { + return openMidiPortWithJuceIndex (index, 0, false); + } + + /* 0: unpaired, 1: paired, 2: pairing */ + public int getBluetoothDeviceStatus (String address) + { + synchronized (MidiDeviceManager.class) + { + if (!address.isEmpty ()) + { + if (findMidiDeviceForBluetoothAddress (address) != null) + return 1; + + if (btDevicesPairing.containsKey (address)) + return 2; + + if (findOpenTaskForBluetoothAddress (address) != null) + return 2; + } + } + + return 0; + } + + public boolean pairBluetoothDevice (BluetoothDevice btDevice) + { + String btAddress = btDevice.getAddress (); + if (btAddress.isEmpty ()) + return false; + + synchronized (MidiDeviceManager.class) + { + if (getBluetoothDeviceStatus (btAddress) != 0) + return false; + + + btDevicesPairing.put (btDevice.getAddress (), null); + BluetoothGatt gatt = btDevice.connectGatt (appContext.getApplicationContext (), true, new DummyBluetoothGattCallback (this)); + + if (gatt != null) + { + btDevicesPairing.put (btDevice.getAddress (), gatt); + } else + { + pairBluetoothDeviceStepTwo (btDevice); + } + } + + return true; + } + + public void pairBluetoothDeviceStepTwo (BluetoothDevice btDevice) + { + manager.openBluetoothDevice (btDevice, this, null); + } + + public void unpairBluetoothDevice (String address) + { + if (address.isEmpty ()) + return; + + synchronized (MidiDeviceManager.class) + { + if (btDevicesPairing.containsKey (address)) + { + BluetoothGatt gatt = btDevicesPairing.get (address); + if (gatt != null) + { + gatt.disconnect (); + gatt.close (); + } + + btDevicesPairing.remove (address); + } + + MidiDeviceOpenTask openTask = findOpenTaskForBluetoothAddress (address); + if (openTask != null) + { + int deviceID = openTask.getID (); + openTask.cancel (); + openTasks.remove (deviceID); + } + + Pair midiDevicePair = findMidiDeviceForBluetoothAddress (address); + if (midiDevicePair != null) + { + MidiDevice midiDevice = midiDevicePair.first; + onDeviceRemoved (midiDevice.getInfo ()); + + try + { + midiDevice.close (); + } catch (IOException exception) + { + Log.d ("JUCE", "IOException while closing midi device"); + } + } + } + } + + private Pair findMidiDeviceForBluetoothAddress (String address) + { + for (Pair midiDevice : midiDevices) + { + MidiDeviceInfo info = midiDevice.first.getInfo (); + if (info.getType () == MidiDeviceInfo.TYPE_BLUETOOTH) + { + BluetoothDevice btDevice = (BluetoothDevice) info.getProperties ().get (info.PROPERTY_BLUETOOTH_DEVICE); + if (btDevice != null && btDevice.getAddress ().equals (address)) + return midiDevice; + } + } + + 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); + } + + public String getInputPortNameForJuceIndex (int index) + { + MidiPortPath portInfo = getPortPathForJuceIndex (MidiDeviceInfo.PortInfo.TYPE_OUTPUT, index); + if (portInfo != null) + return getPortName (portInfo); + + return ""; + } + + public String getOutputPortNameForJuceIndex (int index) + { + MidiPortPath portInfo = getPortPathForJuceIndex (MidiDeviceInfo.PortInfo.TYPE_INPUT, index); + if (portInfo != null) + return getPortName (portInfo); + + return ""; + } + + public void onDeviceAdded (MidiDeviceInfo info) + { + // only add standard midi devices + if (info.getType () == info.TYPE_BLUETOOTH) + return; + + manager.openDevice (info, this, null); + } + + public void onDeviceRemoved (MidiDeviceInfo info) + { + synchronized (MidiDeviceManager.class) + { + Pair 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 (gatt != null) + { + gatt.disconnect (); + gatt.close (); + } + + midiDevices.remove (devicePair); + } + } + } + + public void onDeviceStatusChanged (MidiDeviceStatus status) + { + } + + @Override + public void onDeviceOpened (MidiDevice theDevice) + { + synchronized (MidiDeviceManager.class) + { + MidiDeviceInfo info = theDevice.getInfo (); + int deviceID = info.getId (); + BluetoothGatt gatt = null; + boolean isBluetooth = false; + + if (!openTasks.containsKey (deviceID)) + { + if (info.getType () == MidiDeviceInfo.TYPE_BLUETOOTH) + { + isBluetooth = true; + BluetoothDevice btDevice = (BluetoothDevice) info.getProperties ().get (info.PROPERTY_BLUETOOTH_DEVICE); + if (btDevice != null) + { + String btAddress = btDevice.getAddress (); + if (btDevicesPairing.containsKey (btAddress)) + { + gatt = btDevicesPairing.get (btAddress); + btDevicesPairing.remove (btAddress); + } else + { + // unpair was called in the mean time + try + { + Pair midiDevicePair = findMidiDeviceForBluetoothAddress (btDevice.getAddress ()); + if (midiDevicePair != null) + { + gatt = midiDevicePair.second; + + if (gatt != null) + { + gatt.disconnect (); + gatt.close (); + } + } + + theDevice.close (); + } catch (IOException e) + { + } + + return; + } + } + } + + MidiDeviceOpenTask openTask = new MidiDeviceOpenTask (this, theDevice, gatt); + openTasks.put (deviceID, openTask); + + new java.util.Timer ().schedule (openTask, (isBluetooth ? 2000 : 100)); + } + } + } + + public void onDeviceOpenedDelayed (MidiDevice theDevice) + { + synchronized (MidiDeviceManager.class) + { + int deviceID = theDevice.getInfo ().getId (); + + if (openTasks.containsKey (deviceID)) + { + if (!midiDevices.contains (theDevice)) + { + BluetoothGatt gatt = openTasks.get (deviceID).getGatt (); + openTasks.remove (deviceID); + midiDevices.add (new Pair (theDevice, gatt)); + } + } else + { + // 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 midiDevicePair = findMidiDeviceForBluetoothAddress (btDevice.getAddress ()); + if (midiDevicePair != null) + { + BluetoothGatt gatt = midiDevicePair.second; + + if (gatt != null) + { + gatt.disconnect (); + gatt.close (); + } + } + } + + try + { + theDevice.close (); + } catch (IOException e) + { + } + } + } + } + + public String getPortName (MidiPortPath path) + { + int portTypeToFind = (path.isInput ? MidiDeviceInfo.PortInfo.TYPE_INPUT : MidiDeviceInfo.PortInfo.TYPE_OUTPUT); + + synchronized (MidiDeviceManager.class) + { + for (MidiDeviceInfo info : deviceInfos) + { + int localIndex = 0; + if (info.getId () == path.deviceId) + { + for (MidiDeviceInfo.PortInfo portInfo : info.getPorts ()) + { + int portType = portInfo.getType (); + if (portType == portTypeToFind) + { + int portIndex = portInfo.getPortNumber (); + if (portIndex == path.portIndex) + { + String portName = portInfo.getName (); + if (portName.isEmpty ()) + portName = (String) info.getProperties ().get (info.PROPERTY_NAME); + + return portName; + } + } + } + } + } + } + + return ""; + } + + public MidiPortPath getPortPathForJuceIndex (int portType, int juceIndex) + { + int portIdx = 0; + for (MidiDeviceInfo info : deviceInfos) + { + for (MidiDeviceInfo.PortInfo portInfo : info.getPorts ()) + { + if (portInfo.getType () == portType) + { + if (portIdx == juceIndex) + return new MidiPortPath (info.getId (), + (portType == MidiDeviceInfo.PortInfo.TYPE_INPUT), + portInfo.getPortNumber ()); + + portIdx++; + } + } + } + + return null; + } + + private MidiDeviceInfo[] getDeviceInfos () + { + synchronized (MidiDeviceManager.class) + { + MidiDeviceInfo[] infos = new MidiDeviceInfo[midiDevices.size ()]; + + int idx = 0; + for (Pair midiDevice : midiDevices) + infos[idx++] = midiDevice.first.getInfo (); + + return infos; + } + } + + private Pair getMidiDevicePairForId (int deviceId) + { + synchronized (MidiDeviceManager.class) + { + for (Pair midiDevice : midiDevices) + if (midiDevice.first.getInfo ().getId () == deviceId) + return midiDevice; + } + + return null; + } + + private MidiManager manager; + private HashMap btDevicesPairing; + private HashMap openTasks; + private ArrayList> midiDevices; + private MidiDeviceInfo[] deviceInfos; + private HashMap> openPorts; + private Context appContext = null; + } + + public static MidiDeviceManager getAndroidMidiDeviceManager (Context context) + { + if (context.getSystemService (MIDI_SERVICE) == null) + return null; + + synchronized (JuceMidiSupport.class) + { + if (midiDeviceManager == null) + midiDeviceManager = new MidiDeviceManager (context); + } + + return midiDeviceManager; + } + + public static BluetoothManager getAndroidBluetoothManager (Context context) + { + BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter (); + + if (adapter == null) + return null; + + if (adapter.getBluetoothLeScanner () == null) + return null; + + synchronized (JuceMidiSupport.class) + { + if (bluetoothManager == null) + bluetoothManager = new BluetoothManager (context); + } + + return bluetoothManager; + } + + private static MidiDeviceManager midiDeviceManager = null; + private static BluetoothManager bluetoothManager = null; +} diff --git a/modules/juce_core/native/java/com/roli/juce/FragmentOverlay.java b/modules/juce_core/native/java/com/roli/juce/FragmentOverlay.java index 0e96761949..4b4a419197 100644 --- a/modules/juce_core/native/java/com/roli/juce/FragmentOverlay.java +++ b/modules/juce_core/native/java/com/roli/juce/FragmentOverlay.java @@ -1,58 +1,58 @@ -package com.roli.juce; - -import android.app.DialogFragment; -import android.content.Intent; -import android.os.Bundle; - -public class FragmentOverlay extends DialogFragment -{ - @Override - public void onCreate (Bundle state) - { - super.onCreate (state); - cppThis = getArguments ().getLong ("cppThis"); - - if (cppThis != 0) - onCreateNative (cppThis, state); - } - - @Override - public void onStart () - { - super.onStart (); - - if (cppThis != 0) - onStartNative (cppThis); - } - - public void onRequestPermissionsResult (int requestCode, - String[] permissions, - int[] grantResults) - { - if (cppThis != 0) - onRequestPermissionsResultNative (cppThis, requestCode, - permissions, grantResults); - } - - @Override - public void onActivityResult (int requestCode, int resultCode, Intent data) - { - if (cppThis != 0) - onActivityResultNative (cppThis, requestCode, resultCode, data); - } - - public void close () - { - cppThis = 0; - dismiss (); - } - - //============================================================================== - private long cppThis = 0; - - private native void onActivityResultNative (long myself, int requestCode, int resultCode, Intent data); - private native void onCreateNative (long myself, Bundle state); - private native void onStartNative (long myself); - private native void onRequestPermissionsResultNative (long myself, int requestCode, - String[] permissions, int[] grantResults); -} +package com.roli.juce; + +import android.app.DialogFragment; +import android.content.Intent; +import android.os.Bundle; + +public class FragmentOverlay extends DialogFragment +{ + @Override + public void onCreate (Bundle state) + { + super.onCreate (state); + cppThis = getArguments ().getLong ("cppThis"); + + if (cppThis != 0) + onCreateNative (cppThis, state); + } + + @Override + public void onStart () + { + super.onStart (); + + if (cppThis != 0) + onStartNative (cppThis); + } + + public void onRequestPermissionsResult (int requestCode, + String[] permissions, + int[] grantResults) + { + if (cppThis != 0) + onRequestPermissionsResultNative (cppThis, requestCode, + permissions, grantResults); + } + + @Override + public void onActivityResult (int requestCode, int resultCode, Intent data) + { + if (cppThis != 0) + onActivityResultNative (cppThis, requestCode, resultCode, data); + } + + public void close () + { + cppThis = 0; + dismiss (); + } + + //============================================================================== + private long cppThis = 0; + + private native void onActivityResultNative (long myself, int requestCode, int resultCode, Intent data); + private native void onCreateNative (long myself, Bundle state); + private native void onStartNative (long myself); + private native void onRequestPermissionsResultNative (long myself, int requestCode, + String[] permissions, int[] grantResults); +} diff --git a/modules/juce_core/native/java/com/roli/juce/JuceHTTPStream.java b/modules/juce_core/native/java/com/roli/juce/JuceHTTPStream.java index ee4302b5d1..887a66c2a9 100644 --- a/modules/juce_core/native/java/com/roli/juce/JuceHTTPStream.java +++ b/modules/juce_core/native/java/com/roli/juce/JuceHTTPStream.java @@ -1,407 +1,407 @@ -package com.roli.juce; - -import java.lang.Runnable; -import java.io.*; -import java.net.URL; -import java.net.HttpURLConnection; -import java.util.concurrent.CancellationException; -import java.util.concurrent.Future; -import java.util.concurrent.Executors; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Callable; -import java.util.concurrent.locks.ReentrantLock; -import java.util.concurrent.atomic.*; - -public class JuceHTTPStream -{ - public JuceHTTPStream(String address, boolean isPostToUse, byte[] postDataToUse, - String headersToUse, int timeOutMsToUse, - int[] statusCodeToUse, StringBuffer responseHeadersToUse, - int numRedirectsToFollowToUse, String httpRequestCmdToUse) throws IOException - { - isPost = isPostToUse; - postData = postDataToUse; - headers = headersToUse; - timeOutMs = timeOutMsToUse; - statusCode = statusCodeToUse; - responseHeaders = responseHeadersToUse; - totalLength = -1; - numRedirectsToFollow = numRedirectsToFollowToUse; - httpRequestCmd = httpRequestCmdToUse; - - connection = createConnection(address, isPost, postData, headers, timeOutMs, httpRequestCmd); - } - - public static final JuceHTTPStream createHTTPStream(String address, boolean isPost, byte[] postData, - String headers, int timeOutMs, int[] statusCode, - StringBuffer responseHeaders, int numRedirectsToFollow, - String httpRequestCmd) - { - // timeout parameter of zero for HttpUrlConnection is a blocking connect (negative value for juce::URL) - if (timeOutMs < 0) - timeOutMs = 0; - else if (timeOutMs == 0) - timeOutMs = 30000; - - for (; ; ) - { - try - { - JuceHTTPStream httpStream = new JuceHTTPStream(address, isPost, postData, headers, - timeOutMs, statusCode, responseHeaders, - numRedirectsToFollow, httpRequestCmd); - - return httpStream; - } catch (Throwable e) - { - } - - return null; - } - } - - private final HttpURLConnection createConnection(String address, boolean isPost, byte[] postData, - String headers, int timeOutMs, String httpRequestCmdToUse) throws IOException - { - HttpURLConnection newConnection = (HttpURLConnection) (new URL(address).openConnection()); - - try - { - newConnection.setInstanceFollowRedirects(false); - newConnection.setConnectTimeout(timeOutMs); - newConnection.setReadTimeout(timeOutMs); - - // headers - if not empty, this string is appended onto the headers that are used for the request. It must therefore be a valid set of HTML header directives, separated by newlines. - // So convert headers string to an array, with an element for each line - String headerLines[] = headers.split("\\n"); - - // Set request headers - for (int i = 0; i < headerLines.length; ++i) - { - int pos = headerLines[i].indexOf(":"); - - if (pos > 0 && pos < headerLines[i].length()) - { - String field = headerLines[i].substring(0, pos); - String value = headerLines[i].substring(pos + 1); - - if (value.length() > 0) - newConnection.setRequestProperty(field, value); - } - } - - newConnection.setRequestMethod(httpRequestCmd); - - if (isPost) - { - newConnection.setDoOutput(true); - - if (postData != null) - { - OutputStream out = newConnection.getOutputStream(); - out.write(postData); - out.flush(); - } - } - - return newConnection; - } catch (Throwable e) - { - newConnection.disconnect(); - throw new IOException("Connection error"); - } - } - - private final InputStream getCancellableStream(final boolean isInput) throws ExecutionException - { - synchronized (createFutureLock) - { - if (hasBeenCancelled.get()) - return null; - - streamFuture = executor.submit(new Callable() - { - @Override - public BufferedInputStream call() throws IOException - { - return new BufferedInputStream(isInput ? connection.getInputStream() - : connection.getErrorStream()); - } - }); - } - - try - { - return streamFuture.get(); - } catch (InterruptedException e) - { - return null; - } catch (CancellationException e) - { - return null; - } - } - - public final boolean connect() - { - boolean result = false; - int numFollowedRedirects = 0; - - while (true) - { - result = doConnect(); - - if (!result) - return false; - - if (++numFollowedRedirects > numRedirectsToFollow) - break; - - int status = statusCode[0]; - - if (status == 301 || status == 302 || status == 303 || status == 307) - { - // Assumes only one occurrence of "Location" - int pos1 = responseHeaders.indexOf("Location:") + 10; - int pos2 = responseHeaders.indexOf("\n", pos1); - - if (pos2 > pos1) - { - String currentLocation = connection.getURL().toString(); - String newLocation = responseHeaders.substring(pos1, pos2); - - try - { - // Handle newLocation whether it's absolute or relative - URL baseUrl = new URL(currentLocation); - URL newUrl = new URL(baseUrl, newLocation); - String transformedNewLocation = newUrl.toString(); - - if (transformedNewLocation != currentLocation) - { - // Clear responseHeaders before next iteration - responseHeaders.delete(0, responseHeaders.length()); - - synchronized (createStreamLock) - { - if (hasBeenCancelled.get()) - return false; - - connection.disconnect(); - - try - { - connection = createConnection(transformedNewLocation, isPost, - postData, headers, timeOutMs, - httpRequestCmd); - } catch (Throwable e) - { - return false; - } - } - } else - { - break; - } - } catch (Throwable e) - { - return false; - } - } else - { - break; - } - } else - { - break; - } - } - - return result; - } - - private final boolean doConnect() - { - synchronized (createStreamLock) - { - if (hasBeenCancelled.get()) - return false; - - try - { - try - { - inputStream = getCancellableStream(true); - } catch (ExecutionException e) - { - if (connection.getResponseCode() < 400) - { - statusCode[0] = connection.getResponseCode(); - connection.disconnect(); - return false; - } - } finally - { - statusCode[0] = connection.getResponseCode(); - } - - try - { - if (statusCode[0] >= 400) - inputStream = getCancellableStream(false); - else - inputStream = getCancellableStream(true); - } catch (ExecutionException e) - { - } - - for (java.util.Map.Entry> entry : connection.getHeaderFields().entrySet()) - { - if (entry.getKey() != null && entry.getValue() != null) - { - responseHeaders.append(entry.getKey() + ": " - + android.text.TextUtils.join(",", entry.getValue()) + "\n"); - - if (entry.getKey().compareTo("Content-Length") == 0) - totalLength = Integer.decode(entry.getValue().get(0)); - } - } - - return true; - } catch (IOException e) - { - return false; - } - } - } - - static class DisconnectionRunnable implements Runnable - { - public DisconnectionRunnable(HttpURLConnection theConnection, - InputStream theInputStream, - ReentrantLock theCreateStreamLock, - Object theCreateFutureLock, - Future theStreamFuture) - { - connectionToDisconnect = theConnection; - inputStream = theInputStream; - createStreamLock = theCreateStreamLock; - createFutureLock = theCreateFutureLock; - streamFuture = theStreamFuture; - } - - public void run() - { - try - { - if (!createStreamLock.tryLock()) - { - synchronized (createFutureLock) - { - if (streamFuture != null) - streamFuture.cancel(true); - } - - createStreamLock.lock(); - } - - if (connectionToDisconnect != null) - connectionToDisconnect.disconnect(); - - if (inputStream != null) - inputStream.close(); - } catch (IOException e) - { - } finally - { - createStreamLock.unlock(); - } - } - - private HttpURLConnection connectionToDisconnect; - private InputStream inputStream; - private ReentrantLock createStreamLock; - private Object createFutureLock; - Future streamFuture; - } - - public final void release() - { - DisconnectionRunnable disconnectionRunnable = new DisconnectionRunnable(connection, - inputStream, - createStreamLock, - createFutureLock, - streamFuture); - - synchronized (createStreamLock) - { - hasBeenCancelled.set(true); - - connection = null; - } - - Thread disconnectionThread = new Thread(disconnectionRunnable); - disconnectionThread.start(); - } - - public final int read(byte[] buffer, int numBytes) - { - int num = 0; - - try - { - synchronized (createStreamLock) - { - if (inputStream != null) - num = inputStream.read(buffer, 0, numBytes); - } - } catch (IOException e) - { - } - - if (num > 0) - position += num; - - return num; - } - - public final long getPosition() - { - return position; - } - - public final long getTotalLength() - { - return totalLength; - } - - public final boolean isExhausted() - { - return false; - } - - public final boolean setPosition(long newPos) - { - return false; - } - - private boolean isPost; - private byte[] postData; - private String headers; - private int timeOutMs; - String httpRequestCmd; - private HttpURLConnection connection; - private int[] statusCode; - private StringBuffer responseHeaders; - private int totalLength; - private int numRedirectsToFollow; - private InputStream inputStream; - private long position; - private final ReentrantLock createStreamLock = new ReentrantLock(); - private final Object createFutureLock = new Object(); - private AtomicBoolean hasBeenCancelled = new AtomicBoolean(); - - private final ExecutorService executor = Executors.newCachedThreadPool(Executors.defaultThreadFactory()); - Future streamFuture; -} \ No newline at end of file +package com.roli.juce; + +import java.lang.Runnable; +import java.io.*; +import java.net.URL; +import java.net.HttpURLConnection; +import java.util.concurrent.CancellationException; +import java.util.concurrent.Future; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Callable; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.atomic.*; + +public class JuceHTTPStream +{ + public JuceHTTPStream(String address, boolean isPostToUse, byte[] postDataToUse, + String headersToUse, int timeOutMsToUse, + int[] statusCodeToUse, StringBuffer responseHeadersToUse, + int numRedirectsToFollowToUse, String httpRequestCmdToUse) throws IOException + { + isPost = isPostToUse; + postData = postDataToUse; + headers = headersToUse; + timeOutMs = timeOutMsToUse; + statusCode = statusCodeToUse; + responseHeaders = responseHeadersToUse; + totalLength = -1; + numRedirectsToFollow = numRedirectsToFollowToUse; + httpRequestCmd = httpRequestCmdToUse; + + connection = createConnection(address, isPost, postData, headers, timeOutMs, httpRequestCmd); + } + + public static final JuceHTTPStream createHTTPStream(String address, boolean isPost, byte[] postData, + String headers, int timeOutMs, int[] statusCode, + StringBuffer responseHeaders, int numRedirectsToFollow, + String httpRequestCmd) + { + // timeout parameter of zero for HttpUrlConnection is a blocking connect (negative value for juce::URL) + if (timeOutMs < 0) + timeOutMs = 0; + else if (timeOutMs == 0) + timeOutMs = 30000; + + for (; ; ) + { + try + { + JuceHTTPStream httpStream = new JuceHTTPStream(address, isPost, postData, headers, + timeOutMs, statusCode, responseHeaders, + numRedirectsToFollow, httpRequestCmd); + + return httpStream; + } catch (Throwable e) + { + } + + return null; + } + } + + private final HttpURLConnection createConnection(String address, boolean isPost, byte[] postData, + String headers, int timeOutMs, String httpRequestCmdToUse) throws IOException + { + HttpURLConnection newConnection = (HttpURLConnection) (new URL(address).openConnection()); + + try + { + newConnection.setInstanceFollowRedirects(false); + newConnection.setConnectTimeout(timeOutMs); + newConnection.setReadTimeout(timeOutMs); + + // headers - if not empty, this string is appended onto the headers that are used for the request. It must therefore be a valid set of HTML header directives, separated by newlines. + // So convert headers string to an array, with an element for each line + String headerLines[] = headers.split("\\n"); + + // Set request headers + for (int i = 0; i < headerLines.length; ++i) + { + int pos = headerLines[i].indexOf(":"); + + if (pos > 0 && pos < headerLines[i].length()) + { + String field = headerLines[i].substring(0, pos); + String value = headerLines[i].substring(pos + 1); + + if (value.length() > 0) + newConnection.setRequestProperty(field, value); + } + } + + newConnection.setRequestMethod(httpRequestCmd); + + if (isPost) + { + newConnection.setDoOutput(true); + + if (postData != null) + { + OutputStream out = newConnection.getOutputStream(); + out.write(postData); + out.flush(); + } + } + + return newConnection; + } catch (Throwable e) + { + newConnection.disconnect(); + throw new IOException("Connection error"); + } + } + + private final InputStream getCancellableStream(final boolean isInput) throws ExecutionException + { + synchronized (createFutureLock) + { + if (hasBeenCancelled.get()) + return null; + + streamFuture = executor.submit(new Callable() + { + @Override + public BufferedInputStream call() throws IOException + { + return new BufferedInputStream(isInput ? connection.getInputStream() + : connection.getErrorStream()); + } + }); + } + + try + { + return streamFuture.get(); + } catch (InterruptedException e) + { + return null; + } catch (CancellationException e) + { + return null; + } + } + + public final boolean connect() + { + boolean result = false; + int numFollowedRedirects = 0; + + while (true) + { + result = doConnect(); + + if (!result) + return false; + + if (++numFollowedRedirects > numRedirectsToFollow) + break; + + int status = statusCode[0]; + + if (status == 301 || status == 302 || status == 303 || status == 307) + { + // Assumes only one occurrence of "Location" + int pos1 = responseHeaders.indexOf("Location:") + 10; + int pos2 = responseHeaders.indexOf("\n", pos1); + + if (pos2 > pos1) + { + String currentLocation = connection.getURL().toString(); + String newLocation = responseHeaders.substring(pos1, pos2); + + try + { + // Handle newLocation whether it's absolute or relative + URL baseUrl = new URL(currentLocation); + URL newUrl = new URL(baseUrl, newLocation); + String transformedNewLocation = newUrl.toString(); + + if (transformedNewLocation != currentLocation) + { + // Clear responseHeaders before next iteration + responseHeaders.delete(0, responseHeaders.length()); + + synchronized (createStreamLock) + { + if (hasBeenCancelled.get()) + return false; + + connection.disconnect(); + + try + { + connection = createConnection(transformedNewLocation, isPost, + postData, headers, timeOutMs, + httpRequestCmd); + } catch (Throwable e) + { + return false; + } + } + } else + { + break; + } + } catch (Throwable e) + { + return false; + } + } else + { + break; + } + } else + { + break; + } + } + + return result; + } + + private final boolean doConnect() + { + synchronized (createStreamLock) + { + if (hasBeenCancelled.get()) + return false; + + try + { + try + { + inputStream = getCancellableStream(true); + } catch (ExecutionException e) + { + if (connection.getResponseCode() < 400) + { + statusCode[0] = connection.getResponseCode(); + connection.disconnect(); + return false; + } + } finally + { + statusCode[0] = connection.getResponseCode(); + } + + try + { + if (statusCode[0] >= 400) + inputStream = getCancellableStream(false); + else + inputStream = getCancellableStream(true); + } catch (ExecutionException e) + { + } + + for (java.util.Map.Entry> entry : connection.getHeaderFields().entrySet()) + { + if (entry.getKey() != null && entry.getValue() != null) + { + responseHeaders.append(entry.getKey() + ": " + + android.text.TextUtils.join(",", entry.getValue()) + "\n"); + + if (entry.getKey().compareTo("Content-Length") == 0) + totalLength = Integer.decode(entry.getValue().get(0)); + } + } + + return true; + } catch (IOException e) + { + return false; + } + } + } + + static class DisconnectionRunnable implements Runnable + { + public DisconnectionRunnable(HttpURLConnection theConnection, + InputStream theInputStream, + ReentrantLock theCreateStreamLock, + Object theCreateFutureLock, + Future theStreamFuture) + { + connectionToDisconnect = theConnection; + inputStream = theInputStream; + createStreamLock = theCreateStreamLock; + createFutureLock = theCreateFutureLock; + streamFuture = theStreamFuture; + } + + public void run() + { + try + { + if (!createStreamLock.tryLock()) + { + synchronized (createFutureLock) + { + if (streamFuture != null) + streamFuture.cancel(true); + } + + createStreamLock.lock(); + } + + if (connectionToDisconnect != null) + connectionToDisconnect.disconnect(); + + if (inputStream != null) + inputStream.close(); + } catch (IOException e) + { + } finally + { + createStreamLock.unlock(); + } + } + + private HttpURLConnection connectionToDisconnect; + private InputStream inputStream; + private ReentrantLock createStreamLock; + private Object createFutureLock; + Future streamFuture; + } + + public final void release() + { + DisconnectionRunnable disconnectionRunnable = new DisconnectionRunnable(connection, + inputStream, + createStreamLock, + createFutureLock, + streamFuture); + + synchronized (createStreamLock) + { + hasBeenCancelled.set(true); + + connection = null; + } + + Thread disconnectionThread = new Thread(disconnectionRunnable); + disconnectionThread.start(); + } + + public final int read(byte[] buffer, int numBytes) + { + int num = 0; + + try + { + synchronized (createStreamLock) + { + if (inputStream != null) + num = inputStream.read(buffer, 0, numBytes); + } + } catch (IOException e) + { + } + + if (num > 0) + position += num; + + return num; + } + + public final long getPosition() + { + return position; + } + + public final long getTotalLength() + { + return totalLength; + } + + public final boolean isExhausted() + { + return false; + } + + public final boolean setPosition(long newPos) + { + return false; + } + + private boolean isPost; + private byte[] postData; + private String headers; + private int timeOutMs; + String httpRequestCmd; + private HttpURLConnection connection; + private int[] statusCode; + private StringBuffer responseHeaders; + private int totalLength; + private int numRedirectsToFollow; + private InputStream inputStream; + private long position; + private final ReentrantLock createStreamLock = new ReentrantLock(); + private final Object createFutureLock = new Object(); + private AtomicBoolean hasBeenCancelled = new AtomicBoolean(); + + private final ExecutorService executor = Executors.newCachedThreadPool(Executors.defaultThreadFactory()); + Future streamFuture; +} diff --git a/modules/juce_gui_basics/native/java/com/roli/juce/ComponentPeerView.java b/modules/juce_gui_basics/native/java/com/roli/juce/ComponentPeerView.java index 5415f26016..d5f49315a3 100644 --- a/modules/juce_gui_basics/native/java/com/roli/juce/ComponentPeerView.java +++ b/modules/juce_gui_basics/native/java/com/roli/juce/ComponentPeerView.java @@ -1,493 +1,493 @@ -package com.roli.juce; - -import android.app.Activity; -import android.app.Application; -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.ColorMatrix; -import android.graphics.ColorMatrixColorFilter; -import android.graphics.Paint; -import android.graphics.Rect; -import android.os.Bundle; -import android.text.InputType; -import android.view.KeyEvent; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewTreeObserver; -import android.view.inputmethod.BaseInputConnection; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputConnection; -import android.view.inputmethod.InputMethodManager; - -import java.lang.reflect.Method; - -public final class ComponentPeerView extends ViewGroup - implements View.OnFocusChangeListener, Application.ActivityLifecycleCallbacks -{ - public ComponentPeerView (Context context, boolean opaque_, long host) - { - super (context); - - if (Application.class.isInstance (context)) - { - ((Application) context).registerActivityLifecycleCallbacks (this); - } else - { - ((Application) context.getApplicationContext ()).registerActivityLifecycleCallbacks (this); - } - - this.host = host; - setWillNotDraw (false); - opaque = opaque_; - - setFocusable (true); - setFocusableInTouchMode (true); - setOnFocusChangeListener (this); - - // swap red and blue colours to match internal opengl texture format - ColorMatrix colorMatrix = new ColorMatrix (); - - float[] colorTransform = {0, 0, 1.0f, 0, 0, - 0, 1.0f, 0, 0, 0, - 1.0f, 0, 0, 0, 0, - 0, 0, 0, 1.0f, 0}; - - colorMatrix.set (colorTransform); - paint.setColorFilter (new ColorMatrixColorFilter (colorMatrix)); - - java.lang.reflect.Method method = null; - - try - { - method = getClass ().getMethod ("setLayerType", int.class, Paint.class); - } catch (SecurityException e) - { - } catch (NoSuchMethodException e) - { - } - - if (method != null) - { - try - { - int layerTypeNone = 0; - method.invoke (this, layerTypeNone, null); - } catch (java.lang.IllegalArgumentException e) - { - } catch (java.lang.IllegalAccessException e) - { - } catch (java.lang.reflect.InvocationTargetException e) - { - } - } - } - - public void clear () - { - host = 0; - } - - //============================================================================== - private native void handlePaint (long host, Canvas canvas, Paint paint); - - @Override - public void onDraw (Canvas canvas) - { - if (host == 0) - return; - - handlePaint (host, canvas, paint); - } - - @Override - public boolean isOpaque () - { - return opaque; - } - - private boolean opaque; - private long host; - private Paint paint = new Paint (); - - //============================================================================== - private native void handleMouseDown (long host, int index, float x, float y, long time); - private native void handleMouseDrag (long host, int index, float x, float y, long time); - private native void handleMouseUp (long host, int index, float x, float y, long time); - - @Override - public boolean onTouchEvent (MotionEvent event) - { - if (host == 0) - return false; - - int action = event.getAction (); - long time = event.getEventTime (); - - switch (action & MotionEvent.ACTION_MASK) - { - case MotionEvent.ACTION_DOWN: - handleMouseDown (host, event.getPointerId (0), event.getRawX (), event.getRawY (), time); - return true; - - case MotionEvent.ACTION_CANCEL: - case MotionEvent.ACTION_UP: - handleMouseUp (host, event.getPointerId (0), event.getRawX (), event.getRawY (), time); - return true; - - case MotionEvent.ACTION_MOVE: - { - handleMouseDrag (host, event.getPointerId (0), event.getRawX (), event.getRawY (), time); - - int n = event.getPointerCount (); - - if (n > 1) - { - int point[] = new int[2]; - getLocationOnScreen (point); - - for (int i = 1; i < n; ++i) - handleMouseDrag (host, event.getPointerId (i), event.getX (i) + point[0], event.getY (i) + point[1], time); - } - - return true; - } - - case MotionEvent.ACTION_POINTER_UP: - { - int i = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; - - if (i == 0) - { - handleMouseUp (host, event.getPointerId (0), event.getRawX (), event.getRawY (), time); - } else - { - int point[] = new int[2]; - getLocationOnScreen (point); - - handleMouseUp (host, event.getPointerId (i), event.getX (i) + point[0], event.getY (i) + point[1], time); - } - return true; - } - - case MotionEvent.ACTION_POINTER_DOWN: - { - int i = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; - - if (i == 0) - { - handleMouseDown (host, event.getPointerId (0), event.getRawX (), event.getRawY (), time); - } else - { - int point[] = new int[2]; - getLocationOnScreen (point); - - handleMouseDown (host, event.getPointerId (i), event.getX (i) + point[0], event.getY (i) + point[1], time); - } - return true; - } - - default: - break; - } - - return false; - } - - //============================================================================== - private native void handleKeyDown (long host, int keycode, int textchar); - private native void handleKeyUp (long host, int keycode, int textchar); - private native void handleBackButton (long host); - private native void handleKeyboardHidden (long host); - - public void showKeyboard (String type) - { - InputMethodManager imm = (InputMethodManager) getContext ().getSystemService (Context.INPUT_METHOD_SERVICE); - - if (imm != null) - { - if (type.length () > 0) - { - imm.showSoftInput (this, android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT); - imm.setInputMethod (getWindowToken (), type); - keyboardDismissListener.startListening (); - } else - { - imm.hideSoftInputFromWindow (getWindowToken (), 0); - keyboardDismissListener.stopListening (); - } - } - } - - public void backButtonPressed () - { - if (host == 0) - return; - - handleBackButton (host); - } - - @Override - public boolean onKeyDown (int keyCode, KeyEvent event) - { - if (host == 0) - return false; - - switch (keyCode) - { - case KeyEvent.KEYCODE_VOLUME_UP: - case KeyEvent.KEYCODE_VOLUME_DOWN: - return super.onKeyDown (keyCode, event); - case KeyEvent.KEYCODE_BACK: - { - ((Activity) getContext ()).onBackPressed (); - return true; - } - - default: - break; - } - - handleKeyDown (host, keyCode, event.getUnicodeChar ()); - return true; - } - - @Override - public boolean onKeyUp (int keyCode, KeyEvent event) - { - if (host == 0) - return false; - - handleKeyUp (host, keyCode, event.getUnicodeChar ()); - return true; - } - - @Override - public boolean onKeyMultiple (int keyCode, int count, KeyEvent event) - { - if (host == 0) - return false; - - if (keyCode != KeyEvent.KEYCODE_UNKNOWN || event.getAction () != KeyEvent.ACTION_MULTIPLE) - return super.onKeyMultiple (keyCode, count, event); - - if (event.getCharacters () != null) - { - int utf8Char = event.getCharacters ().codePointAt (0); - handleKeyDown (host, utf8Char, utf8Char); - return true; - } - - return false; - } - - //============================================================================== - private final class KeyboardDismissListener - { - public KeyboardDismissListener (ComponentPeerView viewToUse) - { - view = viewToUse; - } - - private void startListening () - { - view.getViewTreeObserver ().addOnGlobalLayoutListener (viewTreeObserver); - } - - private void stopListening () - { - view.getViewTreeObserver ().removeGlobalOnLayoutListener (viewTreeObserver); - } - - private class TreeObserver implements ViewTreeObserver.OnGlobalLayoutListener - { - TreeObserver () - { - keyboardShown = false; - } - - @Override - public void onGlobalLayout () - { - Rect r = new Rect (); - - View parentView = getRootView (); - int diff = 0; - - if (parentView == null) - { - getWindowVisibleDisplayFrame (r); - diff = getHeight () - (r.bottom - r.top); - } else - { - parentView.getWindowVisibleDisplayFrame (r); - diff = parentView.getHeight () - (r.bottom - r.top); - } - - // Arbitrary threshold, surely keyboard would take more than 20 pix. - if (diff < 20 && keyboardShown) - { - keyboardShown = false; - handleKeyboardHidden (view.host); - } - - if (!keyboardShown && diff > 20) - keyboardShown = true; - } - - ; - - private boolean keyboardShown; - } - - ; - - private ComponentPeerView view; - private TreeObserver viewTreeObserver = new TreeObserver (); - } - - private KeyboardDismissListener keyboardDismissListener = new KeyboardDismissListener (this); - - // this is here to make keyboard entry work on a Galaxy Tab2 10.1 - @Override - public InputConnection onCreateInputConnection (EditorInfo outAttrs) - { - outAttrs.actionLabel = ""; - outAttrs.hintText = ""; - outAttrs.initialCapsMode = 0; - outAttrs.initialSelEnd = outAttrs.initialSelStart = -1; - outAttrs.label = ""; - outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE | EditorInfo.IME_FLAG_NO_EXTRACT_UI; - outAttrs.inputType = InputType.TYPE_NULL; - - return new BaseInputConnection (this, false); - } - - //============================================================================== - @Override - protected void onSizeChanged (int w, int h, int oldw, int oldh) - { - super.onSizeChanged (w, h, oldw, oldh); - - if (host != 0) - viewSizeChanged (host); - } - - @Override - protected void onLayout (boolean changed, int left, int top, int right, int bottom) - { - } - - private native void viewSizeChanged (long host); - - @Override - public void onFocusChange (View v, boolean hasFocus) - { - if (host == 0) - return; - - if (v == this) - focusChanged (host, hasFocus); - } - - private native void focusChanged (long host, boolean hasFocus); - - public void setViewName (String newName) - { - } - - public void setSystemUiVisibilityCompat (int visibility) - { - Method systemUIVisibilityMethod = null; - try - { - systemUIVisibilityMethod = this.getClass ().getMethod ("setSystemUiVisibility", int.class); - } catch (SecurityException e) - { - return; - } catch (NoSuchMethodException e) - { - return; - } - if (systemUIVisibilityMethod == null) return; - - try - { - systemUIVisibilityMethod.invoke (this, visibility); - } catch (java.lang.IllegalArgumentException e) - { - } catch (java.lang.IllegalAccessException e) - { - } catch (java.lang.reflect.InvocationTargetException e) - { - } - } - - public boolean isVisible () - { - return getVisibility () == VISIBLE; - } - - public void setVisible (boolean b) - { - setVisibility (b ? VISIBLE : INVISIBLE); - } - - public boolean containsPoint (int x, int y) - { - return true; //xxx needs to check overlapping views - } - - //============================================================================== - private native void handleAppPaused (long host); - private native void handleAppResumed (long host); - - @Override - public void onActivityPaused (Activity activity) - { - if (host == 0) - return; - - handleAppPaused (host); - } - - @Override - public void onActivityStopped (Activity activity) - { - - } - - @Override - public void onActivitySaveInstanceState (Activity activity, Bundle bundle) - { - - } - - @Override - public void onActivityDestroyed (Activity activity) - { - - } - - @Override - public void onActivityCreated (Activity activity, Bundle bundle) - { - - } - - @Override - public void onActivityStarted (Activity activity) - { - - } - - @Override - public void onActivityResumed (Activity activity) - { - if (host == 0) - return; - - // Ensure that navigation/status bar visibility is correctly restored. - handleAppResumed (host); - } -} +package com.roli.juce; + +import android.app.Activity; +import android.app.Application; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.ColorMatrix; +import android.graphics.ColorMatrixColorFilter; +import android.graphics.Paint; +import android.graphics.Rect; +import android.os.Bundle; +import android.text.InputType; +import android.view.KeyEvent; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewTreeObserver; +import android.view.inputmethod.BaseInputConnection; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputConnection; +import android.view.inputmethod.InputMethodManager; + +import java.lang.reflect.Method; + +public final class ComponentPeerView extends ViewGroup + implements View.OnFocusChangeListener, Application.ActivityLifecycleCallbacks +{ + public ComponentPeerView (Context context, boolean opaque_, long host) + { + super (context); + + if (Application.class.isInstance (context)) + { + ((Application) context).registerActivityLifecycleCallbacks (this); + } else + { + ((Application) context.getApplicationContext ()).registerActivityLifecycleCallbacks (this); + } + + this.host = host; + setWillNotDraw (false); + opaque = opaque_; + + setFocusable (true); + setFocusableInTouchMode (true); + setOnFocusChangeListener (this); + + // swap red and blue colours to match internal opengl texture format + ColorMatrix colorMatrix = new ColorMatrix (); + + float[] colorTransform = {0, 0, 1.0f, 0, 0, + 0, 1.0f, 0, 0, 0, + 1.0f, 0, 0, 0, 0, + 0, 0, 0, 1.0f, 0}; + + colorMatrix.set (colorTransform); + paint.setColorFilter (new ColorMatrixColorFilter (colorMatrix)); + + java.lang.reflect.Method method = null; + + try + { + method = getClass ().getMethod ("setLayerType", int.class, Paint.class); + } catch (SecurityException e) + { + } catch (NoSuchMethodException e) + { + } + + if (method != null) + { + try + { + int layerTypeNone = 0; + method.invoke (this, layerTypeNone, null); + } catch (java.lang.IllegalArgumentException e) + { + } catch (java.lang.IllegalAccessException e) + { + } catch (java.lang.reflect.InvocationTargetException e) + { + } + } + } + + public void clear () + { + host = 0; + } + + //============================================================================== + private native void handlePaint (long host, Canvas canvas, Paint paint); + + @Override + public void onDraw (Canvas canvas) + { + if (host == 0) + return; + + handlePaint (host, canvas, paint); + } + + @Override + public boolean isOpaque () + { + return opaque; + } + + private boolean opaque; + private long host; + private Paint paint = new Paint (); + + //============================================================================== + private native void handleMouseDown (long host, int index, float x, float y, long time); + private native void handleMouseDrag (long host, int index, float x, float y, long time); + private native void handleMouseUp (long host, int index, float x, float y, long time); + + @Override + public boolean onTouchEvent (MotionEvent event) + { + if (host == 0) + return false; + + int action = event.getAction (); + long time = event.getEventTime (); + + switch (action & MotionEvent.ACTION_MASK) + { + case MotionEvent.ACTION_DOWN: + handleMouseDown (host, event.getPointerId (0), event.getRawX (), event.getRawY (), time); + return true; + + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + handleMouseUp (host, event.getPointerId (0), event.getRawX (), event.getRawY (), time); + return true; + + case MotionEvent.ACTION_MOVE: + { + handleMouseDrag (host, event.getPointerId (0), event.getRawX (), event.getRawY (), time); + + int n = event.getPointerCount (); + + if (n > 1) + { + int point[] = new int[2]; + getLocationOnScreen (point); + + for (int i = 1; i < n; ++i) + handleMouseDrag (host, event.getPointerId (i), event.getX (i) + point[0], event.getY (i) + point[1], time); + } + + return true; + } + + case MotionEvent.ACTION_POINTER_UP: + { + int i = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; + + if (i == 0) + { + handleMouseUp (host, event.getPointerId (0), event.getRawX (), event.getRawY (), time); + } else + { + int point[] = new int[2]; + getLocationOnScreen (point); + + handleMouseUp (host, event.getPointerId (i), event.getX (i) + point[0], event.getY (i) + point[1], time); + } + return true; + } + + case MotionEvent.ACTION_POINTER_DOWN: + { + int i = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; + + if (i == 0) + { + handleMouseDown (host, event.getPointerId (0), event.getRawX (), event.getRawY (), time); + } else + { + int point[] = new int[2]; + getLocationOnScreen (point); + + handleMouseDown (host, event.getPointerId (i), event.getX (i) + point[0], event.getY (i) + point[1], time); + } + return true; + } + + default: + break; + } + + return false; + } + + //============================================================================== + private native void handleKeyDown (long host, int keycode, int textchar); + private native void handleKeyUp (long host, int keycode, int textchar); + private native void handleBackButton (long host); + private native void handleKeyboardHidden (long host); + + public void showKeyboard (String type) + { + InputMethodManager imm = (InputMethodManager) getContext ().getSystemService (Context.INPUT_METHOD_SERVICE); + + if (imm != null) + { + if (type.length () > 0) + { + imm.showSoftInput (this, android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT); + imm.setInputMethod (getWindowToken (), type); + keyboardDismissListener.startListening (); + } else + { + imm.hideSoftInputFromWindow (getWindowToken (), 0); + keyboardDismissListener.stopListening (); + } + } + } + + public void backButtonPressed () + { + if (host == 0) + return; + + handleBackButton (host); + } + + @Override + public boolean onKeyDown (int keyCode, KeyEvent event) + { + if (host == 0) + return false; + + switch (keyCode) + { + case KeyEvent.KEYCODE_VOLUME_UP: + case KeyEvent.KEYCODE_VOLUME_DOWN: + return super.onKeyDown (keyCode, event); + case KeyEvent.KEYCODE_BACK: + { + ((Activity) getContext ()).onBackPressed (); + return true; + } + + default: + break; + } + + handleKeyDown (host, keyCode, event.getUnicodeChar ()); + return true; + } + + @Override + public boolean onKeyUp (int keyCode, KeyEvent event) + { + if (host == 0) + return false; + + handleKeyUp (host, keyCode, event.getUnicodeChar ()); + return true; + } + + @Override + public boolean onKeyMultiple (int keyCode, int count, KeyEvent event) + { + if (host == 0) + return false; + + if (keyCode != KeyEvent.KEYCODE_UNKNOWN || event.getAction () != KeyEvent.ACTION_MULTIPLE) + return super.onKeyMultiple (keyCode, count, event); + + if (event.getCharacters () != null) + { + int utf8Char = event.getCharacters ().codePointAt (0); + handleKeyDown (host, utf8Char, utf8Char); + return true; + } + + return false; + } + + //============================================================================== + private final class KeyboardDismissListener + { + public KeyboardDismissListener (ComponentPeerView viewToUse) + { + view = viewToUse; + } + + private void startListening () + { + view.getViewTreeObserver ().addOnGlobalLayoutListener (viewTreeObserver); + } + + private void stopListening () + { + view.getViewTreeObserver ().removeGlobalOnLayoutListener (viewTreeObserver); + } + + private class TreeObserver implements ViewTreeObserver.OnGlobalLayoutListener + { + TreeObserver () + { + keyboardShown = false; + } + + @Override + public void onGlobalLayout () + { + Rect r = new Rect (); + + View parentView = getRootView (); + int diff = 0; + + if (parentView == null) + { + getWindowVisibleDisplayFrame (r); + diff = getHeight () - (r.bottom - r.top); + } else + { + parentView.getWindowVisibleDisplayFrame (r); + diff = parentView.getHeight () - (r.bottom - r.top); + } + + // Arbitrary threshold, surely keyboard would take more than 20 pix. + if (diff < 20 && keyboardShown) + { + keyboardShown = false; + handleKeyboardHidden (view.host); + } + + if (!keyboardShown && diff > 20) + keyboardShown = true; + } + + ; + + private boolean keyboardShown; + } + + ; + + private ComponentPeerView view; + private TreeObserver viewTreeObserver = new TreeObserver (); + } + + private KeyboardDismissListener keyboardDismissListener = new KeyboardDismissListener (this); + + // this is here to make keyboard entry work on a Galaxy Tab2 10.1 + @Override + public InputConnection onCreateInputConnection (EditorInfo outAttrs) + { + outAttrs.actionLabel = ""; + outAttrs.hintText = ""; + outAttrs.initialCapsMode = 0; + outAttrs.initialSelEnd = outAttrs.initialSelStart = -1; + outAttrs.label = ""; + outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE | EditorInfo.IME_FLAG_NO_EXTRACT_UI; + outAttrs.inputType = InputType.TYPE_NULL; + + return new BaseInputConnection (this, false); + } + + //============================================================================== + @Override + protected void onSizeChanged (int w, int h, int oldw, int oldh) + { + super.onSizeChanged (w, h, oldw, oldh); + + if (host != 0) + viewSizeChanged (host); + } + + @Override + protected void onLayout (boolean changed, int left, int top, int right, int bottom) + { + } + + private native void viewSizeChanged (long host); + + @Override + public void onFocusChange (View v, boolean hasFocus) + { + if (host == 0) + return; + + if (v == this) + focusChanged (host, hasFocus); + } + + private native void focusChanged (long host, boolean hasFocus); + + public void setViewName (String newName) + { + } + + public void setSystemUiVisibilityCompat (int visibility) + { + Method systemUIVisibilityMethod = null; + try + { + systemUIVisibilityMethod = this.getClass ().getMethod ("setSystemUiVisibility", int.class); + } catch (SecurityException e) + { + return; + } catch (NoSuchMethodException e) + { + return; + } + if (systemUIVisibilityMethod == null) return; + + try + { + systemUIVisibilityMethod.invoke (this, visibility); + } catch (java.lang.IllegalArgumentException e) + { + } catch (java.lang.IllegalAccessException e) + { + } catch (java.lang.reflect.InvocationTargetException e) + { + } + } + + public boolean isVisible () + { + return getVisibility () == VISIBLE; + } + + public void setVisible (boolean b) + { + setVisibility (b ? VISIBLE : INVISIBLE); + } + + public boolean containsPoint (int x, int y) + { + return true; //xxx needs to check overlapping views + } + + //============================================================================== + private native void handleAppPaused (long host); + private native void handleAppResumed (long host); + + @Override + public void onActivityPaused (Activity activity) + { + if (host == 0) + return; + + handleAppPaused (host); + } + + @Override + public void onActivityStopped (Activity activity) + { + + } + + @Override + public void onActivitySaveInstanceState (Activity activity, Bundle bundle) + { + + } + + @Override + public void onActivityDestroyed (Activity activity) + { + + } + + @Override + public void onActivityCreated (Activity activity, Bundle bundle) + { + + } + + @Override + public void onActivityStarted (Activity activity) + { + + } + + @Override + public void onActivityResumed (Activity activity) + { + if (host == 0) + return; + + // Ensure that navigation/status bar visibility is correctly restored. + handleAppResumed (host); + } +} diff --git a/modules/juce_gui_extra/native/java/com/roli/juce/JuceWebView.java b/modules/juce_gui_extra/native/java/com/roli/juce/JuceWebView.java index be4155769e..a94815728e 100644 --- a/modules/juce_gui_extra/native/java/com/roli/juce/JuceWebView.java +++ b/modules/juce_gui_extra/native/java/com/roli/juce/JuceWebView.java @@ -1,107 +1,107 @@ -package com.roli.juce; - -import android.graphics.Bitmap; -import android.net.http.SslError; -import android.os.Message; -import android.webkit.WebResourceResponse; -import android.webkit.WebView; -import android.webkit.WebViewClient; -import android.webkit.SslErrorHandler; -import android.webkit.WebChromeClient; - - -//============================================================================== -public class JuceWebView -{ - static public class Client extends WebViewClient - { - public Client (long hostToUse) - { - host = hostToUse; - } - - public void hostDeleted () - { - synchronized (hostLock) - { - host = 0; - } - } - - public void onPageFinished (WebView view, String url) - { - if (host == 0) - return; - - webViewPageLoadFinished (host, view, url); - } - - public void onReceivedSslError (WebView view, SslErrorHandler handler, SslError error) - { - if (host == 0) - return; - - webViewReceivedSslError (host, view, handler, error); - } - - public void onPageStarted (WebView view, String url, Bitmap favicon) - { - if (host != 0) - webViewPageLoadStarted (host, view, url); - } - - public WebResourceResponse shouldInterceptRequest (WebView view, String url) - { - synchronized (hostLock) - { - if (host != 0) - { - boolean shouldLoad = webViewPageLoadStarted (host, view, url); - - if (shouldLoad) - return null; - } - } - - return new WebResourceResponse ("text/html", null, null); - } - - private native boolean webViewPageLoadStarted (long host, WebView view, String url); - - private native void webViewPageLoadFinished (long host, WebView view, String url); - - private native void webViewReceivedSslError (long host, WebView view, SslErrorHandler handler, SslError error); - - private long host; - private final Object hostLock = new Object (); - } - - static public class ChromeClient extends WebChromeClient - { - public ChromeClient (long hostToUse) - { - host = hostToUse; - } - - @Override - public void onCloseWindow (WebView window) - { - webViewCloseWindowRequest (host, window); - } - - @Override - public boolean onCreateWindow (WebView view, boolean isDialog, - boolean isUserGesture, Message resultMsg) - { - webViewCreateWindowRequest (host, view); - return false; - } - - private native void webViewCloseWindowRequest (long host, WebView view); - - private native void webViewCreateWindowRequest (long host, WebView view); - - private long host; - private final Object hostLock = new Object (); - } -} \ No newline at end of file +package com.roli.juce; + +import android.graphics.Bitmap; +import android.net.http.SslError; +import android.os.Message; +import android.webkit.WebResourceResponse; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.webkit.SslErrorHandler; +import android.webkit.WebChromeClient; + + +//============================================================================== +public class JuceWebView +{ + static public class Client extends WebViewClient + { + public Client (long hostToUse) + { + host = hostToUse; + } + + public void hostDeleted () + { + synchronized (hostLock) + { + host = 0; + } + } + + public void onPageFinished (WebView view, String url) + { + if (host == 0) + return; + + webViewPageLoadFinished (host, view, url); + } + + public void onReceivedSslError (WebView view, SslErrorHandler handler, SslError error) + { + if (host == 0) + return; + + webViewReceivedSslError (host, view, handler, error); + } + + public void onPageStarted (WebView view, String url, Bitmap favicon) + { + if (host != 0) + webViewPageLoadStarted (host, view, url); + } + + public WebResourceResponse shouldInterceptRequest (WebView view, String url) + { + synchronized (hostLock) + { + if (host != 0) + { + boolean shouldLoad = webViewPageLoadStarted (host, view, url); + + if (shouldLoad) + return null; + } + } + + return new WebResourceResponse ("text/html", null, null); + } + + private native boolean webViewPageLoadStarted (long host, WebView view, String url); + + private native void webViewPageLoadFinished (long host, WebView view, String url); + + private native void webViewReceivedSslError (long host, WebView view, SslErrorHandler handler, SslError error); + + private long host; + private final Object hostLock = new Object (); + } + + static public class ChromeClient extends WebChromeClient + { + public ChromeClient (long hostToUse) + { + host = hostToUse; + } + + @Override + public void onCloseWindow (WebView window) + { + webViewCloseWindowRequest (host, window); + } + + @Override + public boolean onCreateWindow (WebView view, boolean isDialog, + boolean isUserGesture, Message resultMsg) + { + webViewCreateWindowRequest (host, view); + return false; + } + + private native void webViewCloseWindowRequest (long host, WebView view); + + private native void webViewCreateWindowRequest (long host, WebView view); + + private long host; + private final Object hostLock = new Object (); + } +} diff --git a/modules/juce_opengl/native/java/com/roli/juce/JuceOpenGLView.java b/modules/juce_opengl/native/java/com/roli/juce/JuceOpenGLView.java index 022f131cf6..727c97e2b6 100644 --- a/modules/juce_opengl/native/java/com/roli/juce/JuceOpenGLView.java +++ b/modules/juce_opengl/native/java/com/roli/juce/JuceOpenGLView.java @@ -1,56 +1,56 @@ -package com.roli.juce; - -import android.content.Context; -import android.graphics.Canvas; -import android.view.SurfaceView; - -public class JuceOpenGLView extends SurfaceView -{ - private long host = 0; - - JuceOpenGLView (Context context, long nativeThis) - { - super (context); - host = nativeThis; - } - - public void cancel () - { - host = 0; - } - - //============================================================================== - @Override - protected void onAttachedToWindow () - { - super.onAttachedToWindow (); - - if (host != 0) - onAttchedWindowNative (host); - } - - @Override - protected void onDetachedFromWindow () - { - if (host != 0) - onDetachedFromWindowNative (host); - - super.onDetachedFromWindow (); - } - - @Override - protected void dispatchDraw (Canvas canvas) - { - super.dispatchDraw (canvas); - - if (host != 0) - onDrawNative (host, canvas); - } - - //============================================================================== - private native void onAttchedWindowNative (long nativeThis); - - private native void onDetachedFromWindowNative (long nativeThis); - - private native void onDrawNative (long nativeThis, Canvas canvas); -} \ No newline at end of file +package com.roli.juce; + +import android.content.Context; +import android.graphics.Canvas; +import android.view.SurfaceView; + +public class JuceOpenGLView extends SurfaceView +{ + private long host = 0; + + JuceOpenGLView (Context context, long nativeThis) + { + super (context); + host = nativeThis; + } + + public void cancel () + { + host = 0; + } + + //============================================================================== + @Override + protected void onAttachedToWindow () + { + super.onAttachedToWindow (); + + if (host != 0) + onAttchedWindowNative (host); + } + + @Override + protected void onDetachedFromWindow () + { + if (host != 0) + onDetachedFromWindowNative (host); + + super.onDetachedFromWindow (); + } + + @Override + protected void dispatchDraw (Canvas canvas) + { + super.dispatchDraw (canvas); + + if (host != 0) + onDrawNative (host, canvas); + } + + //============================================================================== + private native void onAttchedWindowNative (long nativeThis); + + private native void onDetachedFromWindowNative (long nativeThis); + + private native void onDrawNative (long nativeThis, Canvas canvas); +} diff --git a/modules/juce_video/native/java/com/roli/juce/CameraCaptureSessionCaptureCallback.java b/modules/juce_video/native/java/com/roli/juce/CameraCaptureSessionCaptureCallback.java index db5adf74f3..8fdd9d67b0 100644 --- a/modules/juce_video/native/java/com/roli/juce/CameraCaptureSessionCaptureCallback.java +++ b/modules/juce_video/native/java/com/roli/juce/CameraCaptureSessionCaptureCallback.java @@ -1,65 +1,65 @@ -package com.roli.juce; - -import android.hardware.camera2.CameraCaptureSession; -import android.hardware.camera2.CaptureRequest; -import android.hardware.camera2.TotalCaptureResult; -import android.hardware.camera2.CaptureFailure; -import android.hardware.camera2.CaptureResult; - -public class CameraCaptureSessionCaptureCallback extends CameraCaptureSession.CaptureCallback -{ - private native void cameraCaptureSessionCaptureCompleted (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result); - private native void cameraCaptureSessionCaptureFailed (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, CaptureFailure failure); - private native void cameraCaptureSessionCaptureProgressed (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, CaptureResult partialResult); - private native void cameraCaptureSessionCaptureStarted (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber); - private native void cameraCaptureSessionCaptureSequenceAborted (long host, boolean isPreview, CameraCaptureSession session, int sequenceId); - private native void cameraCaptureSessionCaptureSequenceCompleted (long host, boolean isPreview, CameraCaptureSession session, int sequenceId, long frameNumber); - - CameraCaptureSessionCaptureCallback (long hostToUse, boolean shouldBePreview) - { - host = hostToUse; - preview = shouldBePreview; - } - - @Override - public void onCaptureCompleted (CameraCaptureSession session, CaptureRequest request, - TotalCaptureResult result) - { - cameraCaptureSessionCaptureCompleted (host, preview, session, request, result); - } - - @Override - public void onCaptureFailed (CameraCaptureSession session, CaptureRequest request, CaptureFailure failure) - { - cameraCaptureSessionCaptureFailed (host, preview, session, request, failure); - } - - @Override - public void onCaptureProgressed (CameraCaptureSession session, CaptureRequest request, - CaptureResult partialResult) - { - cameraCaptureSessionCaptureProgressed (host, preview, session, request, partialResult); - } - - @Override - public void onCaptureSequenceAborted (CameraCaptureSession session, int sequenceId) - { - cameraCaptureSessionCaptureSequenceAborted (host, preview, session, sequenceId); - } - - @Override - public void onCaptureSequenceCompleted (CameraCaptureSession session, int sequenceId, long frameNumber) - { - cameraCaptureSessionCaptureSequenceCompleted (host, preview, session, sequenceId, frameNumber); - } - - @Override - public void onCaptureStarted (CameraCaptureSession session, CaptureRequest request, long timestamp, - long frameNumber) - { - cameraCaptureSessionCaptureStarted (host, preview, session, request, timestamp, frameNumber); - } - - private long host; - private boolean preview; -} +package com.roli.juce; + +import android.hardware.camera2.CameraCaptureSession; +import android.hardware.camera2.CaptureRequest; +import android.hardware.camera2.TotalCaptureResult; +import android.hardware.camera2.CaptureFailure; +import android.hardware.camera2.CaptureResult; + +public class CameraCaptureSessionCaptureCallback extends CameraCaptureSession.CaptureCallback +{ + private native void cameraCaptureSessionCaptureCompleted (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result); + private native void cameraCaptureSessionCaptureFailed (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, CaptureFailure failure); + private native void cameraCaptureSessionCaptureProgressed (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, CaptureResult partialResult); + private native void cameraCaptureSessionCaptureStarted (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber); + private native void cameraCaptureSessionCaptureSequenceAborted (long host, boolean isPreview, CameraCaptureSession session, int sequenceId); + private native void cameraCaptureSessionCaptureSequenceCompleted (long host, boolean isPreview, CameraCaptureSession session, int sequenceId, long frameNumber); + + CameraCaptureSessionCaptureCallback (long hostToUse, boolean shouldBePreview) + { + host = hostToUse; + preview = shouldBePreview; + } + + @Override + public void onCaptureCompleted (CameraCaptureSession session, CaptureRequest request, + TotalCaptureResult result) + { + cameraCaptureSessionCaptureCompleted (host, preview, session, request, result); + } + + @Override + public void onCaptureFailed (CameraCaptureSession session, CaptureRequest request, CaptureFailure failure) + { + cameraCaptureSessionCaptureFailed (host, preview, session, request, failure); + } + + @Override + public void onCaptureProgressed (CameraCaptureSession session, CaptureRequest request, + CaptureResult partialResult) + { + cameraCaptureSessionCaptureProgressed (host, preview, session, request, partialResult); + } + + @Override + public void onCaptureSequenceAborted (CameraCaptureSession session, int sequenceId) + { + cameraCaptureSessionCaptureSequenceAborted (host, preview, session, sequenceId); + } + + @Override + public void onCaptureSequenceCompleted (CameraCaptureSession session, int sequenceId, long frameNumber) + { + cameraCaptureSessionCaptureSequenceCompleted (host, preview, session, sequenceId, frameNumber); + } + + @Override + public void onCaptureStarted (CameraCaptureSession session, CaptureRequest request, long timestamp, + long frameNumber) + { + cameraCaptureSessionCaptureStarted (host, preview, session, request, timestamp, frameNumber); + } + + private long host; + private boolean preview; +} diff --git a/modules/juce_video/native/java/com/roli/juce/CameraCaptureSessionStateCallback.java b/modules/juce_video/native/java/com/roli/juce/CameraCaptureSessionStateCallback.java index 3cb782c024..b800f60277 100644 --- a/modules/juce_video/native/java/com/roli/juce/CameraCaptureSessionStateCallback.java +++ b/modules/juce_video/native/java/com/roli/juce/CameraCaptureSessionStateCallback.java @@ -1,53 +1,53 @@ -package com.roli.juce; - -import android.hardware.camera2.CameraCaptureSession; - -public class CameraCaptureSessionStateCallback extends CameraCaptureSession.StateCallback -{ - private native void cameraCaptureSessionActive (long host, CameraCaptureSession session); - - private native void cameraCaptureSessionClosed (long host, CameraCaptureSession session); - - private native void cameraCaptureSessionConfigureFailed (long host, CameraCaptureSession session); - - private native void cameraCaptureSessionConfigured (long host, CameraCaptureSession session); - - private native void cameraCaptureSessionReady (long host, CameraCaptureSession session); - - CameraCaptureSessionStateCallback (long hostToUse) - { - host = hostToUse; - } - - @Override - public void onActive (CameraCaptureSession session) - { - cameraCaptureSessionActive (host, session); - } - - @Override - public void onClosed (CameraCaptureSession session) - { - cameraCaptureSessionClosed (host, session); - } - - @Override - public void onConfigureFailed (CameraCaptureSession session) - { - cameraCaptureSessionConfigureFailed (host, session); - } - - @Override - public void onConfigured (CameraCaptureSession session) - { - cameraCaptureSessionConfigured (host, session); - } - - @Override - public void onReady (CameraCaptureSession session) - { - cameraCaptureSessionReady (host, session); - } - - private long host; -} +package com.roli.juce; + +import android.hardware.camera2.CameraCaptureSession; + +public class CameraCaptureSessionStateCallback extends CameraCaptureSession.StateCallback +{ + private native void cameraCaptureSessionActive (long host, CameraCaptureSession session); + + private native void cameraCaptureSessionClosed (long host, CameraCaptureSession session); + + private native void cameraCaptureSessionConfigureFailed (long host, CameraCaptureSession session); + + private native void cameraCaptureSessionConfigured (long host, CameraCaptureSession session); + + private native void cameraCaptureSessionReady (long host, CameraCaptureSession session); + + CameraCaptureSessionStateCallback (long hostToUse) + { + host = hostToUse; + } + + @Override + public void onActive (CameraCaptureSession session) + { + cameraCaptureSessionActive (host, session); + } + + @Override + public void onClosed (CameraCaptureSession session) + { + cameraCaptureSessionClosed (host, session); + } + + @Override + public void onConfigureFailed (CameraCaptureSession session) + { + cameraCaptureSessionConfigureFailed (host, session); + } + + @Override + public void onConfigured (CameraCaptureSession session) + { + cameraCaptureSessionConfigured (host, session); + } + + @Override + public void onReady (CameraCaptureSession session) + { + cameraCaptureSessionReady (host, session); + } + + private long host; +} diff --git a/modules/juce_video/native/java/com/roli/juce/CameraDeviceStateCallback.java b/modules/juce_video/native/java/com/roli/juce/CameraDeviceStateCallback.java index 509ae621f8..49cb45b786 100644 --- a/modules/juce_video/native/java/com/roli/juce/CameraDeviceStateCallback.java +++ b/modules/juce_video/native/java/com/roli/juce/CameraDeviceStateCallback.java @@ -1,43 +1,42 @@ -package com.roli.juce; - -import android.hardware.camera2.CameraDevice; - -public class CameraDeviceStateCallback extends CameraDevice.StateCallback -{ - private native void cameraDeviceStateClosed (long host, CameraDevice camera); - private native void cameraDeviceStateDisconnected (long host, CameraDevice camera); - private native void cameraDeviceStateError (long host, CameraDevice camera, int error); - private native void cameraDeviceStateOpened (long host, CameraDevice camera); - - CameraDeviceStateCallback (long hostToUse) - { - host = hostToUse; - } - - @Override - public void onClosed (CameraDevice camera) - { - cameraDeviceStateClosed (host, camera); - } - - @Override - public void onDisconnected (CameraDevice camera) - { - cameraDeviceStateDisconnected (host, camera); - } - - @Override - public void onError (CameraDevice camera, int error) - { - cameraDeviceStateError (host, camera, error); - } - - @Override - public void onOpened (CameraDevice camera) - { - cameraDeviceStateOpened (host, camera); - } - - private long host; -} - +package com.roli.juce; + +import android.hardware.camera2.CameraDevice; + +public class CameraDeviceStateCallback extends CameraDevice.StateCallback +{ + private native void cameraDeviceStateClosed (long host, CameraDevice camera); + private native void cameraDeviceStateDisconnected (long host, CameraDevice camera); + private native void cameraDeviceStateError (long host, CameraDevice camera, int error); + private native void cameraDeviceStateOpened (long host, CameraDevice camera); + + CameraDeviceStateCallback (long hostToUse) + { + host = hostToUse; + } + + @Override + public void onClosed (CameraDevice camera) + { + cameraDeviceStateClosed (host, camera); + } + + @Override + public void onDisconnected (CameraDevice camera) + { + cameraDeviceStateDisconnected (host, camera); + } + + @Override + public void onError (CameraDevice camera, int error) + { + cameraDeviceStateError (host, camera, error); + } + + @Override + public void onOpened (CameraDevice camera) + { + cameraDeviceStateOpened (host, camera); + } + + private long host; +} diff --git a/modules/juce_video/native/java/com/roli/juce/JuceOrientationEventListener.java b/modules/juce_video/native/java/com/roli/juce/JuceOrientationEventListener.java index 89769b6092..3d0c396793 100644 --- a/modules/juce_video/native/java/com/roli/juce/JuceOrientationEventListener.java +++ b/modules/juce_video/native/java/com/roli/juce/JuceOrientationEventListener.java @@ -1,24 +1,24 @@ -package com.roli.juce; - -import android.view.OrientationEventListener; -import android.content.Context; - -public class JuceOrientationEventListener extends OrientationEventListener -{ - private native void deviceOrientationChanged (long host, int orientation); - - public JuceOrientationEventListener (long hostToUse, Context context, int rate) - { - super (context, rate); - - host = hostToUse; - } - - @Override - public void onOrientationChanged (int orientation) - { - deviceOrientationChanged (host, orientation); - } - - private long host; -} +package com.roli.juce; + +import android.view.OrientationEventListener; +import android.content.Context; + +public class JuceOrientationEventListener extends OrientationEventListener +{ + private native void deviceOrientationChanged (long host, int orientation); + + public JuceOrientationEventListener (long hostToUse, Context context, int rate) + { + super (context, rate); + + host = hostToUse; + } + + @Override + public void onOrientationChanged (int orientation) + { + deviceOrientationChanged (host, orientation); + } + + private long host; +} diff --git a/modules/juce_video/native/java/com/roli/juce/MediaControllerCallback.java b/modules/juce_video/native/java/com/roli/juce/MediaControllerCallback.java index 8e02e9c263..a0f8ce37ff 100644 --- a/modules/juce_video/native/java/com/roli/juce/MediaControllerCallback.java +++ b/modules/juce_video/native/java/com/roli/juce/MediaControllerCallback.java @@ -1,53 +1,53 @@ -package com.roli.juce; - -import android.media.session.MediaController; -import android.media.session.MediaSession; -import android.media.MediaMetadata; -import android.media.session.PlaybackState; - -import java.util.List; - -//============================================================================== -public class MediaControllerCallback extends MediaController.Callback -{ - private native void mediaControllerAudioInfoChanged (long host, MediaController.PlaybackInfo info); - private native void mediaControllerMetadataChanged (long host, MediaMetadata metadata); - private native void mediaControllerPlaybackStateChanged (long host, PlaybackState state); - private native void mediaControllerSessionDestroyed (long host); - - MediaControllerCallback (long hostToUse) - { - host = hostToUse; - } - - @Override - public void onAudioInfoChanged (MediaController.PlaybackInfo info) - { - mediaControllerAudioInfoChanged (host, info); - } - - @Override - public void onMetadataChanged (MediaMetadata metadata) - { - mediaControllerMetadataChanged (host, metadata); - } - - @Override - public void onPlaybackStateChanged (PlaybackState state) - { - mediaControllerPlaybackStateChanged (host, state); - } - - @Override - public void onQueueChanged (List queue) - { - } - - @Override - public void onSessionDestroyed () - { - mediaControllerSessionDestroyed (host); - } - - private long host; -} +package com.roli.juce; + +import android.media.session.MediaController; +import android.media.session.MediaSession; +import android.media.MediaMetadata; +import android.media.session.PlaybackState; + +import java.util.List; + +//============================================================================== +public class MediaControllerCallback extends MediaController.Callback +{ + private native void mediaControllerAudioInfoChanged (long host, MediaController.PlaybackInfo info); + private native void mediaControllerMetadataChanged (long host, MediaMetadata metadata); + private native void mediaControllerPlaybackStateChanged (long host, PlaybackState state); + private native void mediaControllerSessionDestroyed (long host); + + MediaControllerCallback (long hostToUse) + { + host = hostToUse; + } + + @Override + public void onAudioInfoChanged (MediaController.PlaybackInfo info) + { + mediaControllerAudioInfoChanged (host, info); + } + + @Override + public void onMetadataChanged (MediaMetadata metadata) + { + mediaControllerMetadataChanged (host, metadata); + } + + @Override + public void onPlaybackStateChanged (PlaybackState state) + { + mediaControllerPlaybackStateChanged (host, state); + } + + @Override + public void onQueueChanged (List queue) + { + } + + @Override + public void onSessionDestroyed () + { + mediaControllerSessionDestroyed (host); + } + + private long host; +} diff --git a/modules/juce_video/native/java/com/roli/juce/MediaSessionCallback.java b/modules/juce_video/native/java/com/roli/juce/MediaSessionCallback.java index b93e5979e0..882ae07157 100644 --- a/modules/juce_video/native/java/com/roli/juce/MediaSessionCallback.java +++ b/modules/juce_video/native/java/com/roli/juce/MediaSessionCallback.java @@ -1,78 +1,78 @@ -package com.roli.juce; - -import android.media.session.MediaSession; - -import java.lang.String; - -import android.os.Bundle; -import android.content.Intent; - -import java.util.List; - -//============================================================================== -public class MediaSessionCallback extends MediaSession.Callback -{ - private native void mediaSessionPause (long host); - private native void mediaSessionPlay (long host); - private native void mediaSessionPlayFromMediaId (long host, String mediaId, Bundle extras); - private native void mediaSessionSeekTo (long host, long pos); - private native void mediaSessionStop (long host); - - MediaSessionCallback (long hostToUse) - { - host = hostToUse; - } - - @Override - public void onPause () - { - mediaSessionPause (host); - } - - @Override - public void onPlay () - { - mediaSessionPlay (host); - } - - @Override - public void onPlayFromMediaId (String mediaId, Bundle extras) - { - mediaSessionPlayFromMediaId (host, mediaId, extras); - } - - @Override - public void onSeekTo (long pos) - { - mediaSessionSeekTo (host, pos); - } - - @Override - public void onStop () - { - mediaSessionStop (host); - } - - @Override - public void onFastForward () {} - - @Override - public boolean onMediaButtonEvent (Intent mediaButtonIntent) - { - return true; - } - - @Override - public void onRewind () {} - - @Override - public void onSkipToNext () {} - - @Override - public void onSkipToPrevious () {} - - @Override - public void onSkipToQueueItem (long id) {} - - private long host; -} +package com.roli.juce; + +import android.media.session.MediaSession; + +import java.lang.String; + +import android.os.Bundle; +import android.content.Intent; + +import java.util.List; + +//============================================================================== +public class MediaSessionCallback extends MediaSession.Callback +{ + private native void mediaSessionPause (long host); + private native void mediaSessionPlay (long host); + private native void mediaSessionPlayFromMediaId (long host, String mediaId, Bundle extras); + private native void mediaSessionSeekTo (long host, long pos); + private native void mediaSessionStop (long host); + + MediaSessionCallback (long hostToUse) + { + host = hostToUse; + } + + @Override + public void onPause () + { + mediaSessionPause (host); + } + + @Override + public void onPlay () + { + mediaSessionPlay (host); + } + + @Override + public void onPlayFromMediaId (String mediaId, Bundle extras) + { + mediaSessionPlayFromMediaId (host, mediaId, extras); + } + + @Override + public void onSeekTo (long pos) + { + mediaSessionSeekTo (host, pos); + } + + @Override + public void onStop () + { + mediaSessionStop (host); + } + + @Override + public void onFastForward () {} + + @Override + public boolean onMediaButtonEvent (Intent mediaButtonIntent) + { + return true; + } + + @Override + public void onRewind () {} + + @Override + public void onSkipToNext () {} + + @Override + public void onSkipToPrevious () {} + + @Override + public void onSkipToQueueItem (long id) {} + + private long host; +} diff --git a/modules/juce_video/native/java/com/roli/juce/SystemVolumeObserver.java b/modules/juce_video/native/java/com/roli/juce/SystemVolumeObserver.java index bead8a05ae..86df1a9f30 100644 --- a/modules/juce_video/native/java/com/roli/juce/SystemVolumeObserver.java +++ b/modules/juce_video/native/java/com/roli/juce/SystemVolumeObserver.java @@ -1,37 +1,37 @@ -package com.roli.juce; - -import android.database.ContentObserver; -import android.app.Activity; -import android.net.Uri; - -//============================================================================== -public class SystemVolumeObserver extends ContentObserver -{ - private native void mediaSessionSystemVolumeChanged (long host); - - SystemVolumeObserver (Activity activityToUse, long hostToUse) - { - super (null); - - activity = activityToUse; - host = hostToUse; - } - - void setEnabled (boolean shouldBeEnabled) - { - if (shouldBeEnabled) - activity.getApplicationContext ().getContentResolver ().registerContentObserver (android.provider.Settings.System.CONTENT_URI, true, this); - else - activity.getApplicationContext ().getContentResolver ().unregisterContentObserver (this); - } - - @Override - public void onChange (boolean selfChange, Uri uri) - { - if (uri.toString ().startsWith ("content://settings/system/volume_music")) - mediaSessionSystemVolumeChanged (host); - } - - private Activity activity; - private long host; -} +package com.roli.juce; + +import android.database.ContentObserver; +import android.app.Activity; +import android.net.Uri; + +//============================================================================== +public class SystemVolumeObserver extends ContentObserver +{ + private native void mediaSessionSystemVolumeChanged (long host); + + SystemVolumeObserver (Activity activityToUse, long hostToUse) + { + super (null); + + activity = activityToUse; + host = hostToUse; + } + + void setEnabled (boolean shouldBeEnabled) + { + if (shouldBeEnabled) + activity.getApplicationContext ().getContentResolver ().registerContentObserver (android.provider.Settings.System.CONTENT_URI, true, this); + else + activity.getApplicationContext ().getContentResolver ().unregisterContentObserver (this); + } + + @Override + public void onChange (boolean selfChange, Uri uri) + { + if (uri.toString ().startsWith ("content://settings/system/volume_music")) + mediaSessionSystemVolumeChanged (host); + } + + private Activity activity; + private long host; +}