| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.example.android.common.midi; |
| |
| import android.media.midi.MidiDevice; |
| import android.media.midi.MidiDevice.MidiConnection; |
| import android.media.midi.MidiDeviceInfo; |
| import android.media.midi.MidiInputPort; |
| import android.media.midi.MidiManager; |
| import android.os.Handler; |
| import android.util.Log; |
| |
| import java.io.IOException; |
| |
| /** |
| * Tool for connecting MIDI ports on two remote devices. |
| */ |
| public class MidiPortConnector { |
| private final MidiManager mMidiManager; |
| private MidiDevice mSourceDevice; |
| private MidiDevice mDestinationDevice; |
| private MidiConnection mConnection; |
| |
| /** |
| * @param mMidiManager |
| */ |
| public MidiPortConnector(MidiManager midiManager) { |
| mMidiManager = midiManager; |
| } |
| |
| public void close() throws IOException { |
| if (mConnection != null) { |
| Log.i(MidiConstants.TAG, |
| "MidiPortConnector closing connection " + mConnection); |
| mConnection.close(); |
| mConnection = null; |
| } |
| if (mSourceDevice != null) { |
| mSourceDevice.close(); |
| mSourceDevice = null; |
| } |
| if (mDestinationDevice != null) { |
| mDestinationDevice.close(); |
| mDestinationDevice = null; |
| } |
| } |
| |
| private void safeClose() { |
| try { |
| close(); |
| } catch (IOException e) { |
| Log.e(MidiConstants.TAG, "could not close resources", e); |
| } |
| } |
| |
| /** |
| * Listener class used for receiving the results of |
| * {@link #connectToDevicePort} |
| */ |
| public interface OnPortsConnectedListener { |
| /** |
| * Called to respond to a {@link #connectToDevicePort} request |
| * |
| * @param connection |
| * a {@link MidiConnection} that represents the connected |
| * ports, or null if connection failed |
| */ |
| abstract public void onPortsConnected(MidiConnection connection); |
| } |
| |
| /** |
| * Open two devices and connect their ports. |
| * |
| * @param sourceDeviceInfo |
| * @param sourcePortIndex |
| * @param destinationDeviceInfo |
| * @param destinationPortIndex |
| */ |
| public void connectToDevicePort(final MidiDeviceInfo sourceDeviceInfo, |
| final int sourcePortIndex, |
| final MidiDeviceInfo destinationDeviceInfo, |
| final int destinationPortIndex) { |
| connectToDevicePort(sourceDeviceInfo, sourcePortIndex, |
| destinationDeviceInfo, destinationPortIndex, null, null); |
| } |
| |
| /** |
| * Open two devices and connect their ports. |
| * |
| * @param sourceDeviceInfo |
| * @param sourcePortIndex |
| * @param destinationDeviceInfo |
| * @param destinationPortIndex |
| */ |
| public void connectToDevicePort(final MidiDeviceInfo sourceDeviceInfo, |
| final int sourcePortIndex, |
| final MidiDeviceInfo destinationDeviceInfo, |
| final int destinationPortIndex, |
| final OnPortsConnectedListener listener, final Handler handler) { |
| safeClose(); |
| mMidiManager.openDevice(destinationDeviceInfo, |
| new MidiManager.OnDeviceOpenedListener() { |
| @Override |
| public void onDeviceOpened(MidiDevice destinationDevice) { |
| if (destinationDevice == null) { |
| Log.e(MidiConstants.TAG, |
| "could not open " + destinationDeviceInfo); |
| if (listener != null) { |
| listener.onPortsConnected(null); |
| } |
| } else { |
| mDestinationDevice = destinationDevice; |
| Log.i(MidiConstants.TAG, |
| "connectToDevicePort opened " |
| + destinationDeviceInfo); |
| // Destination device was opened so go to next step. |
| MidiInputPort destinationInputPort = destinationDevice |
| .openInputPort(destinationPortIndex); |
| if (destinationInputPort != null) { |
| Log.i(MidiConstants.TAG, |
| "connectToDevicePort opened port on " |
| + destinationDeviceInfo); |
| connectToDevicePort(sourceDeviceInfo, |
| sourcePortIndex, |
| destinationInputPort, |
| listener, handler); |
| } else { |
| Log.e(MidiConstants.TAG, |
| "could not open port on " |
| + destinationDeviceInfo); |
| safeClose(); |
| if (listener != null) { |
| listener.onPortsConnected(null); |
| } |
| } |
| } |
| } |
| }, handler); |
| } |
| |
| |
| /** |
| * Open a source device and connect its output port to the |
| * destinationInputPort. |
| * |
| * @param sourceDeviceInfo |
| * @param sourcePortIndex |
| * @param destinationInputPort |
| */ |
| private void connectToDevicePort(final MidiDeviceInfo sourceDeviceInfo, |
| final int sourcePortIndex, |
| final MidiInputPort destinationInputPort, |
| final OnPortsConnectedListener listener, final Handler handler) { |
| mMidiManager.openDevice(sourceDeviceInfo, |
| new MidiManager.OnDeviceOpenedListener() { |
| @Override |
| public void onDeviceOpened(MidiDevice device) { |
| if (device == null) { |
| Log.e(MidiConstants.TAG, |
| "could not open " + sourceDeviceInfo); |
| safeClose(); |
| if (listener != null) { |
| listener.onPortsConnected(null); |
| } |
| } else { |
| Log.i(MidiConstants.TAG, |
| "connectToDevicePort opened " |
| + sourceDeviceInfo); |
| // Device was opened so connect the ports. |
| mSourceDevice = device; |
| mConnection = device.connectPorts( |
| destinationInputPort, sourcePortIndex); |
| if (mConnection == null) { |
| Log.e(MidiConstants.TAG, "could not connect to " |
| + sourceDeviceInfo); |
| safeClose(); |
| } |
| if (listener != null) { |
| listener.onPortsConnected(mConnection); |
| } |
| } |
| } |
| }, handler); |
| } |
| |
| } |