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 20namespace media { 21 22namespace { 23 24typedef UsbMidiDevice::Factory::Callback Callback; 25 26} // namespace 27 28UsbMidiDeviceFactoryAndroid::UsbMidiDeviceFactoryAndroid() : delegate_(NULL) {} 29 30UsbMidiDeviceFactoryAndroid::~UsbMidiDeviceFactoryAndroid() { 31 JNIEnv* env = base::android::AttachCurrentThread(); 32 if (!raw_factory_.is_null()) 33 Java_UsbMidiDeviceFactoryAndroid_close(env, raw_factory_.obj()); 34} 35 36void 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. 58void 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 73bool UsbMidiDeviceFactoryAndroid::RegisterUsbMidiDeviceFactory(JNIEnv* env) { 74 return RegisterNativesImpl(env); 75} 76 77} // namespace media 78