blob: c2229850b4cef2bb53e1788a74b2e56e0bfb33b5 [file] [log] [blame]
Mike Lockwood67f8e8b2014-12-01 13:54:59 -08001/*
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
Mike Lockwoodb6737702015-02-20 08:28:47 -080017package android.media.midi;
Mike Lockwood67f8e8b2014-12-01 13:54:59 -080018
19import android.os.Bundle;
20import android.os.Parcel;
21import android.os.Parcelable;
22
Mikhail Naganov33603ae2016-09-27 10:42:53 -070023import android.util.Log;
24
Mike Lockwood67f8e8b2014-12-01 13:54:59 -080025/**
26 * This class contains information to describe a MIDI device.
27 * For now we only have information that can be retrieved easily for USB devices,
28 * but we will probably expand this in the future.
29 *
30 * This class is just an immutable object to encapsulate the MIDI device description.
31 * Use the MidiDevice class to actually communicate with devices.
Mike Lockwood67f8e8b2014-12-01 13:54:59 -080032 */
Mike Lockwoodbe215dd2015-03-07 11:04:59 -080033public final class MidiDeviceInfo implements Parcelable {
Mike Lockwood67f8e8b2014-12-01 13:54:59 -080034
35 private static final String TAG = "MidiDeviceInfo";
36
Mikhail Naganov84b67402016-09-15 11:00:57 -070037 /*
38 * Please note that constants and (un)marshalling code need to be kept in sync
39 * with the native implementation (MidiDeviceInfo.h|cpp)
40 */
41
Mike Lockwood78beecf2014-12-11 09:15:23 -080042 /**
43 * Constant representing USB MIDI devices for {@link #getType}
44 */
Mike Lockwood67f8e8b2014-12-01 13:54:59 -080045 public static final int TYPE_USB = 1;
Mike Lockwood78beecf2014-12-11 09:15:23 -080046
47 /**
48 * Constant representing virtual (software based) MIDI devices for {@link #getType}
49 */
Mike Lockwood67f8e8b2014-12-01 13:54:59 -080050 public static final int TYPE_VIRTUAL = 2;
51
Mike Lockwoodf2cd8022015-03-11 08:50:41 -070052 /**
Mike Lockwood3f5acc62015-03-17 13:21:03 -070053 * Constant representing Bluetooth MIDI devices for {@link #getType}
54 */
55 public static final int TYPE_BLUETOOTH = 3;
56
57 /**
Mike Lockwoodf2cd8022015-03-11 08:50:41 -070058 * Bundle key for the device's user visible name property.
Mike Lockwood7eb441c2015-05-12 13:32:16 -070059 * The value for this property is of type {@link java.lang.String}.
Mike Lockwoodf2cd8022015-03-11 08:50:41 -070060 * Used with the {@link android.os.Bundle} returned by {@link #getProperties}.
61 * For USB devices, this is a concatenation of the manufacturer and product names.
62 */
63 public static final String PROPERTY_NAME = "name";
Mike Lockwood67f8e8b2014-12-01 13:54:59 -080064
Mike Lockwood67f8e8b2014-12-01 13:54:59 -080065 /**
66 * Bundle key for the device's manufacturer name property.
Mike Lockwood7eb441c2015-05-12 13:32:16 -070067 * The value for this property is of type {@link java.lang.String}.
Mike Lockwood67f8e8b2014-12-01 13:54:59 -080068 * Used with the {@link android.os.Bundle} returned by {@link #getProperties}.
69 * Matches the USB device manufacturer name string for USB MIDI devices.
70 */
71 public static final String PROPERTY_MANUFACTURER = "manufacturer";
72
73 /**
Mike Lockwoodf2cd8022015-03-11 08:50:41 -070074 * Bundle key for the device's product name property.
Mike Lockwood7eb441c2015-05-12 13:32:16 -070075 * The value for this property is of type {@link java.lang.String}.
Mike Lockwood67f8e8b2014-12-01 13:54:59 -080076 * Used with the {@link android.os.Bundle} returned by {@link #getProperties}
77 * Matches the USB device product name string for USB MIDI devices.
78 */
Mike Lockwoodf2cd8022015-03-11 08:50:41 -070079 public static final String PROPERTY_PRODUCT = "product";
Mike Lockwood67f8e8b2014-12-01 13:54:59 -080080
81 /**
Mike Lockwood02868b12015-04-29 13:44:34 -070082 * Bundle key for the device's version property.
Mike Lockwood7eb441c2015-05-12 13:32:16 -070083 * The value for this property is of type {@link java.lang.String}.
Mike Lockwood02868b12015-04-29 13:44:34 -070084 * Used with the {@link android.os.Bundle} returned by {@link #getProperties}
85 * Matches the USB device version number for USB MIDI devices.
86 */
87 public static final String PROPERTY_VERSION = "version";
88
89 /**
Mike Lockwood67f8e8b2014-12-01 13:54:59 -080090 * Bundle key for the device's serial number property.
Mike Lockwood7eb441c2015-05-12 13:32:16 -070091 * The value for this property is of type {@link java.lang.String}.
Mike Lockwood67f8e8b2014-12-01 13:54:59 -080092 * Used with the {@link android.os.Bundle} returned by {@link #getProperties}
93 * Matches the USB device serial number for USB MIDI devices.
94 */
95 public static final String PROPERTY_SERIAL_NUMBER = "serial_number";
96
97 /**
Mike Lockwood7eb441c2015-05-12 13:32:16 -070098 * Bundle key for the device's corresponding USB device.
99 * The value for this property is of type {@link android.hardware.usb.UsbDevice}.
Mike Lockwood67f8e8b2014-12-01 13:54:59 -0800100 * Only set for USB MIDI devices.
101 * Used with the {@link android.os.Bundle} returned by {@link #getProperties}
102 */
103 public static final String PROPERTY_USB_DEVICE = "usb_device";
104
105 /**
Mike Lockwood7eb441c2015-05-12 13:32:16 -0700106 * Bundle key for the device's corresponding Bluetooth device.
107 * The value for this property is of type {@link android.bluetooth.BluetoothDevice}.
Mike Lockwood3f5acc62015-03-17 13:21:03 -0700108 * Only set for Bluetooth MIDI devices.
109 * Used with the {@link android.os.Bundle} returned by {@link #getProperties}
110 */
111 public static final String PROPERTY_BLUETOOTH_DEVICE = "bluetooth_device";
112
113 /**
Mike Lockwood10024b32014-12-11 13:44:20 -0800114 * Bundle key for the device's ALSA card number.
Mike Lockwood7eb441c2015-05-12 13:32:16 -0700115 * The value for this property is an integer.
Mike Lockwood10024b32014-12-11 13:44:20 -0800116 * Only set for USB MIDI devices.
117 * Used with the {@link android.os.Bundle} returned by {@link #getProperties}
Mike Lockwood11fd96d2015-03-02 12:07:49 -0800118 *
119 * @hide
Mike Lockwood10024b32014-12-11 13:44:20 -0800120 */
121 public static final String PROPERTY_ALSA_CARD = "alsa_card";
122
123 /**
124 * Bundle key for the device's ALSA device number.
Mike Lockwood7eb441c2015-05-12 13:32:16 -0700125 * The value for this property is an integer.
Mike Lockwood10024b32014-12-11 13:44:20 -0800126 * Only set for USB MIDI devices.
127 * Used with the {@link android.os.Bundle} returned by {@link #getProperties}
Mike Lockwood11fd96d2015-03-02 12:07:49 -0800128 *
129 * @hide
Mike Lockwood10024b32014-12-11 13:44:20 -0800130 */
131 public static final String PROPERTY_ALSA_DEVICE = "alsa_device";
132
133 /**
Mike Lockwood7eb441c2015-05-12 13:32:16 -0700134 * ServiceInfo for the service hosting the device implementation.
135 * The value for this property is of type {@link android.content.pm.ServiceInfo}.
Mike Lockwood11fd96d2015-03-02 12:07:49 -0800136 * Only set for Virtual MIDI devices.
137 * Used with the {@link android.os.Bundle} returned by {@link #getProperties}
138 *
139 * @hide
140 */
141 public static final String PROPERTY_SERVICE_INFO = "service_info";
142
143 /**
Mike Lockwoodf2cd8022015-03-11 08:50:41 -0700144 * Contains information about an input or output port.
145 */
146 public static final class PortInfo {
147 /**
148 * Port type for input ports
149 */
150 public static final int TYPE_INPUT = 1;
151
152 /**
153 * Port type for output ports
154 */
155 public static final int TYPE_OUTPUT = 2;
156
157 private final int mPortType;
158 private final int mPortNumber;
159 private final String mName;
160
161 PortInfo(int type, int portNumber, String name) {
162 mPortType = type;
163 mPortNumber = portNumber;
164 mName = (name == null ? "" : name);
165 }
166
167 /**
168 * Returns the port type of the port (either {@link #TYPE_INPUT} or {@link #TYPE_OUTPUT})
169 * @return the port type
170 */
171 public int getType() {
172 return mPortType;
173 }
174
175 /**
176 * Returns the port number of the port
177 * @return the port number
178 */
179 public int getPortNumber() {
180 return mPortNumber;
181 }
182
183 /**
184 * Returns the name of the port, or empty string if the port has no name
185 * @return the port name
186 */
187 public String getName() {
188 return mName;
189 }
190 }
191
192 private final int mType; // USB or virtual
Paul McLean8a3e33b2017-03-14 15:20:51 -0700193 private final int mId; // unique ID generated by MidiService. Accessed from native code.
Mike Lockwoodf2cd8022015-03-11 08:50:41 -0700194 private final int mInputPortCount;
195 private final int mOutputPortCount;
196 private final String[] mInputPortNames;
197 private final String[] mOutputPortNames;
198 private final Bundle mProperties;
199 private final boolean mIsPrivate;
200
201 /**
Mike Lockwood67f8e8b2014-12-01 13:54:59 -0800202 * MidiDeviceInfo should only be instantiated by MidiService implementation
203 * @hide
204 */
Mike Lockwoodb6b9a912014-12-08 11:19:04 -0800205 public MidiDeviceInfo(int type, int id, int numInputPorts, int numOutputPorts,
Mike Lockwoodf2cd8022015-03-11 08:50:41 -0700206 String[] inputPortNames, String[] outputPortNames, Bundle properties,
207 boolean isPrivate) {
Mike Lockwood67f8e8b2014-12-01 13:54:59 -0800208 mType = type;
209 mId = id;
Mike Lockwoodb6b9a912014-12-08 11:19:04 -0800210 mInputPortCount = numInputPorts;
211 mOutputPortCount = numOutputPorts;
Mike Lockwood0caf6892015-03-16 16:03:17 -0700212 if (inputPortNames == null) {
213 mInputPortNames = new String[numInputPorts];
214 } else {
215 mInputPortNames = inputPortNames;
216 }
217 if (outputPortNames == null) {
218 mOutputPortNames = new String[numOutputPorts];
219 } else {
220 mOutputPortNames = outputPortNames;
221 }
Mike Lockwood67f8e8b2014-12-01 13:54:59 -0800222 mProperties = properties;
Mike Lockwood11fd96d2015-03-02 12:07:49 -0800223 mIsPrivate = isPrivate;
Mike Lockwood67f8e8b2014-12-01 13:54:59 -0800224 }
225
226 /**
227 * Returns the type of the device.
228 *
229 * @return the device's type
230 */
231 public int getType() {
232 return mType;
233 }
234
235 /**
236 * Returns the ID of the device.
237 * This ID is generated by the MIDI service and is not persistent across device unplugs.
238 *
239 * @return the device's ID
240 */
241 public int getId() {
242 return mId;
243 }
244
245 /**
Mike Lockwoodb6b9a912014-12-08 11:19:04 -0800246 * Returns the device's number of input ports.
247 *
248 * @return the number of input ports
249 */
250 public int getInputPortCount() {
251 return mInputPortCount;
252 }
253
254 /**
255 * Returns the device's number of output ports.
256 *
257 * @return the number of output ports
258 */
259 public int getOutputPortCount() {
260 return mOutputPortCount;
261 }
262
263 /**
Mike Lockwood9189f5f2015-04-09 17:51:32 -0700264 * Returns information about the device's ports.
265 * The ports are in unspecified order.
Mike Lockwoodf2cd8022015-03-11 08:50:41 -0700266 *
Mike Lockwood9189f5f2015-04-09 17:51:32 -0700267 * @return array of {@link PortInfo}
Mike Lockwoodf2cd8022015-03-11 08:50:41 -0700268 */
Mike Lockwood7eb441c2015-05-12 13:32:16 -0700269 public PortInfo[] getPorts() {
270 PortInfo[] ports = new PortInfo[mInputPortCount + mOutputPortCount];
Mike Lockwoodf2cd8022015-03-11 08:50:41 -0700271
Mike Lockwood9189f5f2015-04-09 17:51:32 -0700272 int index = 0;
273 for (int i = 0; i < mInputPortCount; i++) {
Mike Lockwood7eb441c2015-05-12 13:32:16 -0700274 ports[index++] = new PortInfo(PortInfo.TYPE_INPUT, i, mInputPortNames[i]);
Mike Lockwoodf2cd8022015-03-11 08:50:41 -0700275 }
Mike Lockwood9189f5f2015-04-09 17:51:32 -0700276 for (int i = 0; i < mOutputPortCount; i++) {
Mike Lockwood7eb441c2015-05-12 13:32:16 -0700277 ports[index++] = new PortInfo(PortInfo.TYPE_OUTPUT, i, mOutputPortNames[i]);
Mike Lockwood9189f5f2015-04-09 17:51:32 -0700278 }
279
Mike Lockwood7eb441c2015-05-12 13:32:16 -0700280 return ports;
Mike Lockwoodf2cd8022015-03-11 08:50:41 -0700281 }
282
283 /**
Mike Lockwood67f8e8b2014-12-01 13:54:59 -0800284 * Returns the {@link android.os.Bundle} containing the device's properties.
285 *
286 * @return the device's properties
287 */
288 public Bundle getProperties() {
289 return mProperties;
290 }
291
Mike Lockwood11fd96d2015-03-02 12:07:49 -0800292 /**
293 * Returns true if the device is private. Private devices are only visible and accessible
294 * to clients with the same UID as the application that is hosting the device.
295 *
296 * @return true if the device is private
297 */
298 public boolean isPrivate() {
299 return mIsPrivate;
300 }
301
Mike Lockwood67f8e8b2014-12-01 13:54:59 -0800302 @Override
303 public boolean equals(Object o) {
304 if (o instanceof MidiDeviceInfo) {
305 return (((MidiDeviceInfo)o).mId == mId);
306 } else {
307 return false;
308 }
309 }
310
311 @Override
312 public int hashCode() {
313 return mId;
314 }
315
316 @Override
317 public String toString() {
Mike Lockwoodfd5637f2015-05-07 13:02:01 -0700318 // This is a hack to force the mProperties Bundle to unparcel so we can
319 // print all the names and values.
320 mProperties.getString(PROPERTY_NAME);
Mike Lockwood67f8e8b2014-12-01 13:54:59 -0800321 return ("MidiDeviceInfo[mType=" + mType +
Mike Lockwoodb6b9a912014-12-08 11:19:04 -0800322 ",mInputPortCount=" + mInputPortCount +
323 ",mOutputPortCount=" + mOutputPortCount +
Mike Lockwood11fd96d2015-03-02 12:07:49 -0800324 ",mProperties=" + mProperties +
325 ",mIsPrivate=" + mIsPrivate);
Mike Lockwood67f8e8b2014-12-01 13:54:59 -0800326 }
327
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700328 public static final @android.annotation.NonNull Parcelable.Creator<MidiDeviceInfo> CREATOR =
Mike Lockwood67f8e8b2014-12-01 13:54:59 -0800329 new Parcelable.Creator<MidiDeviceInfo>() {
330 public MidiDeviceInfo createFromParcel(Parcel in) {
Mikhail Naganov84b67402016-09-15 11:00:57 -0700331 // Needs to be kept in sync with code in MidiDeviceInfo.cpp
Mike Lockwood67f8e8b2014-12-01 13:54:59 -0800332 int type = in.readInt();
333 int id = in.readInt();
Mikhail Naganov84b67402016-09-15 11:00:57 -0700334 int inputPortCount = in.readInt();
335 int outputPortCount = in.readInt();
Mike Lockwoodf2cd8022015-03-11 08:50:41 -0700336 String[] inputPortNames = in.createStringArray();
337 String[] outputPortNames = in.createStringArray();
Mike Lockwood11fd96d2015-03-02 12:07:49 -0800338 boolean isPrivate = (in.readInt() == 1);
Mikhail Naganov84b67402016-09-15 11:00:57 -0700339 Bundle basicPropertiesIgnored = in.readBundle();
340 Bundle properties = in.readBundle();
341 return new MidiDeviceInfo(type, id, inputPortCount, outputPortCount,
Mike Lockwoodf2cd8022015-03-11 08:50:41 -0700342 inputPortNames, outputPortNames, properties, isPrivate);
Mike Lockwood67f8e8b2014-12-01 13:54:59 -0800343 }
344
345 public MidiDeviceInfo[] newArray(int size) {
346 return new MidiDeviceInfo[size];
347 }
348 };
349
350 public int describeContents() {
351 return 0;
352 }
353
Mikhail Naganov84b67402016-09-15 11:00:57 -0700354 private Bundle getBasicProperties(String[] keys) {
355 Bundle basicProperties = new Bundle();
356 for (String key : keys) {
Mikhail Naganov33603ae2016-09-27 10:42:53 -0700357 Object val = mProperties.get(key);
Mikhail Naganov84b67402016-09-15 11:00:57 -0700358 if (val != null) {
Mikhail Naganov33603ae2016-09-27 10:42:53 -0700359 if (val instanceof String) {
360 basicProperties.putString(key, (String) val);
361 } else if (val instanceof Integer) {
362 basicProperties.putInt(key, (Integer) val);
363 } else {
364 Log.w(TAG, "Unsupported property type: " + val.getClass().getName());
365 }
Mikhail Naganov84b67402016-09-15 11:00:57 -0700366 }
367 }
368 return basicProperties;
369 }
370
Mike Lockwood67f8e8b2014-12-01 13:54:59 -0800371 public void writeToParcel(Parcel parcel, int flags) {
Mikhail Naganov84b67402016-09-15 11:00:57 -0700372 // Needs to be kept in sync with code in MidiDeviceInfo.cpp
Mike Lockwood67f8e8b2014-12-01 13:54:59 -0800373 parcel.writeInt(mType);
374 parcel.writeInt(mId);
Mike Lockwoodb6b9a912014-12-08 11:19:04 -0800375 parcel.writeInt(mInputPortCount);
376 parcel.writeInt(mOutputPortCount);
Mike Lockwoodf2cd8022015-03-11 08:50:41 -0700377 parcel.writeStringArray(mInputPortNames);
378 parcel.writeStringArray(mOutputPortNames);
Mike Lockwood11fd96d2015-03-02 12:07:49 -0800379 parcel.writeInt(mIsPrivate ? 1 : 0);
Mikhail Naganov84b67402016-09-15 11:00:57 -0700380 // "Basic" properties only contain properties of primitive types
381 // and thus can be read back by native code. "Extra" properties is
382 // a superset that contains all properties.
383 parcel.writeBundle(getBasicProperties(new String[] {
384 PROPERTY_NAME, PROPERTY_MANUFACTURER, PROPERTY_PRODUCT, PROPERTY_VERSION,
385 PROPERTY_SERIAL_NUMBER, PROPERTY_ALSA_CARD, PROPERTY_ALSA_DEVICE
386 }));
387 // Must be serialized last so native code can safely ignore it.
388 parcel.writeBundle(mProperties);
Mike Lockwood67f8e8b2014-12-01 13:54:59 -0800389 }
390}