1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.mobileer.miditools; 18 19 import android.media.midi.MidiDevice; 20 import android.media.midi.MidiDevice.MidiConnection; 21 import android.media.midi.MidiDeviceInfo; 22 import android.media.midi.MidiInputPort; 23 import android.media.midi.MidiManager; 24 import android.os.Handler; 25 import android.util.Log; 26 27 import java.io.IOException; 28 29 /** 30 * Tool for connecting MIDI ports on two remote devices. 31 */ 32 public class MidiPortConnector { 33 private final MidiManager mMidiManager; 34 private MidiDevice mSourceDevice; 35 private MidiDevice mDestinationDevice; 36 private MidiConnection mConnection; 37 38 /** 39 * @param midiManager 40 */ MidiPortConnector(MidiManager midiManager)41 public MidiPortConnector(MidiManager midiManager) { 42 mMidiManager = midiManager; 43 } 44 close()45 public void close() throws IOException { 46 if (mConnection != null) { 47 Log.i(MidiConstants.TAG, 48 "MidiPortConnector closing connection " + mConnection); 49 mConnection.close(); 50 mConnection = null; 51 } 52 if (mSourceDevice != null) { 53 mSourceDevice.close(); 54 mSourceDevice = null; 55 } 56 if (mDestinationDevice != null) { 57 mDestinationDevice.close(); 58 mDestinationDevice = null; 59 } 60 } 61 safeClose()62 private void safeClose() { 63 try { 64 close(); 65 } catch (IOException e) { 66 Log.e(MidiConstants.TAG, "could not close resources", e); 67 } 68 } 69 70 /** 71 * Listener class used for receiving the results of 72 * {@link #connectToDevicePort} 73 */ 74 public interface OnPortsConnectedListener { 75 /** 76 * Called to respond to a {@link #connectToDevicePort} request 77 * 78 * @param connection 79 * a {@link MidiConnection} that represents the connected 80 * ports, or null if connection failed 81 */ onPortsConnected(MidiConnection connection)82 abstract public void onPortsConnected(MidiConnection connection); 83 } 84 85 /** 86 * Open two devices and connect their ports. 87 * 88 * @param sourceDeviceInfo 89 * @param sourcePortIndex 90 * @param destinationDeviceInfo 91 * @param destinationPortIndex 92 */ connectToDevicePort(final MidiDeviceInfo sourceDeviceInfo, final int sourcePortIndex, final MidiDeviceInfo destinationDeviceInfo, final int destinationPortIndex)93 public void connectToDevicePort(final MidiDeviceInfo sourceDeviceInfo, 94 final int sourcePortIndex, 95 final MidiDeviceInfo destinationDeviceInfo, 96 final int destinationPortIndex) { 97 connectToDevicePort(sourceDeviceInfo, sourcePortIndex, 98 destinationDeviceInfo, destinationPortIndex, null, null); 99 } 100 101 /** 102 * Open two devices and connect their ports. 103 * Then notify listener of the result. 104 * 105 * @param sourceDeviceInfo 106 * @param sourcePortIndex 107 * @param destinationDeviceInfo 108 * @param destinationPortIndex 109 * @param listener 110 * @param handler 111 */ connectToDevicePort(final MidiDeviceInfo sourceDeviceInfo, final int sourcePortIndex, final MidiDeviceInfo destinationDeviceInfo, final int destinationPortIndex, final OnPortsConnectedListener listener, final Handler handler)112 public void connectToDevicePort(final MidiDeviceInfo sourceDeviceInfo, 113 final int sourcePortIndex, 114 final MidiDeviceInfo destinationDeviceInfo, 115 final int destinationPortIndex, 116 final OnPortsConnectedListener listener, final Handler handler) { 117 safeClose(); 118 mMidiManager.openDevice(destinationDeviceInfo, 119 new MidiManager.OnDeviceOpenedListener() { 120 @Override 121 public void onDeviceOpened(MidiDevice destinationDevice) { 122 if (destinationDevice == null) { 123 Log.e(MidiConstants.TAG, 124 "could not open " + destinationDeviceInfo); 125 if (listener != null) { 126 listener.onPortsConnected(null); 127 } 128 } else { 129 mDestinationDevice = destinationDevice; 130 Log.i(MidiConstants.TAG, 131 "connectToDevicePort opened " 132 + destinationDeviceInfo); 133 // Destination device was opened so go to next step. 134 MidiInputPort destinationInputPort = destinationDevice 135 .openInputPort(destinationPortIndex); 136 if (destinationInputPort != null) { 137 Log.i(MidiConstants.TAG, 138 "connectToDevicePort opened port on " 139 + destinationDeviceInfo); 140 connectToDevicePort(sourceDeviceInfo, 141 sourcePortIndex, 142 destinationInputPort, 143 listener, handler); 144 } else { 145 Log.e(MidiConstants.TAG, 146 "could not open port on " 147 + destinationDeviceInfo); 148 safeClose(); 149 if (listener != null) { 150 listener.onPortsConnected(null); 151 } 152 } 153 } 154 } 155 }, handler); 156 } 157 158 159 /** 160 * Open a source device and connect its output port to the 161 * destinationInputPort. 162 * 163 * @param sourceDeviceInfo 164 * @param sourcePortIndex 165 * @param destinationInputPort 166 */ connectToDevicePort(final MidiDeviceInfo sourceDeviceInfo, final int sourcePortIndex, final MidiInputPort destinationInputPort, final OnPortsConnectedListener listener, final Handler handler)167 private void connectToDevicePort(final MidiDeviceInfo sourceDeviceInfo, 168 final int sourcePortIndex, 169 final MidiInputPort destinationInputPort, 170 final OnPortsConnectedListener listener, final Handler handler) { 171 mMidiManager.openDevice(sourceDeviceInfo, 172 new MidiManager.OnDeviceOpenedListener() { 173 @Override 174 public void onDeviceOpened(MidiDevice device) { 175 if (device == null) { 176 Log.e(MidiConstants.TAG, 177 "could not open " + sourceDeviceInfo); 178 safeClose(); 179 if (listener != null) { 180 listener.onPortsConnected(null); 181 } 182 } else { 183 Log.i(MidiConstants.TAG, 184 "connectToDevicePort opened " 185 + sourceDeviceInfo); 186 // Device was opened so connect the ports. 187 mSourceDevice = device; 188 mConnection = device.connectPorts( 189 destinationInputPort, sourcePortIndex); 190 if (mConnection == null) { 191 Log.e(MidiConstants.TAG, "could not connect to " 192 + sourceDeviceInfo); 193 safeClose(); 194 } 195 if (listener != null) { 196 listener.onPortsConnected(mConnection); 197 } 198 } 199 } 200 }, handler); 201 } 202 203 } 204