Index: media/midi/usb_midi_device_android.cc |
diff --git a/media/midi/usb_midi_device_android.cc b/media/midi/usb_midi_device_android.cc |
index ff58e624d3989186b03db8df4565f2a38222343f..f62eb86eb545eb797b6b00ed75ca77aff9559668 100644 |
--- a/media/midi/usb_midi_device_android.cc |
+++ b/media/midi/usb_midi_device_android.cc |
@@ -8,8 +8,11 @@ |
#include <vector> |
#include "base/android/jni_array.h" |
+#include "base/i18n/icu_string_conversions.h" |
+#include "base/strings/stringprintf.h" |
#include "base/time/time.h" |
#include "jni/UsbMidiDeviceAndroid_jni.h" |
+#include "media/midi/usb_midi_descriptor_parser.h" |
namespace media { |
@@ -19,6 +22,9 @@ UsbMidiDeviceAndroid::UsbMidiDeviceAndroid(ObjectRef raw_device, |
JNIEnv* env = base::android::AttachCurrentThread(); |
Java_UsbMidiDeviceAndroid_registerSelf( |
env, raw_device_.obj(), reinterpret_cast<jlong>(this)); |
+ |
+ GetDescriptorsInternal(); |
+ InitDeviceInfo(); |
} |
UsbMidiDeviceAndroid::~UsbMidiDeviceAndroid() { |
@@ -26,14 +32,20 @@ UsbMidiDeviceAndroid::~UsbMidiDeviceAndroid() { |
Java_UsbMidiDeviceAndroid_close(env, raw_device_.obj()); |
} |
-std::vector<uint8> UsbMidiDeviceAndroid::GetDescriptor() { |
- JNIEnv* env = base::android::AttachCurrentThread(); |
- base::android::ScopedJavaLocalRef<jbyteArray> descriptors = |
- Java_UsbMidiDeviceAndroid_getDescriptors(env, raw_device_.obj()); |
+std::vector<uint8> UsbMidiDeviceAndroid::GetDescriptors() { |
+ return descriptors_; |
+} |
- std::vector<uint8> ret; |
- base::android::JavaByteArrayToByteVector(env, descriptors.obj(), &ret); |
- return ret; |
+std::string UsbMidiDeviceAndroid::GetManufacturer() { |
+ return manufacturer_; |
+} |
+ |
+std::string UsbMidiDeviceAndroid::GetProductName() { |
+ return product_; |
+} |
+ |
+std::string UsbMidiDeviceAndroid::GetDeviceVersion() { |
+ return device_version_; |
} |
void UsbMidiDeviceAndroid::Send(int endpoint_number, |
@@ -63,4 +75,71 @@ bool UsbMidiDeviceAndroid::RegisterUsbMidiDevice(JNIEnv* env) { |
return RegisterNativesImpl(env); |
} |
+void UsbMidiDeviceAndroid::GetDescriptorsInternal() { |
+ JNIEnv* env = base::android::AttachCurrentThread(); |
+ base::android::ScopedJavaLocalRef<jbyteArray> descriptors = |
+ Java_UsbMidiDeviceAndroid_getDescriptors(env, raw_device_.obj()); |
+ |
+ base::android::JavaByteArrayToByteVector(env, descriptors.obj(), |
+ &descriptors_); |
+} |
+ |
+void UsbMidiDeviceAndroid::InitDeviceInfo() { |
+ UsbMidiDescriptorParser parser; |
+ UsbMidiDescriptorParser::DeviceInfo info; |
+ |
+ const uint8* data = descriptors_.size() > 0 ? &descriptors_[0] : nullptr; |
+ |
+ if (!parser.ParseDeviceInfo(data, descriptors_.size(), &info)) { |
+ // We don't report the error here. If it is critical, we will realize it |
+ // when we parse the descriptors again for ports. |
+ manufacturer_ = "invalid descriptor"; |
+ product_ = "invalid descriptor"; |
+ device_version_ = "invalid descriptor"; |
+ return; |
+ } |
+ |
+ manufacturer_ = |
+ GetString(info.manufacturer_index, |
+ base::StringPrintf("(vendor id = 0x%04x)", info.vendor_id)); |
+ product_ = |
+ GetString(info.product_index, |
+ base::StringPrintf("(product id = 0x%04x)", info.product_id)); |
+ device_version_ = info.BcdVersionToString(info.bcd_device_version); |
+} |
+ |
+std::vector<uint8> UsbMidiDeviceAndroid::GetStringDescriptor(int index) { |
+ JNIEnv* env = base::android::AttachCurrentThread(); |
+ base::android::ScopedJavaLocalRef<jbyteArray> descriptors = |
+ Java_UsbMidiDeviceAndroid_getStringDescriptor(env, raw_device_.obj(), |
+ index); |
+ |
+ std::vector<uint8> ret; |
+ base::android::JavaByteArrayToByteVector(env, descriptors.obj(), &ret); |
+ return ret; |
+} |
+ |
+std::string UsbMidiDeviceAndroid::GetString(int index, |
+ const std::string& backup) { |
+ const uint8 DESCRIPTOR_TYPE_STRING = 3; |
+ |
+ if (!index) { |
+ // index 0 means there is no such descriptor. |
+ return backup; |
+ } |
+ std::vector<uint8> descriptor = GetStringDescriptor(index); |
+ if (descriptor.size() < 2 || descriptor.size() < descriptor[0] || |
+ descriptor[1] != DESCRIPTOR_TYPE_STRING) { |
+ // |descriptor| is not a valid string descriptor. |
+ return backup; |
+ } |
+ size_t size = descriptor[0]; |
+ std::string encoded(reinterpret_cast<char*>(&descriptor[0]) + 2, size - 2); |
+ std::string result; |
+ // Unicode ECN specifies that the string is encoded in UTF-16LE. |
+ if (!base::ConvertToUtf8AndNormalize(encoded, "utf-16le", &result)) |
+ return backup; |
+ return result; |
+} |
+ |
} // namespace media |