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