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. 4 5 #include "media/midi/usb_midi_device_factory_android.h" 6 7 #include <jni.h> 8 #include <vector> 9 10 #include "base/android/scoped_java_ref.h" 11 #include "base/bind.h" 12 #include "base/containers/hash_tables.h" 13 #include "base/lazy_instance.h" 14 #include "base/memory/scoped_vector.h" 15 #include "base/message_loop/message_loop.h" 16 #include "base/synchronization/lock.h" 17 #include "jni/UsbMidiDeviceFactoryAndroid_jni.h" 18 #include "media/midi/usb_midi_device_android.h" 19 20 namespace media { 21 22 namespace { 23 24 typedef UsbMidiDevice::Factory::Callback Callback; 25 26 } // namespace 27 28 UsbMidiDeviceFactoryAndroid::UsbMidiDeviceFactoryAndroid() : delegate_(NULL) {} 29 30 UsbMidiDeviceFactoryAndroid::~UsbMidiDeviceFactoryAndroid() { 31 JNIEnv* env = base::android::AttachCurrentThread(); 32 if (!raw_factory_.is_null()) 33 Java_UsbMidiDeviceFactoryAndroid_close(env, raw_factory_.obj()); 34 } 35 36 void UsbMidiDeviceFactoryAndroid::EnumerateDevices( 37 UsbMidiDeviceDelegate* delegate, 38 Callback callback) { 39 DCHECK(!delegate_); 40 JNIEnv* env = base::android::AttachCurrentThread(); 41 uintptr_t pointer = reinterpret_cast<uintptr_t>(this); 42 raw_factory_.Reset(Java_UsbMidiDeviceFactoryAndroid_create(env, pointer)); 43 44 delegate_ = delegate; 45 callback_ = callback; 46 47 if (Java_UsbMidiDeviceFactoryAndroid_enumerateDevices( 48 env, raw_factory_.obj(), base::android::GetApplicationContext())) { 49 // Asynchronous operation. 50 return; 51 } 52 // No devices are found. 53 ScopedVector<UsbMidiDevice> devices; 54 callback.Run(true, &devices); 55 } 56 57 // Called from the Java world. 58 void UsbMidiDeviceFactoryAndroid::OnUsbMidiDeviceRequestDone( 59 JNIEnv* env, 60 jobject caller, 61 jobjectArray devices) { 62 size_t size = env->GetArrayLength(devices); 63 ScopedVector<UsbMidiDevice> devices_to_pass; 64 for (size_t i = 0; i < size; ++i) { 65 UsbMidiDeviceAndroid::ObjectRef raw_device( 66 env, env->GetObjectArrayElement(devices, i)); 67 devices_to_pass.push_back(new UsbMidiDeviceAndroid(raw_device, delegate_)); 68 } 69 70 callback_.Run(true, &devices_to_pass); 71 } 72 73 bool UsbMidiDeviceFactoryAndroid::RegisterUsbMidiDeviceFactory(JNIEnv* env) { 74 return RegisterNativesImpl(env); 75 } 76 77 } // namespace media 78