diff options
19 files changed, 211 insertions, 183 deletions
diff --git a/api/current.txt b/api/current.txt index 9b7042a..827d9b7 100644 --- a/api/current.txt +++ b/api/current.txt @@ -17259,7 +17259,7 @@ package android.media.midi { method public int getId(); method public int getInputPortCount(); method public int getOutputPortCount(); - method public android.media.midi.MidiDeviceInfo.PortInfo[] getPortList(); + method public android.media.midi.MidiDeviceInfo.PortInfo[] getPorts(); method public android.os.Bundle getProperties(); method public int getType(); method public boolean isPrivate(); @@ -17307,22 +17307,17 @@ package android.media.midi { public final class MidiInputPort extends android.media.midi.MidiReceiver implements java.io.Closeable { method public void close() throws java.io.IOException; method public final int getPortNumber(); - method public void onReceive(byte[], int, int, long) throws java.io.IOException; + method public void onSend(byte[], int, int, long) throws java.io.IOException; } public final class MidiManager { - method public android.media.midi.MidiDeviceInfo[] getDeviceList(); - method public void openBluetoothDevice(android.bluetooth.BluetoothDevice, android.media.midi.MidiManager.BluetoothOpenCallback, android.os.Handler); - method public void openDevice(android.media.midi.MidiDeviceInfo, android.media.midi.MidiManager.DeviceOpenCallback, android.os.Handler); + method public android.media.midi.MidiDeviceInfo[] getDevices(); + method public void openBluetoothDevice(android.bluetooth.BluetoothDevice, android.media.midi.MidiManager.OnDeviceOpenedListener, android.os.Handler); + method public void openDevice(android.media.midi.MidiDeviceInfo, android.media.midi.MidiManager.OnDeviceOpenedListener, android.os.Handler); method public void registerDeviceCallback(android.media.midi.MidiManager.DeviceCallback, android.os.Handler); method public void unregisterDeviceCallback(android.media.midi.MidiManager.DeviceCallback); } - public static abstract class MidiManager.BluetoothOpenCallback { - ctor public MidiManager.BluetoothOpenCallback(); - method public abstract void onDeviceOpened(android.bluetooth.BluetoothDevice, android.media.midi.MidiDevice); - } - public static class MidiManager.DeviceCallback { ctor public MidiManager.DeviceCallback(); method public void onDeviceAdded(android.media.midi.MidiDeviceInfo); @@ -17330,31 +17325,34 @@ package android.media.midi { method public void onDeviceStatusChanged(android.media.midi.MidiDeviceStatus); } - public static abstract class MidiManager.DeviceOpenCallback { - ctor public MidiManager.DeviceOpenCallback(); - method public abstract void onDeviceOpened(android.media.midi.MidiDeviceInfo, android.media.midi.MidiDevice); + public static abstract interface MidiManager.OnDeviceOpenedListener { + method public abstract void onDeviceOpened(android.media.midi.MidiDevice); } public final class MidiOutputPort extends android.media.midi.MidiSender implements java.io.Closeable { method public void close() throws java.io.IOException; - method public void connect(android.media.midi.MidiReceiver); - method public void disconnect(android.media.midi.MidiReceiver); method public final int getPortNumber(); + method public void onConnect(android.media.midi.MidiReceiver); + method public void onDisconnect(android.media.midi.MidiReceiver); } public abstract class MidiReceiver { ctor public MidiReceiver(); + ctor public MidiReceiver(int); method public void flush() throws java.io.IOException; - method public int getMaxMessageSize(); - method public abstract void onReceive(byte[], int, int, long) throws java.io.IOException; + method public final int getMaxMessageSize(); + method public void onFlush() throws java.io.IOException; + method public abstract void onSend(byte[], int, int, long) throws java.io.IOException; method public void send(byte[], int, int) throws java.io.IOException; - method public void sendWithTimestamp(byte[], int, int, long) throws java.io.IOException; + method public void send(byte[], int, int, long) throws java.io.IOException; } public abstract class MidiSender { ctor public MidiSender(); - method public abstract void connect(android.media.midi.MidiReceiver); - method public abstract void disconnect(android.media.midi.MidiReceiver); + method public void connect(android.media.midi.MidiReceiver); + method public void disconnect(android.media.midi.MidiReceiver); + method public abstract void onConnect(android.media.midi.MidiReceiver); + method public abstract void onDisconnect(android.media.midi.MidiReceiver); } } diff --git a/api/system-current.txt b/api/system-current.txt index 3f734ed..6c6b601 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -18562,7 +18562,7 @@ package android.media.midi { method public int getId(); method public int getInputPortCount(); method public int getOutputPortCount(); - method public android.media.midi.MidiDeviceInfo.PortInfo[] getPortList(); + method public android.media.midi.MidiDeviceInfo.PortInfo[] getPorts(); method public android.os.Bundle getProperties(); method public int getType(); method public boolean isPrivate(); @@ -18610,22 +18610,17 @@ package android.media.midi { public final class MidiInputPort extends android.media.midi.MidiReceiver implements java.io.Closeable { method public void close() throws java.io.IOException; method public final int getPortNumber(); - method public void onReceive(byte[], int, int, long) throws java.io.IOException; + method public void onSend(byte[], int, int, long) throws java.io.IOException; } public final class MidiManager { - method public android.media.midi.MidiDeviceInfo[] getDeviceList(); - method public void openBluetoothDevice(android.bluetooth.BluetoothDevice, android.media.midi.MidiManager.BluetoothOpenCallback, android.os.Handler); - method public void openDevice(android.media.midi.MidiDeviceInfo, android.media.midi.MidiManager.DeviceOpenCallback, android.os.Handler); + method public android.media.midi.MidiDeviceInfo[] getDevices(); + method public void openBluetoothDevice(android.bluetooth.BluetoothDevice, android.media.midi.MidiManager.OnDeviceOpenedListener, android.os.Handler); + method public void openDevice(android.media.midi.MidiDeviceInfo, android.media.midi.MidiManager.OnDeviceOpenedListener, android.os.Handler); method public void registerDeviceCallback(android.media.midi.MidiManager.DeviceCallback, android.os.Handler); method public void unregisterDeviceCallback(android.media.midi.MidiManager.DeviceCallback); } - public static abstract class MidiManager.BluetoothOpenCallback { - ctor public MidiManager.BluetoothOpenCallback(); - method public abstract void onDeviceOpened(android.bluetooth.BluetoothDevice, android.media.midi.MidiDevice); - } - public static class MidiManager.DeviceCallback { ctor public MidiManager.DeviceCallback(); method public void onDeviceAdded(android.media.midi.MidiDeviceInfo); @@ -18633,31 +18628,34 @@ package android.media.midi { method public void onDeviceStatusChanged(android.media.midi.MidiDeviceStatus); } - public static abstract class MidiManager.DeviceOpenCallback { - ctor public MidiManager.DeviceOpenCallback(); - method public abstract void onDeviceOpened(android.media.midi.MidiDeviceInfo, android.media.midi.MidiDevice); + public static abstract interface MidiManager.OnDeviceOpenedListener { + method public abstract void onDeviceOpened(android.media.midi.MidiDevice); } public final class MidiOutputPort extends android.media.midi.MidiSender implements java.io.Closeable { method public void close() throws java.io.IOException; - method public void connect(android.media.midi.MidiReceiver); - method public void disconnect(android.media.midi.MidiReceiver); method public final int getPortNumber(); + method public void onConnect(android.media.midi.MidiReceiver); + method public void onDisconnect(android.media.midi.MidiReceiver); } public abstract class MidiReceiver { ctor public MidiReceiver(); + ctor public MidiReceiver(int); method public void flush() throws java.io.IOException; - method public int getMaxMessageSize(); - method public abstract void onReceive(byte[], int, int, long) throws java.io.IOException; + method public final int getMaxMessageSize(); + method public void onFlush() throws java.io.IOException; + method public abstract void onSend(byte[], int, int, long) throws java.io.IOException; method public void send(byte[], int, int) throws java.io.IOException; - method public void sendWithTimestamp(byte[], int, int, long) throws java.io.IOException; + method public void send(byte[], int, int, long) throws java.io.IOException; } public abstract class MidiSender { ctor public MidiSender(); - method public abstract void connect(android.media.midi.MidiReceiver); - method public abstract void disconnect(android.media.midi.MidiReceiver); + method public void connect(android.media.midi.MidiReceiver); + method public void disconnect(android.media.midi.MidiReceiver); + method public abstract void onConnect(android.media.midi.MidiReceiver); + method public abstract void onDisconnect(android.media.midi.MidiReceiver); } } diff --git a/core/java/com/android/internal/midi/MidiDispatcher.java b/core/java/com/android/internal/midi/MidiDispatcher.java index 70e699a..1a3c37c 100644 --- a/core/java/com/android/internal/midi/MidiDispatcher.java +++ b/core/java/com/android/internal/midi/MidiDispatcher.java @@ -27,7 +27,7 @@ import java.util.concurrent.CopyOnWriteArrayList; * This class subclasses {@link android.media.midi.MidiReceiver} and dispatches any data it receives * to its receiver list. Any receivers that throw an exception upon receiving data will * be automatically removed from the receiver list, but no IOException will be returned - * from the dispatcher's {@link android.media.midi.MidiReceiver#onReceive} in that case. + * from the dispatcher's {@link android.media.midi.MidiReceiver#onSend} in that case. */ public final class MidiDispatcher extends MidiReceiver { @@ -35,21 +35,13 @@ public final class MidiDispatcher extends MidiReceiver { = new CopyOnWriteArrayList<MidiReceiver>(); private final MidiSender mSender = new MidiSender() { - /** - * Called to connect a {@link android.media.midi.MidiReceiver} to the sender - * - * @param receiver the receiver to connect - */ - public void connect(MidiReceiver receiver) { + @Override + public void onConnect(MidiReceiver receiver) { mReceivers.add(receiver); } - /** - * Called to disconnect a {@link android.media.midi.MidiReceiver} from the sender - * - * @param receiver the receiver to disconnect - */ - public void disconnect(MidiReceiver receiver) { + @Override + public void onDisconnect(MidiReceiver receiver) { mReceivers.remove(receiver); } }; @@ -73,10 +65,10 @@ public final class MidiDispatcher extends MidiReceiver { } @Override - public void onReceive(byte[] msg, int offset, int count, long timestamp) throws IOException { + public void onSend(byte[] msg, int offset, int count, long timestamp) throws IOException { for (MidiReceiver receiver : mReceivers) { try { - receiver.sendWithTimestamp(msg, offset, count, timestamp); + receiver.send(msg, offset, count, timestamp); } catch (IOException e) { // if the receiver fails we remove the receiver but do not propagate the exception mReceivers.remove(receiver); @@ -85,7 +77,7 @@ public final class MidiDispatcher extends MidiReceiver { } @Override - public void flush() throws IOException { + public void onFlush() throws IOException { for (MidiReceiver receiver : mReceivers) { receiver.flush(); } diff --git a/core/java/com/android/internal/midi/MidiEventScheduler.java b/core/java/com/android/internal/midi/MidiEventScheduler.java index 4dc5838..7b01904 100644 --- a/core/java/com/android/internal/midi/MidiEventScheduler.java +++ b/core/java/com/android/internal/midi/MidiEventScheduler.java @@ -36,7 +36,7 @@ public class MidiEventScheduler extends EventScheduler { * time. */ @Override - public void onReceive(byte[] msg, int offset, int count, long timestamp) + public void onSend(byte[] msg, int offset, int count, long timestamp) throws IOException { MidiEvent event = createScheduledEvent(msg, offset, count, timestamp); if (event != null) { @@ -45,7 +45,7 @@ public class MidiEventScheduler extends EventScheduler { } @Override - public void flush() { + public void onFlush() { MidiEventScheduler.this.flush(); } } diff --git a/core/java/com/android/internal/midi/MidiFramer.java b/core/java/com/android/internal/midi/MidiFramer.java index 8ed5b5a..058f57c 100644 --- a/core/java/com/android/internal/midi/MidiFramer.java +++ b/core/java/com/android/internal/midi/MidiFramer.java @@ -54,10 +54,10 @@ public class MidiFramer extends MidiReceiver { } /* - * @see android.midi.MidiReceiver#onReceive(byte[], int, int, long) + * @see android.midi.MidiReceiver#onSend(byte[], int, int, long) */ @Override - public void onReceive(byte[] data, int offset, int count, long timestamp) + public void onSend(byte[] data, int offset, int count, long timestamp) throws IOException { // Log.i(TAG, formatMidiData(data, offset, count)); int sysExStartOffset = (mInSysEx ? offset : -1); @@ -77,7 +77,7 @@ public class MidiFramer extends MidiReceiver { } else if (b == 0xF7 /* SysEx End */) { // Log.i(TAG, "SysEx End"); if (mInSysEx) { - mReceiver.sendWithTimestamp(data, sysExStartOffset, + mReceiver.send(data, sysExStartOffset, offset - sysExStartOffset + 1, timestamp); mInSysEx = false; sysExStartOffset = -1; @@ -91,11 +91,11 @@ public class MidiFramer extends MidiReceiver { } else { // real-time? // Single byte message interleaved with other data. if (mInSysEx) { - mReceiver.sendWithTimestamp(data, sysExStartOffset, + mReceiver.send(data, sysExStartOffset, offset - sysExStartOffset, timestamp); sysExStartOffset = offset + 1; } - mReceiver.sendWithTimestamp(data, offset, 1, timestamp); + mReceiver.send(data, offset, 1, timestamp); } } else { // data byte // Save SysEx data for SysEx End marker or end of buffer. @@ -105,7 +105,7 @@ public class MidiFramer extends MidiReceiver { if (mRunningStatus != 0) { mBuffer[0] = (byte) mRunningStatus; } - mReceiver.sendWithTimestamp(mBuffer, 0, mCount, timestamp); + mReceiver.send(mBuffer, 0, mCount, timestamp); mNeeded = MidiConstants.getBytesPerMessage(mBuffer[0]) - 1; mCount = 1; } @@ -116,7 +116,7 @@ public class MidiFramer extends MidiReceiver { // send any accumulatedSysEx data if (sysExStartOffset >= 0 && sysExStartOffset < offset) { - mReceiver.sendWithTimestamp(data, sysExStartOffset, + mReceiver.send(data, sysExStartOffset, offset - sysExStartOffset, timestamp); } } diff --git a/media/java/android/media/midi/IMidiManager.aidl b/media/java/android/media/midi/IMidiManager.aidl index 74c63b4..fcd4aff 100644 --- a/media/java/android/media/midi/IMidiManager.aidl +++ b/media/java/android/media/midi/IMidiManager.aidl @@ -26,7 +26,7 @@ import android.os.IBinder; /** @hide */ interface IMidiManager { - MidiDeviceInfo[] getDeviceList(); + MidiDeviceInfo[] getDevices(); // for device creation & removal notifications void registerListener(IBinder token, in IMidiDeviceListener listener); diff --git a/media/java/android/media/midi/MidiDevice.java b/media/java/android/media/midi/MidiDevice.java index 6b36554..6526adc 100644 --- a/media/java/android/media/midi/MidiDevice.java +++ b/media/java/android/media/midi/MidiDevice.java @@ -136,11 +136,14 @@ public final class MidiDevice implements Closeable { /** * Connects the supplied {@link MidiInputPort} to the output port of this device * with the specified port number. Once the connection is made, the MidiInput port instance - * can no longer receive data via its {@link MidiReceiver#onReceive} method. - * This method returns a {@link MidiDevice.MidiConnection} object, which can be used to close the connection + * can no longer receive data via its {@link MidiReceiver#onSend} method. + * This method returns a {@link MidiDevice.MidiConnection} object, which can be used + * to close the connection. + * * @param inputPort the inputPort to connect * @param outputPortNumber the port number of the output port to connect inputPort to. - * @return {@link MidiDevice.MidiConnection} object if the connection is successful, or null in case of failure + * @return {@link MidiDevice.MidiConnection} object if the connection is successful, + * or null in case of failure. */ public MidiConnection connectPorts(MidiInputPort inputPort, int outputPortNumber) { if (outputPortNumber < 0 || outputPortNumber >= mDeviceInfo.getOutputPortCount()) { diff --git a/media/java/android/media/midi/MidiDeviceInfo.java b/media/java/android/media/midi/MidiDeviceInfo.java index 57607e9..a59be54 100644 --- a/media/java/android/media/midi/MidiDeviceInfo.java +++ b/media/java/android/media/midi/MidiDeviceInfo.java @@ -49,6 +49,7 @@ public final class MidiDeviceInfo implements Parcelable { /** * Bundle key for the device's user visible name property. + * The value for this property is of type {@link java.lang.String}. * Used with the {@link android.os.Bundle} returned by {@link #getProperties}. * For USB devices, this is a concatenation of the manufacturer and product names. */ @@ -56,6 +57,7 @@ public final class MidiDeviceInfo implements Parcelable { /** * Bundle key for the device's manufacturer name property. + * The value for this property is of type {@link java.lang.String}. * Used with the {@link android.os.Bundle} returned by {@link #getProperties}. * Matches the USB device manufacturer name string for USB MIDI devices. */ @@ -63,6 +65,7 @@ public final class MidiDeviceInfo implements Parcelable { /** * Bundle key for the device's product name property. + * The value for this property is of type {@link java.lang.String}. * Used with the {@link android.os.Bundle} returned by {@link #getProperties} * Matches the USB device product name string for USB MIDI devices. */ @@ -70,6 +73,7 @@ public final class MidiDeviceInfo implements Parcelable { /** * Bundle key for the device's version property. + * The value for this property is of type {@link java.lang.String}. * Used with the {@link android.os.Bundle} returned by {@link #getProperties} * Matches the USB device version number for USB MIDI devices. */ @@ -77,20 +81,23 @@ public final class MidiDeviceInfo implements Parcelable { /** * Bundle key for the device's serial number property. + * The value for this property is of type {@link java.lang.String}. * Used with the {@link android.os.Bundle} returned by {@link #getProperties} * Matches the USB device serial number for USB MIDI devices. */ public static final String PROPERTY_SERIAL_NUMBER = "serial_number"; /** - * Bundle key for the device's {@link android.hardware.usb.UsbDevice}. + * Bundle key for the device's corresponding USB device. + * The value for this property is of type {@link android.hardware.usb.UsbDevice}. * Only set for USB MIDI devices. * Used with the {@link android.os.Bundle} returned by {@link #getProperties} */ public static final String PROPERTY_USB_DEVICE = "usb_device"; /** - * Bundle key for the device's {@link android.bluetooth.BluetoothDevice}. + * Bundle key for the device's corresponding Bluetooth device. + * The value for this property is of type {@link android.bluetooth.BluetoothDevice}. * Only set for Bluetooth MIDI devices. * Used with the {@link android.os.Bundle} returned by {@link #getProperties} */ @@ -98,6 +105,7 @@ public final class MidiDeviceInfo implements Parcelable { /** * Bundle key for the device's ALSA card number. + * The value for this property is an integer. * Only set for USB MIDI devices. * Used with the {@link android.os.Bundle} returned by {@link #getProperties} * @@ -107,6 +115,7 @@ public final class MidiDeviceInfo implements Parcelable { /** * Bundle key for the device's ALSA device number. + * The value for this property is an integer. * Only set for USB MIDI devices. * Used with the {@link android.os.Bundle} returned by {@link #getProperties} * @@ -115,7 +124,8 @@ public final class MidiDeviceInfo implements Parcelable { public static final String PROPERTY_ALSA_DEVICE = "alsa_device"; /** - * {@link android.content.pm.ServiceInfo} for the service hosting the device implementation. + * ServiceInfo for the service hosting the device implementation. + * The value for this property is of type {@link android.content.pm.ServiceInfo}. * Only set for Virtual MIDI devices. * Used with the {@link android.os.Bundle} returned by {@link #getProperties} * @@ -249,18 +259,18 @@ public final class MidiDeviceInfo implements Parcelable { * * @return array of {@link PortInfo} */ - public PortInfo[] getPortList() { - PortInfo[] portInfoList = new PortInfo[mInputPortCount + mOutputPortCount]; + public PortInfo[] getPorts() { + PortInfo[] ports = new PortInfo[mInputPortCount + mOutputPortCount]; int index = 0; for (int i = 0; i < mInputPortCount; i++) { - portInfoList[index++] = new PortInfo(PortInfo.TYPE_INPUT, i, mInputPortNames[i]); + ports[index++] = new PortInfo(PortInfo.TYPE_INPUT, i, mInputPortNames[i]); } for (int i = 0; i < mOutputPortCount; i++) { - portInfoList[index++] = new PortInfo(PortInfo.TYPE_OUTPUT, i, mOutputPortNames[i]); + ports[index++] = new PortInfo(PortInfo.TYPE_OUTPUT, i, mOutputPortNames[i]); } - return portInfoList; + return ports; } /** diff --git a/media/java/android/media/midi/MidiDeviceStatus.java b/media/java/android/media/midi/MidiDeviceStatus.java index d4abeff..acb54de 100644 --- a/media/java/android/media/midi/MidiDeviceStatus.java +++ b/media/java/android/media/midi/MidiDeviceStatus.java @@ -69,6 +69,7 @@ public final class MidiDeviceStatus implements Parcelable { /** * Returns true if an input port is open. + * An input port can only be opened by one client at a time. * * @param portNumber the input port's port number * @return input port open status @@ -78,7 +79,8 @@ public final class MidiDeviceStatus implements Parcelable { } /** - * Returns the open count for an output port. + * Returns the number of clients currently connected to the specified output port. + * Unlike input ports, an output port can be opened by multiple clients at the same time. * * @param portNumber the output port's port number * @return output port open count diff --git a/media/java/android/media/midi/MidiInputPort.java b/media/java/android/media/midi/MidiInputPort.java index ff16a57..af5a86c 100644 --- a/media/java/android/media/midi/MidiInputPort.java +++ b/media/java/android/media/midi/MidiInputPort.java @@ -49,6 +49,8 @@ public final class MidiInputPort extends MidiReceiver implements Closeable { /* package */ MidiInputPort(IMidiDeviceServer server, IBinder token, ParcelFileDescriptor pfd, int portNumber) { + super(MidiPortImpl.MAX_PACKET_DATA_SIZE); + mDeviceServer = server; mToken = token; mParcelFileDescriptor = pfd; @@ -71,7 +73,7 @@ public final class MidiInputPort extends MidiReceiver implements Closeable { } @Override - public void onReceive(byte[] msg, int offset, int count, long timestamp) throws IOException { + public void onSend(byte[] msg, int offset, int count, long timestamp) throws IOException { if (offset < 0 || count < 0 || offset + count > msg.length) { throw new IllegalArgumentException("offset or count out of range"); } @@ -89,7 +91,7 @@ public final class MidiInputPort extends MidiReceiver implements Closeable { } @Override - public void flush() throws IOException { + public void onFlush() throws IOException { synchronized (mBuffer) { if (mOutputStream == null) { throw new IOException("MidiInputPort is closed"); @@ -113,11 +115,6 @@ public final class MidiInputPort extends MidiReceiver implements Closeable { } @Override - public int getMaxMessageSize() { - return MidiPortImpl.MAX_PACKET_DATA_SIZE; - } - - @Override public void close() throws IOException { synchronized (mGuard) { if (mIsClosed) return; diff --git a/media/java/android/media/midi/MidiManager.java b/media/java/android/media/midi/MidiManager.java index 0ba1744..d19cf36 100644 --- a/media/java/android/media/midi/MidiManager.java +++ b/media/java/android/media/midi/MidiManager.java @@ -151,29 +151,16 @@ public final class MidiManager { } /** - * Callback class used for receiving the results of {@link #openDevice} + * Listener class used for receiving the results of {@link #openDevice} and + * {@link #openBluetoothDevice} */ - abstract public static class DeviceOpenCallback { + public interface OnDeviceOpenedListener { /** * Called to respond to a {@link #openDevice} request * - * @param deviceInfo the {@link MidiDeviceInfo} for the device to open * @param device a {@link MidiDevice} for opened device, or null if opening failed */ - abstract public void onDeviceOpened(MidiDeviceInfo deviceInfo, MidiDevice device); - } - - /** - * Callback class used for receiving the results of {@link #openBluetoothDevice} - */ - abstract public static class BluetoothOpenCallback { - /** - * Called to respond to a {@link #openBluetoothDevice} request - * - * @param bluetoothDevice the {@link android.bluetooth.BluetoothDevice} to open - * @param device a {@link MidiDevice} for opened device, or null if opening failed - */ - abstract public void onDeviceOpened(BluetoothDevice bluetoothDevice, MidiDevice device); + abstract public void onDeviceOpened(MidiDevice device); } /** @@ -224,38 +211,25 @@ public final class MidiManager { * * @return an array of all MIDI devices */ - public MidiDeviceInfo[] getDeviceList() { + public MidiDeviceInfo[] getDevices() { try { - return mService.getDeviceList(); + return mService.getDevices(); } catch (RemoteException e) { - Log.e(TAG, "RemoteException in getDeviceList"); + Log.e(TAG, "RemoteException in getDevices"); return new MidiDeviceInfo[0]; } } - private void sendOpenDeviceResponse(final MidiDeviceInfo deviceInfo, final MidiDevice device, - final DeviceOpenCallback callback, Handler handler) { + private void sendOpenDeviceResponse(final MidiDevice device, + final OnDeviceOpenedListener listener, Handler handler) { if (handler != null) { handler.post(new Runnable() { @Override public void run() { - callback.onDeviceOpened(deviceInfo, device); + listener.onDeviceOpened(device); } }); } else { - callback.onDeviceOpened(deviceInfo, device); - } - } - - private void sendBluetoothDeviceResponse(final BluetoothDevice bluetoothDevice, - final MidiDevice device, final BluetoothOpenCallback callback, Handler handler) { - if (handler != null) { - handler.post(new Runnable() { - @Override public void run() { - callback.onDeviceOpened(bluetoothDevice, device); - } - }); - } else { - callback.onDeviceOpened(bluetoothDevice, device); + listener.onDeviceOpened(device); } } @@ -263,12 +237,13 @@ public final class MidiManager { * Opens a MIDI device for reading and writing. * * @param deviceInfo a {@link android.media.midi.MidiDeviceInfo} to open - * @param callback a {@link MidiManager.DeviceOpenCallback} to be called to receive the result + * @param listener a {@link MidiManager.OnDeviceOpenedListener} to be called + * to receive the result * @param handler the {@link android.os.Handler Handler} that will be used for delivering * the result. If handler is null, then the thread used for the - * callback is unspecified. + * listener is unspecified. */ - public void openDevice(MidiDeviceInfo deviceInfo, DeviceOpenCallback callback, + public void openDevice(MidiDeviceInfo deviceInfo, OnDeviceOpenedListener listener, Handler handler) { MidiDevice device = null; try { @@ -283,7 +258,7 @@ public final class MidiManager { intent.setComponent(new ComponentName(serviceInfo.packageName, serviceInfo.name)); final MidiDeviceInfo deviceInfoF = deviceInfo; - final DeviceOpenCallback callbackF = callback; + final OnDeviceOpenedListener listenerF = listener; final Handler handlerF = handler; if (mContext.bindService(intent, new ServiceConnection() { @@ -291,8 +266,9 @@ public final class MidiManager { public void onServiceConnected(ComponentName name, IBinder binder) { IMidiDeviceServer server = IMidiDeviceServer.Stub.asInterface(binder); - MidiDevice device = new MidiDevice(deviceInfoF, server, mContext, this); - sendOpenDeviceResponse(deviceInfoF, device, callbackF, handlerF); + MidiDevice device = new MidiDevice(deviceInfoF, server, mContext, + this); + sendOpenDeviceResponse(device, listenerF, handlerF); } @Override @@ -314,21 +290,21 @@ public final class MidiManager { } catch (RemoteException e) { Log.e(TAG, "RemoteException in openDevice"); } - sendOpenDeviceResponse(deviceInfo, device, callback, handler); + sendOpenDeviceResponse(device, listener, handler); } /** * Opens a Bluetooth MIDI device for reading and writing. * * @param bluetoothDevice a {@link android.bluetooth.BluetoothDevice} to open as a MIDI device - * @param callback a {@link MidiManager.BluetoothOpenCallback} to be called to receive the + * @param listener a {@link MidiManager.OnDeviceOpenedListener} to be called to receive the * result * @param handler the {@link android.os.Handler Handler} that will be used for delivering * the result. If handler is null, then the thread used for the - * callback is unspecified. + * listener is unspecified. */ public void openBluetoothDevice(final BluetoothDevice bluetoothDevice, - final BluetoothOpenCallback callback, final Handler handler) { + final OnDeviceOpenedListener listener, final Handler handler) { Intent intent = new Intent(BLUETOOTH_MIDI_SERVICE_INTENT); intent.setComponent(new ComponentName(BLUETOOTH_MIDI_SERVICE_PACKAGE, BLUETOOTH_MIDI_SERVICE_CLASS)); @@ -343,10 +319,10 @@ public final class MidiManager { // fetch MidiDeviceInfo from the server MidiDeviceInfo deviceInfo = server.getDeviceInfo(); MidiDevice device = new MidiDevice(deviceInfo, server, mContext, this); - sendBluetoothDeviceResponse(bluetoothDevice, device, callback, handler); + sendOpenDeviceResponse(device, listener, handler); } catch (RemoteException e) { Log.e(TAG, "remote exception in onServiceConnected"); - sendBluetoothDeviceResponse(bluetoothDevice, null, callback, handler); + sendOpenDeviceResponse(null, listener, handler); } } @@ -358,7 +334,7 @@ public final class MidiManager { Context.BIND_AUTO_CREATE)) { Log.e(TAG, "Unable to bind service: " + intent); - sendBluetoothDeviceResponse(bluetoothDevice, null, callback, handler); + sendOpenDeviceResponse(null, listener, handler); } } diff --git a/media/java/android/media/midi/MidiOutputPort.java b/media/java/android/media/midi/MidiOutputPort.java index 7491f3c..0096995 100644 --- a/media/java/android/media/midi/MidiOutputPort.java +++ b/media/java/android/media/midi/MidiOutputPort.java @@ -70,7 +70,7 @@ public final class MidiOutputPort extends MidiSender implements Closeable { long timestamp = MidiPortImpl.getPacketTimestamp(buffer, count); // dispatch to all our receivers - mDispatcher.sendWithTimestamp(buffer, offset, size, timestamp); + mDispatcher.send(buffer, offset, size, timestamp); break; } case MidiPortImpl.PACKET_TYPE_FLUSH: @@ -114,12 +114,12 @@ public final class MidiOutputPort extends MidiSender implements Closeable { } @Override - public void connect(MidiReceiver receiver) { + public void onConnect(MidiReceiver receiver) { mDispatcher.getSender().connect(receiver); } @Override - public void disconnect(MidiReceiver receiver) { + public void onDisconnect(MidiReceiver receiver) { mDispatcher.getSender().disconnect(receiver); } diff --git a/media/java/android/media/midi/MidiReceiver.java b/media/java/android/media/midi/MidiReceiver.java index f8799d4..85c451f 100644 --- a/media/java/android/media/midi/MidiReceiver.java +++ b/media/java/android/media/midi/MidiReceiver.java @@ -22,19 +22,35 @@ import java.io.IOException; * Interface for sending and receiving data to and from a MIDI device. */ abstract public class MidiReceiver { + + private final int mMaxMessageSize; + /** - * Although public, this method should be considered a private implementation - * detail. Client code should call {@link #send} or {@link #sendWithTimestamp} - * instead. - * - * Called to pass MIDI data to the receiver. + * Default MidiReceiver constructor. Maximum message size is set to + * {@link java.lang.Integer#MAX_VALUE} + */ + public MidiReceiver() { + mMaxMessageSize = Integer.MAX_VALUE; + } + + /** + * MidiReceiver constructor. + * @param maxMessageSize the maximum size of a message this receiver can receive + */ + public MidiReceiver(int maxMessageSize) { + mMaxMessageSize = maxMessageSize; + } + + /** + * Called whenever the receiver is passed new MIDI data. + * Subclasses override this method to receive MIDI data. * May fail if count exceeds {@link #getMaxMessageSize}. * * NOTE: the msg array parameter is only valid within the context of this call. * The msg bytes should be copied by the receiver rather than retaining a reference * to this parameter. * Also, modifying the contents of the msg array parameter may result in other receivers - * in the same application receiving incorrect values in their {link #onReceive} method. + * in the same application receiving incorrect values in their {link #onSend} method. * * @param msg a byte array containing the MIDI data * @param offset the offset of the first byte of the data in the array to be processed @@ -42,28 +58,37 @@ abstract public class MidiReceiver { * @param timestamp the timestamp of the message (based on {@link java.lang.System#nanoTime} * @throws IOException */ - abstract public void onReceive(byte[] msg, int offset, int count, long timestamp) + abstract public void onSend(byte[] msg, int offset, int count, long timestamp) throws IOException; /** - * Instructs the receiver to discard all pending events. + * Instructs the receiver to discard all pending MIDI data. * @throws IOException */ public void flush() throws IOException { + onFlush(); + } + + /** + * Called when the receiver is instructed to discard all pending MIDI data. + * Subclasses should override this method if they maintain a list or queue of MIDI data + * to be processed in the future. + * @throws IOException + */ + public void onFlush() throws IOException { } /** * Returns the maximum size of a message this receiver can receive. - * Defaults to {@link java.lang.Integer#MAX_VALUE} unless overridden. * @return maximum message size */ - public int getMaxMessageSize() { - return Integer.MAX_VALUE; + public final int getMaxMessageSize() { + return mMaxMessageSize; } /** * Called to send MIDI data to the receiver - * Data will get split into multiple calls to {@link #onReceive} if count exceeds + * Data will get split into multiple calls to {@link #onSend} if count exceeds * {@link #getMaxMessageSize}. * * @param msg a byte array containing the MIDI data @@ -72,12 +97,12 @@ abstract public class MidiReceiver { * @throws IOException */ public void send(byte[] msg, int offset, int count) throws IOException { - sendWithTimestamp(msg, offset, count, System.nanoTime()); + send(msg, offset, count, System.nanoTime()); } /** * Called to send MIDI data to the receiver to be handled at a specified time in the future - * Data will get split into multiple calls to {@link #onReceive} if count exceeds + * Data will get split into multiple calls to {@link #onSend} if count exceeds * {@link #getMaxMessageSize}. * * @param msg a byte array containing the MIDI data @@ -86,12 +111,12 @@ abstract public class MidiReceiver { * @param timestamp the timestamp of the message (based on {@link java.lang.System#nanoTime} * @throws IOException */ - public void sendWithTimestamp(byte[] msg, int offset, int count, long timestamp) + public void send(byte[] msg, int offset, int count, long timestamp) throws IOException { int messageSize = getMaxMessageSize(); while (count > 0) { int length = (count > messageSize ? messageSize : count); - onReceive(msg, offset, length, timestamp); + onSend(msg, offset, length, timestamp); offset += length; count -= length; } diff --git a/media/java/android/media/midi/MidiSender.java b/media/java/android/media/midi/MidiSender.java index f64fc3c..c5f1edc 100644 --- a/media/java/android/media/midi/MidiSender.java +++ b/media/java/android/media/midi/MidiSender.java @@ -21,17 +21,42 @@ package android.media.midi; * MidiReceivers to a MIDI device. */ abstract public class MidiSender { + + /** + * Connects a {@link MidiReceiver} to the sender + * + * @param receiver the receiver to connect + */ + public void connect(MidiReceiver receiver) { + if (receiver == null) { + throw new NullPointerException("receiver null in MidiSender.connect"); + } + onConnect(receiver); + } + + /** + * Disconnects a {@link MidiReceiver} from the sender + * + * @param receiver the receiver to disconnect + */ + public void disconnect(MidiReceiver receiver) { + if (receiver == null) { + throw new NullPointerException("receiver null in MidiSender.disconnect"); + } + onDisconnect(receiver); + } + /** * Called to connect a {@link MidiReceiver} to the sender * * @param receiver the receiver to connect */ - abstract public void connect(MidiReceiver receiver); + abstract public void onConnect(MidiReceiver receiver); /** * Called to disconnect a {@link MidiReceiver} from the sender * * @param receiver the receiver to disconnect */ - abstract public void disconnect(MidiReceiver receiver); + abstract public void onDisconnect(MidiReceiver receiver); } diff --git a/media/java/android/media/midi/package.html b/media/java/android/media/midi/package.html index 9e7e8b1..8850e6f 100644 --- a/media/java/android/media/midi/package.html +++ b/media/java/android/media/midi/package.html @@ -30,13 +30,13 @@ capabilities, etc. messages. <li> Support transmission of arbitrary length data for SysEx, etc. <li> Timestamps to avoid jitter. - <li> Support direction connection or “patching” of devices for lower latency. + <li> Support direction connection or “patching” of devices for lower latency. </ul> <h2 id=transports_supported>Transports Supported</h2> -<p>The API is “transport agnostic”. But there are several transports currently +<p>The API is “transport agnostic”. But there are several transports currently supported:</p> <ul> @@ -83,7 +83,7 @@ MidiManager m = (MidiManager)context.getSystemService(Context.MIDI_SERVICE); information can be presented to a user, allowing them to choose a device.</p> <pre class=prettyprint> -MidiDeviceInfo[] infos = m.getDeviceList(); +MidiDeviceInfo[] infos = m.getDevices(); </pre> @@ -116,9 +116,9 @@ int numOutputs = info.getOutputPortCount(); </pre> -<p>Note that “input” and “output” are from the standpoint of the device. So a -synthesizer will have an “input” port that receives messages. A keyboard will -have an “output” port that sends messages.</p> +<p>Note that “input” and “output” are from the standpoint of the device. So a +synthesizer will have an “input” port that receives messages. A keyboard will +have an “output” port that sends messages.</p> <p>The MidiDeviceInfo has a bundle of properties.</p> @@ -148,12 +148,11 @@ you need to provide a callback for completion. You can specify an optional Handler if you want the callback to occur on a specific Thread.</p> <pre class=prettyprint> -m.openDevice(info, new MidiManager.DeviceOpenCallback() { +m.openDevice(info, new MidiManager.OnDeviceOpenedListener() { @Override - public void onDeviceOpened(MidiDeviceInfo deviceInfo, - MidiDevice device) { + public void onDeviceOpened(MidiDevice device) { if (device == null) { - Log.e(TAG, "could not open " + deviceInfo); + Log.e(TAG, "could not open device " + info); } else { ... }, new Handler(Looper.getMainLooper()) @@ -164,7 +163,7 @@ m.openDevice(info, new MidiManager.DeviceOpenCallback() { <h2 id=open_a_midi_input_port>Open a MIDI Input Port</h2> -<p>If you want to send a message to a MIDI Device then you need to open an “input” +<p>If you want to send a message to a MIDI Device then you need to open an “input” port with exclusive access.</p> <pre class=prettyprint> @@ -199,7 +198,7 @@ consistent with the other audio and input timers.</p> <pre class=prettyprint> long now = System.nanoTime(); long future = now + (2 * 1000000000); -inputPort.sendWithTimestamp(buffer, offset, numBytes, future); +inputPort.send(buffer, offset, numBytes, future); </pre> @@ -212,7 +211,7 @@ inputPort.flush(); // discard events <p>If there were any MIDI NoteOff message left in the buffer then they will be -discarded and you may get stuck notes. So we recommend sending “all notes off” +discarded and you may get stuck notes. So we recommend sending “all notes off” after doing a flush.</p> <h2 id=receive_a_note>Receive a Note</h2> @@ -223,7 +222,7 @@ connect your receiver to an output port of the device.</p> <pre class=prettyprint> class MyReceiver extends MidiReceiver { - public void onReceive(byte[] data, int offset, + public void onSend(byte[] data, int offset, int count, long timestamp) throws IOException { // parse MIDI or whatever } @@ -264,7 +263,7 @@ AndroidManifest.xml file.</p> <p>The details of the resource in this example is stored in -“res/xml/synth_device_info.xml”.</p> +“res/xml/synth_device_info.xml”.</p> <pre class=prettyprint> <devices> @@ -279,7 +278,7 @@ AndroidManifest.xml file.</p> <p>You then define your server by extending android.media.midi.MidiDeviceService. -Let’s assume you have a MySynthEngine class that extends MidiReceiver.</p> +Let‘s assume you have a MySynthEngine class that extends MidiReceiver.</p> <pre class=prettyprint> import android.media.midi.MidiDeviceService; diff --git a/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothMidiDevice.java b/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothMidiDevice.java index 0ccbf6a..60c6570 100644 --- a/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothMidiDevice.java +++ b/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothMidiDevice.java @@ -234,10 +234,10 @@ public final class BluetoothMidiDevice { break; } try { - mPacketEncoder.sendWithTimestamp(event.data, 0, event.count, + mPacketEncoder.send(event.data, 0, event.count, event.getTimestamp()); } catch (IOException e) { - Log.e(TAG, "mPacketAccumulator.sendWithTimestamp failed", e); + Log.e(TAG, "mPacketAccumulator.send failed", e); } mEventScheduler.addEventToPool(event); } diff --git a/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothPacketDecoder.java b/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothPacketDecoder.java index 1bce9fb..ea95a01 100644 --- a/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothPacketDecoder.java +++ b/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothPacketDecoder.java @@ -86,7 +86,7 @@ public class BluetoothPacketDecoder extends PacketDecoder { if (dataCount > 0) { // send previous message separately since it has a different timestamp try { - receiver.sendWithTimestamp(mBuffer, 0, dataCount, nanoTimestamp); + receiver.send(mBuffer, 0, dataCount, nanoTimestamp); } catch (IOException e) { // ??? } @@ -106,7 +106,7 @@ public class BluetoothPacketDecoder extends PacketDecoder { if (dataCount > 0) { try { - receiver.sendWithTimestamp(mBuffer, 0, dataCount, nanoTimestamp); + receiver.send(mBuffer, 0, dataCount, nanoTimestamp); } catch (IOException e) { // ??? } diff --git a/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothPacketEncoder.java b/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothPacketEncoder.java index 99ea353..5fb162c 100644 --- a/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothPacketEncoder.java +++ b/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothPacketEncoder.java @@ -53,7 +53,7 @@ public class BluetoothPacketEncoder extends PacketEncoder { // This receives normalized data from mMidiFramer and accumulates it into a packet buffer private final MidiReceiver mFramedDataReceiver = new MidiReceiver() { @Override - public void onReceive(byte[] msg, int offset, int count, long timestamp) + public void onSend(byte[] msg, int offset, int count, long timestamp) throws IOException { synchronized (mLock) { @@ -130,7 +130,8 @@ public class BluetoothPacketEncoder extends PacketEncoder { flushLocked(true); appendHeader(milliTimestamp); } - mAccumulationBuffer[mAccumulatedBytes++] = (byte)(0x80 | (milliTimestamp & 0x7F)); + mAccumulationBuffer[mAccumulatedBytes++] = + (byte)(0x80 | (milliTimestamp & 0x7F)); mAccumulationBuffer[mAccumulatedBytes++] = MidiConstants.STATUS_END_SYSEX; } } else { @@ -146,7 +147,8 @@ public class BluetoothPacketEncoder extends PacketEncoder { // now copy data bytes int dataLength = count - 1; - System.arraycopy(msg, offset + 1, mAccumulationBuffer, mAccumulatedBytes, dataLength); + System.arraycopy(msg, offset + 1, mAccumulationBuffer, mAccumulatedBytes, + dataLength); mAccumulatedBytes += dataLength; } @@ -160,7 +162,8 @@ public class BluetoothPacketEncoder extends PacketEncoder { // write header if we are starting a new packet if (mAccumulatedBytes == 0) { // header byte with timestamp bits 7 - 12 - mAccumulationBuffer[mAccumulatedBytes++] = (byte)(0x80 | ((milliTimestamp >> 7) & 0x3F)); + mAccumulationBuffer[mAccumulatedBytes++] = + (byte)(0x80 | ((milliTimestamp >> 7) & 0x3F)); mPacketTimestamp = milliTimestamp; return true; } else { @@ -177,10 +180,10 @@ public class BluetoothPacketEncoder extends PacketEncoder { } @Override - public void onReceive(byte[] msg, int offset, int count, long timestamp) + public void onSend(byte[] msg, int offset, int count, long timestamp) throws IOException { // normalize the data by passing it through a MidiFramer first - mMidiFramer.sendWithTimestamp(msg, offset, count, timestamp); + mMidiFramer.send(msg, offset, count, timestamp); } @Override diff --git a/services/midi/java/com/android/server/midi/MidiService.java b/services/midi/java/com/android/server/midi/MidiService.java index 176f54b..370f125 100644 --- a/services/midi/java/com/android/server/midi/MidiService.java +++ b/services/midi/java/com/android/server/midi/MidiService.java @@ -339,7 +339,7 @@ public class MidiService extends IMidiManager.Stub { private static final MidiDeviceInfo[] EMPTY_DEVICE_INFO_ARRAY = new MidiDeviceInfo[0]; - public MidiDeviceInfo[] getDeviceList() { + public MidiDeviceInfo[] getDevices() { ArrayList<MidiDeviceInfo> deviceInfos = new ArrayList<MidiDeviceInfo>(); int uid = Binder.getCallingUid(); |