// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "device/bluetooth/bluetooth_adapter_android.h" #include "base/android/jni_android.h" #include "base/android/jni_string.h" #include "base/sequenced_task_runner.h" #include "base/single_thread_task_runner.h" #include "base/thread_task_runner_handle.h" #include "device/bluetooth/android/wrappers.h" #include "device/bluetooth/bluetooth_advertisement.h" #include "device/bluetooth/bluetooth_device_android.h" #include "device/bluetooth/bluetooth_discovery_session_outcome.h" #include "jni/ChromeBluetoothAdapter_jni.h" using base::android::AttachCurrentThread; using base::android::ConvertJavaStringToUTF8; namespace device { // static base::WeakPtr BluetoothAdapter::CreateAdapter( const InitCallback& init_callback) { return BluetoothAdapterAndroid::Create( BluetoothAdapterWrapper_CreateWithDefaultAdapter().obj()); } // static base::WeakPtr BluetoothAdapterAndroid::Create( jobject bluetooth_adapter_wrapper) { // Java Type: bluetoothAdapterWrapper BluetoothAdapterAndroid* adapter = new BluetoothAdapterAndroid(); adapter->j_adapter_.Reset(Java_ChromeBluetoothAdapter_create( AttachCurrentThread(), reinterpret_cast(adapter), bluetooth_adapter_wrapper)); return adapter->weak_ptr_factory_.GetWeakPtr(); } // static bool BluetoothAdapterAndroid::RegisterJNI(JNIEnv* env) { return RegisterNativesImpl(env); // Generated in BluetoothAdapter_jni.h } std::string BluetoothAdapterAndroid::GetAddress() const { return ConvertJavaStringToUTF8(Java_ChromeBluetoothAdapter_getAddress( AttachCurrentThread(), j_adapter_.obj())); } std::string BluetoothAdapterAndroid::GetName() const { return ConvertJavaStringToUTF8(Java_ChromeBluetoothAdapter_getName( AttachCurrentThread(), j_adapter_.obj())); } void BluetoothAdapterAndroid::SetName(const std::string& name, const base::Closure& callback, const ErrorCallback& error_callback) { NOTIMPLEMENTED(); } bool BluetoothAdapterAndroid::IsInitialized() const { return true; } bool BluetoothAdapterAndroid::IsPresent() const { return Java_ChromeBluetoothAdapter_isPresent(AttachCurrentThread(), j_adapter_.obj()); } bool BluetoothAdapterAndroid::IsPowered() const { return Java_ChromeBluetoothAdapter_isPowered(AttachCurrentThread(), j_adapter_.obj()); } void BluetoothAdapterAndroid::SetPowered(bool powered, const base::Closure& callback, const ErrorCallback& error_callback) { if (Java_ChromeBluetoothAdapter_setPowered(AttachCurrentThread(), j_adapter_.obj(), powered)) { callback.Run(); } else { error_callback.Run(); } } bool BluetoothAdapterAndroid::IsDiscoverable() const { return Java_ChromeBluetoothAdapter_isDiscoverable(AttachCurrentThread(), j_adapter_.obj()); } void BluetoothAdapterAndroid::SetDiscoverable( bool discoverable, const base::Closure& callback, const ErrorCallback& error_callback) { NOTIMPLEMENTED(); } bool BluetoothAdapterAndroid::IsDiscovering() const { return Java_ChromeBluetoothAdapter_isDiscovering(AttachCurrentThread(), j_adapter_.obj()); } void BluetoothAdapterAndroid::CreateRfcommService( const BluetoothUUID& uuid, const ServiceOptions& options, const CreateServiceCallback& callback, const CreateServiceErrorCallback& error_callback) { NOTIMPLEMENTED(); error_callback.Run("Not Implemented"); } void BluetoothAdapterAndroid::CreateL2capService( const BluetoothUUID& uuid, const ServiceOptions& options, const CreateServiceCallback& callback, const CreateServiceErrorCallback& error_callback) { NOTIMPLEMENTED(); error_callback.Run("Not Implemented"); } void BluetoothAdapterAndroid::RegisterAudioSink( const BluetoothAudioSink::Options& options, const AcquiredCallback& callback, const BluetoothAudioSink::ErrorCallback& error_callback) { error_callback.Run(BluetoothAudioSink::ERROR_UNSUPPORTED_PLATFORM); } void BluetoothAdapterAndroid::RegisterAdvertisement( scoped_ptr advertisement_data, const CreateAdvertisementCallback& callback, const CreateAdvertisementErrorCallback& error_callback) { error_callback.Run(BluetoothAdvertisement::ERROR_UNSUPPORTED_PLATFORM); } void BluetoothAdapterAndroid::OnAdapterStateChanged( JNIEnv* env, const JavaParamRef& caller, const bool powered) { NotifyAdapterStateChanged(powered); } void BluetoothAdapterAndroid::OnScanFailed( JNIEnv* env, const JavaParamRef& caller) { MarkDiscoverySessionsAsInactive(); } void BluetoothAdapterAndroid::CreateOrUpdateDeviceOnScan( JNIEnv* env, const JavaParamRef& caller, const JavaParamRef& address, const JavaParamRef& bluetooth_device_wrapper, // Java Type: bluetoothDeviceWrapper const JavaParamRef& advertised_uuids) { // Java Type: List std::string device_address = ConvertJavaStringToUTF8(env, address); DevicesMap::const_iterator iter = devices_.find(device_address); if (iter == devices_.end()) { // New device. BluetoothDeviceAndroid* device_android = BluetoothDeviceAndroid::Create(this, bluetooth_device_wrapper); device_android->UpdateAdvertisedUUIDs(advertised_uuids); devices_.add(device_address, scoped_ptr(device_android)); FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, DeviceAdded(this, device_android)); } else { // Existing device. BluetoothDeviceAndroid* device_android = static_cast(iter->second); if (device_android->UpdateAdvertisedUUIDs(advertised_uuids)) { FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, DeviceChanged(this, device_android)); } } } BluetoothAdapterAndroid::BluetoothAdapterAndroid() : weak_ptr_factory_(this) { } BluetoothAdapterAndroid::~BluetoothAdapterAndroid() { Java_ChromeBluetoothAdapter_onBluetoothAdapterAndroidDestruction( AttachCurrentThread(), j_adapter_.obj()); } void BluetoothAdapterAndroid::AddDiscoverySession( BluetoothDiscoveryFilter* discovery_filter, const base::Closure& callback, const DiscoverySessionErrorCallback& error_callback) { // TODO(scheib): Support filters crbug.com/490401 if (Java_ChromeBluetoothAdapter_addDiscoverySession(AttachCurrentThread(), j_adapter_.obj())) { callback.Run(); } else { // TODO(scheib): Eventually wire the SCAN_FAILED result through to here. error_callback.Run(UMABluetoothDiscoverySessionOutcome::UNKNOWN); } } void BluetoothAdapterAndroid::RemoveDiscoverySession( BluetoothDiscoveryFilter* discovery_filter, const base::Closure& callback, const DiscoverySessionErrorCallback& error_callback) { if (Java_ChromeBluetoothAdapter_removeDiscoverySession(AttachCurrentThread(), j_adapter_.obj())) { callback.Run(); } else { // TODO(scheib): Eventually wire the SCAN_FAILED result through to here. error_callback.Run(UMABluetoothDiscoverySessionOutcome::UNKNOWN); } } void BluetoothAdapterAndroid::SetDiscoveryFilter( scoped_ptr discovery_filter, const base::Closure& callback, const DiscoverySessionErrorCallback& error_callback) { // TODO(scheib): Support filters crbug.com/490401 NOTIMPLEMENTED(); error_callback.Run(UMABluetoothDiscoverySessionOutcome::NOT_IMPLEMENTED); } void BluetoothAdapterAndroid::RemovePairingDelegateInternal( device::BluetoothDevice::PairingDelegate* pairing_delegate) { } } // namespace device