Home | History | Annotate | Download | only in midi
      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 
    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          */
    164         public int getType() {
    165             return mPortType;
    166         }
    167 
    168         /**
    169          * Returns the port number of the port
    170          * @return the port number
    171          */
    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          */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    291     public boolean isPrivate() {
    292         return mIsPrivate;
    293     }
    294 
    295     @Override
    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
    305     public int hashCode() {
    306         return mId;
    307     }
    308 
    309     @Override
    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 
    341     public int describeContents() {
    342         return 0;
    343     }
    344 
    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