123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- // Copyright 2014 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "media/midi/usb_midi_device_android.h"
- #include <stddef.h>
- #include "base/android/jni_array.h"
- #include "base/i18n/icu_string_conversions.h"
- #include "base/strings/stringprintf.h"
- #include "base/time/time.h"
- #include "media/midi/midi_jni_headers/UsbMidiDeviceAndroid_jni.h"
- #include "media/midi/usb_midi_descriptor_parser.h"
- using base::android::JavaParamRef;
- using base::android::ScopedJavaLocalRef;
- namespace midi {
- UsbMidiDeviceAndroid::UsbMidiDeviceAndroid(
- const base::android::JavaRef<jobject>& raw_device,
- UsbMidiDeviceDelegate* delegate)
- : raw_device_(raw_device), delegate_(delegate) {
- JNIEnv* env = base::android::AttachCurrentThread();
- Java_UsbMidiDeviceAndroid_registerSelf(env, raw_device_,
- reinterpret_cast<jlong>(this));
- GetDescriptorsInternal();
- InitDeviceInfo();
- }
- UsbMidiDeviceAndroid::~UsbMidiDeviceAndroid() {
- JNIEnv* env = base::android::AttachCurrentThread();
- Java_UsbMidiDeviceAndroid_close(env, raw_device_);
- }
- std::vector<uint8_t> UsbMidiDeviceAndroid::GetDescriptors() {
- return descriptors_;
- }
- 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,
- const std::vector<uint8_t>& data) {
- JNIEnv* env = base::android::AttachCurrentThread();
- const uint8_t* head = data.size() ? &data[0] : NULL;
- ScopedJavaLocalRef<jbyteArray> data_to_pass =
- base::android::ToJavaByteArray(env, head, data.size());
- Java_UsbMidiDeviceAndroid_send(env, raw_device_, endpoint_number,
- data_to_pass);
- }
- void UsbMidiDeviceAndroid::OnData(JNIEnv* env,
- jint endpoint_number,
- const JavaParamRef<jbyteArray>& data) {
- std::vector<uint8_t> bytes;
- base::android::JavaByteArrayToByteVector(env, data, &bytes);
- const uint8_t* head = bytes.size() ? &bytes[0] : NULL;
- delegate_->ReceiveUsbMidiData(this, endpoint_number, head, bytes.size(),
- base::TimeTicks::Now());
- }
- void UsbMidiDeviceAndroid::GetDescriptorsInternal() {
- JNIEnv* env = base::android::AttachCurrentThread();
- base::android::ScopedJavaLocalRef<jbyteArray> descriptors =
- Java_UsbMidiDeviceAndroid_getDescriptors(env, raw_device_);
- base::android::JavaByteArrayToByteVector(env, descriptors, &descriptors_);
- }
- void UsbMidiDeviceAndroid::InitDeviceInfo() {
- UsbMidiDescriptorParser parser;
- UsbMidiDescriptorParser::DeviceInfo info;
- const uint8_t* 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_t> UsbMidiDeviceAndroid::GetStringDescriptor(int index) {
- JNIEnv* env = base::android::AttachCurrentThread();
- base::android::ScopedJavaLocalRef<jbyteArray> descriptors =
- Java_UsbMidiDeviceAndroid_getStringDescriptor(env, raw_device_, index);
- std::vector<uint8_t> ret;
- base::android::JavaByteArrayToByteVector(env, descriptors, &ret);
- return ret;
- }
- std::string UsbMidiDeviceAndroid::GetString(int index,
- const std::string& backup) {
- const uint8_t DESCRIPTOR_TYPE_STRING = 3;
- if (!index) {
- // index 0 means there is no such descriptor.
- return backup;
- }
- std::vector<uint8_t> 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 midi
|