Commit 8bd80fe5 authored by mbrunson's avatar mbrunson Committed by Commit bot

bluetooth: Standardize Bluetooth adapter access in Adapter service.

Every implemented function of the Adapter Mojo service requires a
reference to the system's Bluetooth adapter. Since any function could be called
at any time in the service, the adapter must be available from the creation of
the Adapter service. To satisfy this requirement, a factory pattern has been
implemented to create instances of the Adapter service with the required
reference to a Bluetooth adapter.
BUG=651282
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:closure_compilation

Review-Url: https://codereview.chromium.org/2379573006
Cr-Commit-Position: refs/heads/master@{#423730}
parent 7aa93831
...@@ -170,7 +170,7 @@ ...@@ -170,7 +170,7 @@
#include "content/public/common/service_names.h" #include "content/public/common/service_names.h"
#include "content/public/common/url_utils.h" #include "content/public/common/url_utils.h"
#include "content/public/common/web_preferences.h" #include "content/public/common/web_preferences.h"
#include "device/bluetooth/adapter.h" #include "device/bluetooth/adapter_factory.h"
#include "device/bluetooth/public/interfaces/adapter.mojom.h" #include "device/bluetooth/public/interfaces/adapter.mojom.h"
#include "device/usb/public/interfaces/chooser_service.mojom.h" #include "device/usb/public/interfaces/chooser_service.mojom.h"
#include "device/usb/public/interfaces/device_manager.mojom.h" #include "device/usb/public/interfaces/device_manager.mojom.h"
...@@ -2979,8 +2979,8 @@ void ChromeContentBrowserClient::RegisterRenderFrameMojoInterfaces( ...@@ -2979,8 +2979,8 @@ void ChromeContentBrowserClient::RegisterRenderFrameMojoInterfaces(
base::Bind(&CreateWebUsbChooserService, render_frame_host)); base::Bind(&CreateWebUsbChooserService, render_frame_host));
} }
registry->AddInterface<bluetooth::mojom::Adapter>( registry->AddInterface<bluetooth::mojom::AdapterFactory>(
base::Bind(&bluetooth::Adapter::Create)); base::Bind(&bluetooth::AdapterFactory::Create));
if (!render_frame_host->GetParent()) { if (!render_frame_host->GetParent()) {
// Register mojo CredentialManager interface only for main frame. // Register mojo CredentialManager interface only for main frame.
......
...@@ -33,9 +33,7 @@ AdapterClient.prototype = { ...@@ -33,9 +33,7 @@ AdapterClient.prototype = {
}; };
(function() { (function() {
var adapter = null; var adapter, adapterClient;
var adapterClient = null;
var adapterClientHandle = null;
/** /**
* TODO: Move to shared location. See crbug.com/652361. * TODO: Move to shared location. See crbug.com/652361.
...@@ -53,7 +51,8 @@ AdapterClient.prototype = { ...@@ -53,7 +51,8 @@ AdapterClient.prototype = {
/** /**
* Initializes Mojo proxies for page and Bluetooth services. * Initializes Mojo proxies for page and Bluetooth services.
* @return {!Promise} * @return {!Promise} resolves if adapter is acquired, rejects if Bluetooth
* is not supported.
*/ */
function initializeProxies() { function initializeProxies() {
return importModules([ return importModules([
...@@ -67,22 +66,31 @@ AdapterClient.prototype = { ...@@ -67,22 +66,31 @@ AdapterClient.prototype = {
AdapterClient.prototype.__proto__ = AdapterClient.prototype.__proto__ =
bluetoothAdapter.AdapterClient.stubClass.prototype; bluetoothAdapter.AdapterClient.stubClass.prototype;
// Create a message pipe and bind one end to client var adapterFactory = connection.bindHandleToProxy(
// implementation. frameInterfaces.getInterface(bluetoothAdapter.AdapterFactory.name),
adapterClient = new AdapterClient(); bluetoothAdapter.AdapterFactory);
adapterClientHandle = connection.bindStubDerivedImpl(adapterClient);
// Get an Adapter service.
return adapterFactory.getAdapter().then(function(response) {
if (!response.adapter) {
throw new Error('Bluetooth Not Supported on this platform.');
}
adapter = connection.bindHandleToProxy( adapter = connection.bindHandleToProxy(response.adapter,
frameInterfaces.getInterface(bluetoothAdapter.Adapter.name),
bluetoothAdapter.Adapter); bluetoothAdapter.Adapter);
adapter.setClient(adapterClientHandle); // Create a message pipe and bind one end to client
// implementation and the other to the Adapter service.
adapterClient = new AdapterClient();
adapter.setClient(connection.bindStubDerivedImpl(adapterClient));
});
}); });
} }
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
initializeProxies() initializeProxies()
.then(function() { return adapter.getDevices(); }) .then(function() { return adapter.getDevices(); })
.then(function(response) { console.log(response.devices); }); .then(function(response) { console.log(response.devices); })
.catch(function(error) { console.error(error); });
}); });
})(); })();
...@@ -24,6 +24,8 @@ source_set("mojo") { ...@@ -24,6 +24,8 @@ source_set("mojo") {
sources = [ sources = [
"adapter.cc", "adapter.cc",
"adapter.h", "adapter.h",
"adapter_factory.cc",
"adapter_factory.h",
] ]
public_deps = [ public_deps = [
......
...@@ -9,40 +9,30 @@ ...@@ -9,40 +9,30 @@
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "device/bluetooth/adapter.h" #include "device/bluetooth/adapter.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "mojo/public/cpp/bindings/string.h" #include "mojo/public/cpp/bindings/string.h"
#include "mojo/public/cpp/bindings/strong_binding.h" #include "mojo/public/cpp/bindings/strong_binding.h"
namespace bluetooth { namespace bluetooth {
Adapter::Adapter() : client_(nullptr), weak_ptr_factory_(this) {} Adapter::Adapter(scoped_refptr<device::BluetoothAdapter> adapter)
: adapter_(std::move(adapter)), client_(nullptr), weak_ptr_factory_(this) {
adapter_->AddObserver(this);
}
Adapter::~Adapter() { Adapter::~Adapter() {
if (adapter_) {
adapter_->RemoveObserver(this); adapter_->RemoveObserver(this);
adapter_ = nullptr; adapter_ = nullptr;
}
}
// static
void Adapter::Create(mojom::AdapterRequest request) {
mojo::MakeStrongBinding(base::MakeUnique<Adapter>(), std::move(request));
} }
void Adapter::GetDevices(const GetDevicesCallback& callback) { void Adapter::GetDevices(const GetDevicesCallback& callback) {
if (!adapter_) { std::vector<mojom::DeviceInfoPtr> devices;
if (device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) {
base::Closure c = base::Bind(&Adapter::GetDevicesImpl,
weak_ptr_factory_.GetWeakPtr(), callback);
device::BluetoothAdapterFactory::GetAdapter(base::Bind( for (const device::BluetoothDevice* device : adapter_->GetDevices()) {
&Adapter::OnGetAdapter, weak_ptr_factory_.GetWeakPtr(), c)); mojom::DeviceInfoPtr device_info = ConstructDeviceInfoStruct(device);
return; devices.push_back(std::move(device_info));
}
callback.Run(std::vector<mojom::DeviceInfoPtr>());
return;
} }
GetDevicesImpl(callback);
callback.Run(std::move(devices));
} }
void Adapter::SetClient(mojom::AdapterClientPtr client) { void Adapter::SetClient(mojom::AdapterClientPtr client) {
...@@ -65,8 +55,9 @@ void Adapter::DeviceRemoved(device::BluetoothAdapter* adapter, ...@@ -65,8 +55,9 @@ void Adapter::DeviceRemoved(device::BluetoothAdapter* adapter,
} }
} }
// static
mojom::DeviceInfoPtr Adapter::ConstructDeviceInfoStruct( mojom::DeviceInfoPtr Adapter::ConstructDeviceInfoStruct(
const device::BluetoothDevice* device) const { const device::BluetoothDevice* device) {
mojom::DeviceInfoPtr device_info = mojom::DeviceInfo::New(); mojom::DeviceInfoPtr device_info = mojom::DeviceInfo::New();
device_info->name = device->GetName(); device_info->name = device->GetName();
...@@ -78,25 +69,4 @@ mojom::DeviceInfoPtr Adapter::ConstructDeviceInfoStruct( ...@@ -78,25 +69,4 @@ mojom::DeviceInfoPtr Adapter::ConstructDeviceInfoStruct(
return device_info; return device_info;
} }
void Adapter::GetDevicesImpl(const GetDevicesCallback& callback) {
std::vector<mojom::DeviceInfoPtr> devices;
for (const device::BluetoothDevice* device : adapter_->GetDevices()) {
mojom::DeviceInfoPtr device_info = ConstructDeviceInfoStruct(device);
devices.push_back(std::move(device_info));
}
callback.Run(std::move(devices));
}
void Adapter::OnGetAdapter(const base::Closure& continuation,
scoped_refptr<device::BluetoothAdapter> adapter) {
if (!adapter_) {
VLOG(1) << "Adapter acquired";
adapter_ = adapter;
adapter_->AddObserver(this);
}
continuation.Run();
}
} // namespace bluetooth } // namespace bluetooth
...@@ -7,23 +7,21 @@ ...@@ -7,23 +7,21 @@
#include "base/macros.h" #include "base/macros.h"
#include "device/bluetooth/bluetooth_adapter.h" #include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/public/interfaces/adapter.mojom.h" #include "device/bluetooth/public/interfaces/adapter.mojom.h"
namespace bluetooth { namespace bluetooth {
// Implementation of Mojo BluetoothAdapter located in // Implementation of Mojo Adapter located in
// device/bluetooth/public/interfaces/bluetooth.mojom. // device/bluetooth/public/interfaces/adapter.mojom.
// It handles requests for Bluetooth adapter capabilities // It handles requests for Bluetooth adapter capabilities
// and devices and uses the platform abstraction of device/bluetooth. // and devices and uses the platform abstraction of device/bluetooth.
class Adapter : public mojom::Adapter, class Adapter : public mojom::Adapter,
public device::BluetoothAdapter::Observer { public device::BluetoothAdapter::Observer {
public: public:
Adapter(); explicit Adapter(scoped_refptr<device::BluetoothAdapter> adapter);
~Adapter() override; ~Adapter() override;
// Creates an Adapter with a strong Mojo binding to |request|
static void Create(mojom::AdapterRequest request);
// mojom::Adapter overrides: // mojom::Adapter overrides:
void GetDevices(const GetDevicesCallback& callback) override; void GetDevices(const GetDevicesCallback& callback) override;
void SetClient(mojom::AdapterClientPtr client) override; void SetClient(mojom::AdapterClientPtr client) override;
...@@ -35,13 +33,10 @@ class Adapter : public mojom::Adapter, ...@@ -35,13 +33,10 @@ class Adapter : public mojom::Adapter,
device::BluetoothDevice* device) override; device::BluetoothDevice* device) override;
private: private:
mojom::DeviceInfoPtr ConstructDeviceInfoStruct( // Creates a mojom::DeviceInfo using info from the given |device|.
const device::BluetoothDevice* device) const; static mojom::DeviceInfoPtr ConstructDeviceInfoStruct(
const device::BluetoothDevice* device);
void GetDevicesImpl(const GetDevicesCallback& callback);
void OnGetAdapter(const base::Closure& continuation,
scoped_refptr<device::BluetoothAdapter> adapter);
// The current Bluetooth adapter. // The current Bluetooth adapter.
scoped_refptr<device::BluetoothAdapter> adapter_; scoped_refptr<device::BluetoothAdapter> adapter_;
......
// Copyright 2016 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 <utility>
#include "base/memory/ptr_util.h"
#include "device/bluetooth/adapter.h"
#include "device/bluetooth/adapter_factory.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
namespace bluetooth {
AdapterFactory::AdapterFactory() : weak_ptr_factory_(this) {}
AdapterFactory::~AdapterFactory() {}
// static
void AdapterFactory::Create(mojom::AdapterFactoryRequest request) {
mojo::MakeStrongBinding(base::MakeUnique<AdapterFactory>(),
std::move(request));
}
void AdapterFactory::GetAdapter(const GetAdapterCallback& callback) {
if (device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) {
device::BluetoothAdapterFactory::GetAdapter(
base::Bind(&AdapterFactory::OnGetAdapter,
weak_ptr_factory_.GetWeakPtr(), callback));
} else {
callback.Run(nullptr /* AdapterPtr */);
}
}
void AdapterFactory::OnGetAdapter(
const GetAdapterCallback& callback,
scoped_refptr<device::BluetoothAdapter> adapter) {
mojom::AdapterPtr adapter_ptr;
mojo::MakeStrongBinding(base::MakeUnique<Adapter>(adapter),
mojo::GetProxy(&adapter_ptr));
callback.Run(std::move(adapter_ptr));
}
} // namespace bluetooth
// Copyright 2016 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.
#ifndef DEVICE_BLUETOOTH_ADAPTER_FACTORY_H_
#define DEVICE_BLUETOOTH_ADAPTER_FACTORY_H_
#include "base/macros.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/public/interfaces/adapter.mojom.h"
namespace bluetooth {
// Implementation of Mojo AdapterFactory located in
// device/bluetooth/public/interfaces/adapter.mojom.
// It handles requests for Mojo Adapter instances
// and strongly binds the Adapter instance to the system's
// Bluetooth adapter.
class AdapterFactory : public mojom::AdapterFactory {
public:
AdapterFactory();
~AdapterFactory() override;
// Creates an AdapterFactory with a strong Mojo binding to |request|.
static void Create(mojom::AdapterFactoryRequest request);
// mojom::AdapterFactory overrides:
void GetAdapter(const GetAdapterCallback& callback) override;
private:
void OnGetAdapter(const GetAdapterCallback& callback,
scoped_refptr<device::BluetoothAdapter> adapter);
base::WeakPtrFactory<AdapterFactory> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(AdapterFactory);
};
} // namespace bluetooth
#endif // DEVICE_BLUETOOTH_ADAPTER_FACTORY_H_
...@@ -28,3 +28,8 @@ interface AdapterClient { ...@@ -28,3 +28,8 @@ interface AdapterClient {
// Called after the device hasn't been seen for 3 minutes. // Called after the device hasn't been seen for 3 minutes.
DeviceRemoved(DeviceInfo device); DeviceRemoved(DeviceInfo device);
}; };
interface AdapterFactory {
// Gets an Adapter interface. Returns null if Bluetooth is not supported.
GetAdapter() => (Adapter? adapter);
};
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment