Supervised user import: Listen for profile creation/deletion
[chromium-blink-merge.git] / media / midi / usb_midi_device_android.cc
blobf62eb86eb545eb797b6b00ed75ca77aff9559668
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/midi/usb_midi_device_android.h"
7 #include <jni.h>
8 #include <vector>
10 #include "base/android/jni_array.h"
11 #include "base/i18n/icu_string_conversions.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/time/time.h"
14 #include "jni/UsbMidiDeviceAndroid_jni.h"
15 #include "media/midi/usb_midi_descriptor_parser.h"
17 namespace media {
19 UsbMidiDeviceAndroid::UsbMidiDeviceAndroid(ObjectRef raw_device,
20 UsbMidiDeviceDelegate* delegate)
21 : raw_device_(raw_device), delegate_(delegate) {
22 JNIEnv* env = base::android::AttachCurrentThread();
23 Java_UsbMidiDeviceAndroid_registerSelf(
24 env, raw_device_.obj(), reinterpret_cast<jlong>(this));
26 GetDescriptorsInternal();
27 InitDeviceInfo();
30 UsbMidiDeviceAndroid::~UsbMidiDeviceAndroid() {
31 JNIEnv* env = base::android::AttachCurrentThread();
32 Java_UsbMidiDeviceAndroid_close(env, raw_device_.obj());
35 std::vector<uint8> UsbMidiDeviceAndroid::GetDescriptors() {
36 return descriptors_;
39 std::string UsbMidiDeviceAndroid::GetManufacturer() {
40 return manufacturer_;
43 std::string UsbMidiDeviceAndroid::GetProductName() {
44 return product_;
47 std::string UsbMidiDeviceAndroid::GetDeviceVersion() {
48 return device_version_;
51 void UsbMidiDeviceAndroid::Send(int endpoint_number,
52 const std::vector<uint8>& data) {
53 JNIEnv* env = base::android::AttachCurrentThread();
54 const uint8* head = data.size() ? &data[0] : NULL;
55 ScopedJavaLocalRef<jbyteArray> data_to_pass =
56 base::android::ToJavaByteArray(env, head, data.size());
58 Java_UsbMidiDeviceAndroid_send(
59 env, raw_device_.obj(), endpoint_number, data_to_pass.obj());
62 void UsbMidiDeviceAndroid::OnData(JNIEnv* env,
63 jobject caller,
64 jint endpoint_number,
65 jbyteArray data) {
66 std::vector<uint8> bytes;
67 base::android::JavaByteArrayToByteVector(env, data, &bytes);
69 const uint8* head = bytes.size() ? &bytes[0] : NULL;
70 delegate_->ReceiveUsbMidiData(this, endpoint_number, head, bytes.size(),
71 base::TimeTicks::Now());
74 bool UsbMidiDeviceAndroid::RegisterUsbMidiDevice(JNIEnv* env) {
75 return RegisterNativesImpl(env);
78 void UsbMidiDeviceAndroid::GetDescriptorsInternal() {
79 JNIEnv* env = base::android::AttachCurrentThread();
80 base::android::ScopedJavaLocalRef<jbyteArray> descriptors =
81 Java_UsbMidiDeviceAndroid_getDescriptors(env, raw_device_.obj());
83 base::android::JavaByteArrayToByteVector(env, descriptors.obj(),
84 &descriptors_);
87 void UsbMidiDeviceAndroid::InitDeviceInfo() {
88 UsbMidiDescriptorParser parser;
89 UsbMidiDescriptorParser::DeviceInfo info;
91 const uint8* data = descriptors_.size() > 0 ? &descriptors_[0] : nullptr;
93 if (!parser.ParseDeviceInfo(data, descriptors_.size(), &info)) {
94 // We don't report the error here. If it is critical, we will realize it
95 // when we parse the descriptors again for ports.
96 manufacturer_ = "invalid descriptor";
97 product_ = "invalid descriptor";
98 device_version_ = "invalid descriptor";
99 return;
102 manufacturer_ =
103 GetString(info.manufacturer_index,
104 base::StringPrintf("(vendor id = 0x%04x)", info.vendor_id));
105 product_ =
106 GetString(info.product_index,
107 base::StringPrintf("(product id = 0x%04x)", info.product_id));
108 device_version_ = info.BcdVersionToString(info.bcd_device_version);
111 std::vector<uint8> UsbMidiDeviceAndroid::GetStringDescriptor(int index) {
112 JNIEnv* env = base::android::AttachCurrentThread();
113 base::android::ScopedJavaLocalRef<jbyteArray> descriptors =
114 Java_UsbMidiDeviceAndroid_getStringDescriptor(env, raw_device_.obj(),
115 index);
117 std::vector<uint8> ret;
118 base::android::JavaByteArrayToByteVector(env, descriptors.obj(), &ret);
119 return ret;
122 std::string UsbMidiDeviceAndroid::GetString(int index,
123 const std::string& backup) {
124 const uint8 DESCRIPTOR_TYPE_STRING = 3;
126 if (!index) {
127 // index 0 means there is no such descriptor.
128 return backup;
130 std::vector<uint8> descriptor = GetStringDescriptor(index);
131 if (descriptor.size() < 2 || descriptor.size() < descriptor[0] ||
132 descriptor[1] != DESCRIPTOR_TYPE_STRING) {
133 // |descriptor| is not a valid string descriptor.
134 return backup;
136 size_t size = descriptor[0];
137 std::string encoded(reinterpret_cast<char*>(&descriptor[0]) + 2, size - 2);
138 std::string result;
139 // Unicode ECN specifies that the string is encoded in UTF-16LE.
140 if (!base::ConvertToUtf8AndNormalize(encoded, "utf-16le", &result))
141 return backup;
142 return result;
145 } // namespace media