1 /* 2 * Copyright (C) 2014 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 android.media.midi; 18 19 import android.os.Bundle; 20 import android.os.Parcel; 21 import android.os.Parcelable; 22 23 /** 24 * This class contains information to describe a MIDI device. 25 * For now we only have information that can be retrieved easily for USB devices, 26 * but we will probably expand this in the future. 27 * 28 * This class is just an immutable object to encapsulate the MIDI device description. 29 * Use the MidiDevice class to actually communicate with devices. 30 */ 31 public final class MidiDeviceInfo implements Parcelable { 32 33 private static final String TAG = "MidiDeviceInfo"; 34 35 /** 36 * Constant representing USB MIDI devices for {@link #getType} 37 */ 38 public static final int TYPE_USB = 1; 39 40 /** 41 * Constant representing virtual (software based) MIDI devices for {@link #getType} 42 */ 43 public static final int TYPE_VIRTUAL = 2; 44 45 /** 46 * Constant representing Bluetooth MIDI devices for {@link #getType} 47 */ 48 public static final int TYPE_BLUETOOTH = 3; 49 50 /** 51 * Bundle key for the device's user visible name property. 52 * The value for this property is of type {@link java.lang.String}. 53 * Used with the {@link android.os.Bundle} returned by {@link #getProperties}. 54 * For USB devices, this is a concatenation of the manufacturer and product names. 55 */ 56 public static final String PROPERTY_NAME = "name"; 57 58 /** 59 * Bundle key for the device's manufacturer name property. 60 * The value for this property is of type {@link java.lang.String}. 61 * Used with the {@link android.os.Bundle} returned by {@link #getProperties}. 62 * Matches the USB device manufacturer name string for USB MIDI devices. 63 */ 64 public static final String PROPERTY_MANUFACTURER = "manufacturer"; 65 66 /** 67 * Bundle key for the device's product name property. 68 * The value for this property is of type {@link java.lang.String}. 69 * Used with the {@link android.os.Bundle} returned by {@link #getProperties} 70 * Matches the USB device product name string for USB MIDI devices. 71 */ 72 public static final String PROPERTY_PRODUCT = "product"; 73 74 /** 75 * Bundle key for the device's version property. 76 * The value for this property is of type {@link java.lang.String}. 77 * Used with the {@link android.os.Bundle} returned by {@link #getProperties} 78 * Matches the USB device version number for USB MIDI devices. 79 */ 80 public static final String PROPERTY_VERSION = "version"; 81 82 /** 83 * Bundle key for the device's serial number property. 84 * The value for this property is of type {@link java.lang.String}. 85 * Used with the {@link android.os.Bundle} returned by {@link #getProperties} 86 * Matches the USB device serial number for USB MIDI devices. 87 */ 88 public static final String PROPERTY_SERIAL_NUMBER = "serial_number"; 89 90 /** 91 * Bundle key for the device's corresponding USB device. 92 * The value for this property is of type {@link android.hardware.usb.UsbDevice}. 93 * Only set for USB MIDI devices. 94 * Used with the {@link android.os.Bundle} returned by {@link #getProperties} 95 */ 96 public static final String PROPERTY_USB_DEVICE = "usb_device"; 97 98 /** 99 * Bundle key for the device's corresponding Bluetooth device. 100 * The value for this property is of type {@link android.bluetooth.BluetoothDevice}. 101 * Only set for Bluetooth MIDI devices. 102 * Used with the {@link android.os.Bundle} returned by {@link #getProperties} 103 */ 104 public static final String PROPERTY_BLUETOOTH_DEVICE = "bluetooth_device"; 105 106 /** 107 * Bundle key for the device's ALSA card number. 108 * The value for this property is an integer. 109 * Only set for USB MIDI devices. 110 * Used with the {@link android.os.Bundle} returned by {@link #getProperties} 111 * 112 * @hide 113 */ 114 public static final String PROPERTY_ALSA_CARD = "alsa_card"; 115 116 /** 117 * Bundle key for the device's ALSA device number. 118 * The value for this property is an integer. 119 * Only set for USB MIDI devices. 120 * Used with the {@link android.os.Bundle} returned by {@link #getProperties} 121 * 122 * @hide 123 */ 124 public static final String PROPERTY_ALSA_DEVICE = "alsa_device"; 125 126 /** 127 * ServiceInfo for the service hosting the device implementation. 128 * The value for this property is of type {@link android.content.pm.ServiceInfo}. 129 * Only set for Virtual MIDI devices. 130 * Used with the {@link android.os.Bundle} returned by {@link #getProperties} 131 * 132 * @hide 133 */ 134 public static final String PROPERTY_SERVICE_INFO = "service_info"; 135 136 /** 137 * Contains information about an input or output port. 138 */ 139 public static final class PortInfo { 140 /** 141 * Port type for input ports 142 */ 143 public static final int TYPE_INPUT = 1; 144 145 /** 146 * Port type for output ports 147 */ 148 public static final int TYPE_OUTPUT = 2; 149 150 private final int mPortType; 151 private final int mPortNumber; 152 private final String mName; 153 PortInfo(int type, int portNumber, String name)154 PortInfo(int type, int portNumber, String name) { 155 mPortType = type; 156 mPortNumber = portNumber; 157 mName = (name == null ? "" : name); 158 } 159 160 /** 161 * Returns the port type of the port (either {@link #TYPE_INPUT} or {@link #TYPE_OUTPUT}) 162 * @return the port type 163 */ getType()164 public int getType() { 165 return mPortType; 166 } 167 168 /** 169 * Returns the port number of the port 170 * @return the port number 171 */ getPortNumber()172 public int getPortNumber() { 173 return mPortNumber; 174 } 175 176 /** 177 * Returns the name of the port, or empty string if the port has no name 178 * @return the port name 179 */ getName()180 public String getName() { 181 return mName; 182 } 183 } 184 185 private final int mType; // USB or virtual 186 private final int mId; // unique ID generated by MidiService 187 private final int mInputPortCount; 188 private final int mOutputPortCount; 189 private final String[] mInputPortNames; 190 private final String[] mOutputPortNames; 191 private final Bundle mProperties; 192 private final boolean mIsPrivate; 193 194 /** 195 * MidiDeviceInfo should only be instantiated by MidiService implementation 196 * @hide 197 */ MidiDeviceInfo(int type, int id, int numInputPorts, int numOutputPorts, String[] inputPortNames, String[] outputPortNames, Bundle properties, boolean isPrivate)198 public MidiDeviceInfo(int type, int id, int numInputPorts, int numOutputPorts, 199 String[] inputPortNames, String[] outputPortNames, Bundle properties, 200 boolean isPrivate) { 201 mType = type; 202 mId = id; 203 mInputPortCount = numInputPorts; 204 mOutputPortCount = numOutputPorts; 205 if (inputPortNames == null) { 206 mInputPortNames = new String[numInputPorts]; 207 } else { 208 mInputPortNames = inputPortNames; 209 } 210 if (outputPortNames == null) { 211 mOutputPortNames = new String[numOutputPorts]; 212 } else { 213 mOutputPortNames = outputPortNames; 214 } 215 mProperties = properties; 216 mIsPrivate = isPrivate; 217 } 218 219 /** 220 * Returns the type of the device. 221 * 222 * @return the device's type 223 */ getType()224 public int getType() { 225 return mType; 226 } 227 228 /** 229 * Returns the ID of the device. 230 * This ID is generated by the MIDI service and is not persistent across device unplugs. 231 * 232 * @return the device's ID 233 */ getId()234 public int getId() { 235 return mId; 236 } 237 238 /** 239 * Returns the device's number of input ports. 240 * 241 * @return the number of input ports 242 */ getInputPortCount()243 public int getInputPortCount() { 244 return mInputPortCount; 245 } 246 247 /** 248 * Returns the device's number of output ports. 249 * 250 * @return the number of output ports 251 */ getOutputPortCount()252 public int getOutputPortCount() { 253 return mOutputPortCount; 254 } 255 256 /** 257 * Returns information about the device's ports. 258 * The ports are in unspecified order. 259 * 260 * @return array of {@link PortInfo} 261 */ getPorts()262 public PortInfo[] getPorts() { 263 PortInfo[] ports = new PortInfo[mInputPortCount + mOutputPortCount]; 264 265 int index = 0; 266 for (int i = 0; i < mInputPortCount; i++) { 267 ports[index++] = new PortInfo(PortInfo.TYPE_INPUT, i, mInputPortNames[i]); 268 } 269 for (int i = 0; i < mOutputPortCount; i++) { 270 ports[index++] = new PortInfo(PortInfo.TYPE_OUTPUT, i, mOutputPortNames[i]); 271 } 272 273 return ports; 274 } 275 276 /** 277 * Returns the {@link android.os.Bundle} containing the device's properties. 278 * 279 * @return the device's properties 280 */ getProperties()281 public Bundle getProperties() { 282 return mProperties; 283 } 284 285 /** 286 * Returns true if the device is private. Private devices are only visible and accessible 287 * to clients with the same UID as the application that is hosting the device. 288 * 289 * @return true if the device is private 290 */ isPrivate()291 public boolean isPrivate() { 292 return mIsPrivate; 293 } 294 295 @Override equals(Object o)296 public boolean equals(Object o) { 297 if (o instanceof MidiDeviceInfo) { 298 return (((MidiDeviceInfo)o).mId == mId); 299 } else { 300 return false; 301 } 302 } 303 304 @Override hashCode()305 public int hashCode() { 306 return mId; 307 } 308 309 @Override toString()310 public String toString() { 311 // This is a hack to force the mProperties Bundle to unparcel so we can 312 // print all the names and values. 313 mProperties.getString(PROPERTY_NAME); 314 return ("MidiDeviceInfo[mType=" + mType + 315 ",mInputPortCount=" + mInputPortCount + 316 ",mOutputPortCount=" + mOutputPortCount + 317 ",mProperties=" + mProperties + 318 ",mIsPrivate=" + mIsPrivate); 319 } 320 321 public static final Parcelable.Creator<MidiDeviceInfo> CREATOR = 322 new Parcelable.Creator<MidiDeviceInfo>() { 323 public MidiDeviceInfo createFromParcel(Parcel in) { 324 int type = in.readInt(); 325 int id = in.readInt(); 326 int inputPorts = in.readInt(); 327 int outputPorts = in.readInt(); 328 String[] inputPortNames = in.createStringArray(); 329 String[] outputPortNames = in.createStringArray(); 330 Bundle properties = in.readBundle(); 331 boolean isPrivate = (in.readInt() == 1); 332 return new MidiDeviceInfo(type, id, inputPorts, outputPorts, 333 inputPortNames, outputPortNames, properties, isPrivate); 334 } 335 336 public MidiDeviceInfo[] newArray(int size) { 337 return new MidiDeviceInfo[size]; 338 } 339 }; 340 describeContents()341 public int describeContents() { 342 return 0; 343 } 344 writeToParcel(Parcel parcel, int flags)345 public void writeToParcel(Parcel parcel, int flags) { 346 parcel.writeInt(mType); 347 parcel.writeInt(mId); 348 parcel.writeInt(mInputPortCount); 349 parcel.writeInt(mOutputPortCount); 350 parcel.writeStringArray(mInputPortNames); 351 parcel.writeStringArray(mOutputPortNames); 352 parcel.writeBundle(mProperties); 353 parcel.writeInt(mIsPrivate ? 1 : 0); 354 } 355 } 356