15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/midi/usb_midi_device_factory_android.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <jni.h> 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <vector> 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/android/scoped_java_ref.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/bind.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/containers/hash_tables.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/lazy_instance.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/scoped_vector.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/message_loop/message_loop.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/synchronization/lock.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "jni/UsbMidiDeviceFactoryAndroid_jni.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/midi/usb_midi_device_android.h" 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace media { 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)typedef UsbMidiDevice::Factory::Callback Callback; 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)UsbMidiDeviceFactoryAndroid::UsbMidiDeviceFactoryAndroid() : delegate_(NULL) {} 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)UsbMidiDeviceFactoryAndroid::~UsbMidiDeviceFactoryAndroid() { 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JNIEnv* env = base::android::AttachCurrentThread(); 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!raw_factory_.is_null()) 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Java_UsbMidiDeviceFactoryAndroid_close(env, raw_factory_.obj()); 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void UsbMidiDeviceFactoryAndroid::EnumerateDevices( 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UsbMidiDeviceDelegate* delegate, 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Callback callback) { 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!delegate_); 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JNIEnv* env = base::android::AttachCurrentThread(); 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uintptr_t pointer = reinterpret_cast<uintptr_t>(this); 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raw_factory_.Reset(Java_UsbMidiDeviceFactoryAndroid_create(env, pointer)); 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delegate_ = delegate; 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_ = callback; 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (Java_UsbMidiDeviceFactoryAndroid_enumerateDevices( 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) env, raw_factory_.obj(), base::android::GetApplicationContext())) { 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Asynchronous operation. 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // No devices are found. 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedVector<UsbMidiDevice> devices; 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(true, &devices); 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Called from the Java world. 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void UsbMidiDeviceFactoryAndroid::OnUsbMidiDeviceRequestDone( 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JNIEnv* env, 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) jobject caller, 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) jobjectArray devices) { 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t size = env->GetArrayLength(devices); 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedVector<UsbMidiDevice> devices_to_pass; 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i < size; ++i) { 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UsbMidiDeviceAndroid::ObjectRef raw_device( 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) env, env->GetObjectArrayElement(devices, i)); 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) devices_to_pass.push_back(new UsbMidiDeviceAndroid(raw_device, delegate_)); 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_.Run(true, &devices_to_pass); 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool UsbMidiDeviceFactoryAndroid::RegisterUsbMidiDeviceFactory(JNIEnv* env) { 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return RegisterNativesImpl(env); 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace media 78