Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(240)

Side by Side Diff: media/midi/midi_manager_android.cc

Issue 1177973003: [Web MIDI] Use Android MIDI API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/midi/midi_manager_android.h"
6
7 #include "base/android/build_info.h"
8 #include "base/command_line.h"
5 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/stringprintf.h"
11 #include "jni/MidiManagerAndroid_jni.h"
12 #include "media/midi/midi_device_android.h"
6 #include "media/midi/midi_manager_usb.h" 13 #include "media/midi/midi_manager_usb.h"
14 #include "media/midi/midi_output_port_android.h"
15 #include "media/midi/midi_switches.h"
7 #include "media/midi/usb_midi_device_factory_android.h" 16 #include "media/midi/usb_midi_device_factory_android.h"
8 17
9 namespace media { 18 namespace media {
10 namespace midi { 19 namespace midi {
11 20
12 MidiManager* MidiManager::Create() { 21 MidiManager* MidiManager::Create() {
13 return new MidiManagerUsb( 22 auto sdk_version = base::android::BuildInfo::GetInstance()->sdk_int();
14 scoped_ptr<UsbMidiDevice::Factory>(new UsbMidiDeviceFactoryAndroid)); 23 if (sdk_version <= base::android::SDK_VERSION_LOLLIPOP_MR1 ||
24 !base::CommandLine::ForCurrentProcess()->HasSwitch(
25 switches::kUseAndroidMidiApi)) {
26 return new MidiManagerUsb(
27 scoped_ptr<UsbMidiDevice::Factory>(new UsbMidiDeviceFactoryAndroid));
28 }
29
30 return new MidiManagerAndroid();
31 }
32
33 MidiManagerAndroid::MidiManagerAndroid() {}
34
35 MidiManagerAndroid::~MidiManagerAndroid() {}
36
37 void MidiManagerAndroid::StartInitialization() {
38 JNIEnv* env = base::android::AttachCurrentThread();
39
40 uintptr_t pointer = reinterpret_cast<uintptr_t>(this);
41 raw_manager_.Reset(Java_MidiManagerAndroid_create(
42 env, base::android::GetApplicationContext(), pointer));
43 scheduler_.reset(new MidiScheduler(this));
44 Java_MidiManagerAndroid_initialize(env, raw_manager_.obj());
45 }
46
47 void MidiManagerAndroid::DispatchSendMidiData(MidiManagerClient* client,
48 uint32 port_index,
49 const std::vector<uint8>& data,
50 double timestamp) {
51 if (port_index >= all_output_ports_.size()) {
52 // |port_index| is provided by a renderer so we can't believe that it is
53 // in the valid range.
54 return;
55 }
56 DCHECK_EQ(output_ports().size(), all_output_ports_.size());
57 if (output_ports()[port_index].state == MIDI_PORT_CONNECTED) {
58 // We treat send call as implicit open.
59 // TODO(yhirano): Implement explicit open operation from the renderer.
60 if (all_output_ports_[port_index]->Open()) {
61 SetOutputPortState(port_index, MIDI_PORT_OPENED);
62 } else {
63 // We cannot open the port. It's useless to send data to such a port.
64 return;
65 }
66 }
67
68 // output_streams_[port_index] is alive unless MidiManagerUsb is deleted.
69 // The task posted to the MidiScheduler will be disposed safely on deleting
70 // the scheduler.
71 scheduler_->PostSendDataTask(
72 client, data.size(), timestamp,
73 base::Bind(&MidiOutputPortAndroid::Send,
74 base::Unretained(all_output_ports_[port_index]), data));
75 }
76
77 void MidiManagerAndroid::OnReceivedData(MidiInputPortAndroid* port,
78 const uint8* data,
79 size_t size,
80 base::TimeTicks timestamp) {
81 const auto i = input_port_to_index_.find(port);
82 DCHECK(input_port_to_index_.end() != i);
83 ReceiveMidiData(i->second, data, size, timestamp);
84 }
85
86 void MidiManagerAndroid::OnInitialized(JNIEnv* env,
87 jobject caller,
88 jobjectArray devices) {
89 jsize length = env->GetArrayLength(devices);
90
91 for (jsize i = 0; i < length; ++i) {
92 jobject raw_device = env->GetObjectArrayElement(devices, i);
93 AddDevice(make_scoped_ptr(new MidiDeviceAndroid(env, raw_device, this)));
94 }
95 CompleteInitialization(Result::OK);
96 }
97
98 void MidiManagerAndroid::OnAttached(JNIEnv* env,
99 jobject caller,
100 jobject raw_device) {
101 AddDevice(make_scoped_ptr(new MidiDeviceAndroid(env, raw_device, this)));
102 }
103
104 void MidiManagerAndroid::OnDetached(JNIEnv* env,
105 jobject caller,
106 jobject raw_device) {
107 for (const auto& device : devices_) {
108 if (env->IsSameObject(device->raw_device(), raw_device)) {
109 for (const auto& port : device->input_ports()) {
110 DCHECK(input_port_to_index_.end() != input_port_to_index_.find(port));
111 size_t index = input_port_to_index_[port];
112 SetInputPortState(index, MIDI_PORT_DISCONNECTED);
113 }
114 for (const auto& port : device->output_ports()) {
115 DCHECK(output_port_to_index_.end() != output_port_to_index_.find(port));
116 size_t index = output_port_to_index_[port];
117 SetOutputPortState(index, MIDI_PORT_DISCONNECTED);
118 }
119 }
120 }
121 }
122
123 void MidiManagerAndroid::AddDevice(scoped_ptr<MidiDeviceAndroid> device) {
124 for (auto& port : device->input_ports()) {
125 // We implicitely open input ports here, because there are no signal
Takashi Toyoshima 2015/09/07 16:42:20 s/implicitely/implicitly/
yhirano 2015/09/10 11:43:50 Thanks, done.
126 // from the renderer when to open.
127 // TODO(yhirano): Implement open operation in Blink.
128 MidiPortState state = port->Open() ? MIDI_PORT_OPENED : MIDI_PORT_CONNECTED;
129
130 const size_t index = all_input_ports_.size();
131 all_input_ports_.push_back(port);
132 // Port ID must be unique in a MIDI manager. This ID setting is
133 // sufficiently unique although there is no user-friendly meaning.
134 // TODO(yhirano): Use a hashed string as ID.
135 const std::string id(
136 base::StringPrintf("native:port-in-%ld", static_cast<long>(index)));
137
138 input_port_to_index_.insert(std::make_pair(port, index));
139 AddInputPort(MidiPortInfo(id, device->GetManufacturer(),
140 device->GetProductName(),
141 device->GetDeviceVersion(), state));
142 }
143 for (const auto& port : device->output_ports()) {
144 const size_t index = all_output_ports_.size();
145 all_output_ports_.push_back(port);
146
147 // Port ID must be unique in a MIDI manager. This ID setting is
148 // sufficiently unique although there is no user-friendly meaning.
149 // TODO(yhirano): Use a hashed string as ID.
150 const std::string id(
151 base::StringPrintf("native:port-out-%ld", static_cast<long>(index)));
152
153 output_port_to_index_.insert(std::make_pair(port, index));
154 AddOutputPort(
155 MidiPortInfo(id, device->GetManufacturer(), device->GetProductName(),
156 device->GetDeviceVersion(), MIDI_PORT_CONNECTED));
157 }
158 devices_.push_back(device.release());
159 }
160
161 bool MidiManagerAndroid::Register(JNIEnv* env) {
162 return RegisterNativesImpl(env);
15 } 163 }
16 164
17 } // namespace midi 165 } // namespace midi
18 } // namespace media 166 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698