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.example.android.common.midi; 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 mMidiManager 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 * 104 * @param sourceDeviceInfo 105 * @param sourcePortIndex 106 * @param destinationDeviceInfo 107 * @param destinationPortIndex 108 */ connectToDevicePort(final MidiDeviceInfo sourceDeviceInfo, final int sourcePortIndex, final MidiDeviceInfo destinationDeviceInfo, final int destinationPortIndex, final OnPortsConnectedListener listener, final Handler handler)109 public void connectToDevicePort(final MidiDeviceInfo sourceDeviceInfo, 110 final int sourcePortIndex, 111 final MidiDeviceInfo destinationDeviceInfo, 112 final int destinationPortIndex, 113 final OnPortsConnectedListener listener, final Handler handler) { 114 safeClose(); 115 mMidiManager.openDevice(destinationDeviceInfo, 116 new MidiManager.OnDeviceOpenedListener() { 117 @Override 118 public void onDeviceOpened(MidiDevice destinationDevice) { 119 if (destinationDevice == null) { 120 Log.e(MidiConstants.TAG, 121 "could not open " + destinationDeviceInfo); 122 if (listener != null) { 123 listener.onPortsConnected(null); 124 } 125 } else { 126 mDestinationDevice = destinationDevice; 127 Log.i(MidiConstants.TAG, 128 "connectToDevicePort opened " 129 + destinationDeviceInfo); 130 // Destination device was opened so go to next step. 131 MidiInputPort destinationInputPort = destinationDevice 132 .openInputPort(destinationPortIndex); 133 if (destinationInputPort != null) { 134 Log.i(MidiConstants.TAG, 135 "connectToDevicePort opened port on " 136 + destinationDeviceInfo); 137 connectToDevicePort(sourceDeviceInfo, 138 sourcePortIndex, 139 destinationInputPort, 140 listener, handler); 141 } else { 142 Log.e(MidiConstants.TAG, 143 "could not open port on " 144 + destinationDeviceInfo); 145 safeClose(); 146 if (listener != null) { 147 listener.onPortsConnected(null); 148 } 149 } 150 } 151 } 152 }, handler); 153 } 154 155 156 /** 157 * Open a source device and connect its output port to the 158 * destinationInputPort. 159 * 160 * @param sourceDeviceInfo 161 * @param sourcePortIndex 162 * @param destinationInputPort 163 */ connectToDevicePort(final MidiDeviceInfo sourceDeviceInfo, final int sourcePortIndex, final MidiInputPort destinationInputPort, final OnPortsConnectedListener listener, final Handler handler)164 private void connectToDevicePort(final MidiDeviceInfo sourceDeviceInfo, 165 final int sourcePortIndex, 166 final MidiInputPort destinationInputPort, 167 final OnPortsConnectedListener listener, final Handler handler) { 168 mMidiManager.openDevice(sourceDeviceInfo, 169 new MidiManager.OnDeviceOpenedListener() { 170 @Override 171 public void onDeviceOpened(MidiDevice device) { 172 if (device == null) { 173 Log.e(MidiConstants.TAG, 174 "could not open " + sourceDeviceInfo); 175 safeClose(); 176 if (listener != null) { 177 listener.onPortsConnected(null); 178 } 179 } else { 180 Log.i(MidiConstants.TAG, 181 "connectToDevicePort opened " 182 + sourceDeviceInfo); 183 // Device was opened so connect the ports. 184 mSourceDevice = device; 185 mConnection = device.connectPorts( 186 destinationInputPort, sourcePortIndex); 187 if (mConnection == null) { 188 Log.e(MidiConstants.TAG, "could not connect to " 189 + sourceDeviceInfo); 190 safeClose(); 191 } 192 if (listener != null) { 193 listener.onPortsConnected(mConnection); 194 } 195 } 196 } 197 }, handler); 198 } 199 200 } 201