Commit 70d50e7a authored by mbrunson's avatar mbrunson Committed by Commit bot

bluetooth: Add device list retrieval for chrome://bluetooth-internals

Changes WebUI setup to a MojoWebUI for chrome://bluetooth-internals page.
Adds mojom files for Bluetooth service definition and internals page handler.
Adds basic Bluetooth device retrieval using starter Bluetooth service
implementation for logging on web front end.
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:closure_compilation
BUG=651282

Committed: https://crrev.com/e619ab633a89f1c845f5fdd7584344a5914b30a9
Review-Url: https://codereview.chromium.org/2357383002
Cr-Original-Commit-Position: refs/heads/master@{#422570}
Cr-Commit-Position: refs/heads/master@{#422855}
parent 6472a358
...@@ -1403,6 +1403,7 @@ split_static_library("browser") { ...@@ -1403,6 +1403,7 @@ split_static_library("browser") {
"//courgette:courgette_lib", "//courgette:courgette_lib",
"//crypto", "//crypto",
"//crypto:platform", "//crypto:platform",
"//device/bluetooth:mojo",
"//device/core", "//device/core",
"//device/usb/mojo", "//device/usb/mojo",
"//device/usb/public/interfaces", "//device/usb/public/interfaces",
...@@ -3962,6 +3963,7 @@ grit("resources") { ...@@ -3962,6 +3963,7 @@ grit("resources") {
"//chrome/browser/ui/webui/omnibox:mojo_bindings__generator", "//chrome/browser/ui/webui/omnibox:mojo_bindings__generator",
"//chrome/browser/ui/webui/plugins:mojo_bindings__generator", "//chrome/browser/ui/webui/plugins:mojo_bindings__generator",
"//chrome/browser/ui/webui/usb_internals:mojo_bindings__generator", "//chrome/browser/ui/webui/usb_internals:mojo_bindings__generator",
"//device/bluetooth/public/interfaces:experimental_interfaces__generator",
"//url/mojo:url_mojom_gurl__generator", "//url/mojo:url_mojom_gurl__generator",
"//url/mojo:url_mojom_origin__generator", "//url/mojo:url_mojom_origin__generator",
] ]
......
...@@ -94,6 +94,7 @@ ...@@ -94,6 +94,7 @@
<include name="IDR_BLUETOOTH_INTERNALS_CSS" file="resources\bluetooth_internals\bluetooth_internals.css" type="BINDATA" /> <include name="IDR_BLUETOOTH_INTERNALS_CSS" file="resources\bluetooth_internals\bluetooth_internals.css" type="BINDATA" />
<include name="IDR_BLUETOOTH_INTERNALS_HTML" file="resources\bluetooth_internals\bluetooth_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> <include name="IDR_BLUETOOTH_INTERNALS_HTML" file="resources\bluetooth_internals\bluetooth_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
<include name="IDR_BLUETOOTH_INTERNALS_JS" file="resources\bluetooth_internals\bluetooth_internals.js" type="BINDATA" /> <include name="IDR_BLUETOOTH_INTERNALS_JS" file="resources\bluetooth_internals\bluetooth_internals.js" type="BINDATA" />
<include name="IDR_BLUETOOTH_MOJO_JS" file="${root_gen_dir}\device\bluetooth\public\interfaces\adapter.mojom.js" use_base_dir="false" type="BINDATA"/>
<include name="IDR_BOOKMARKS_MANIFEST" file="resources\bookmark_manager\manifest.json" type="BINDATA" /> <include name="IDR_BOOKMARKS_MANIFEST" file="resources\bookmark_manager\manifest.json" type="BINDATA" />
<if expr="is_posix and not is_macosx and not is_ios"> <if expr="is_posix and not is_macosx and not is_ios">
<include name="IDR_CERTIFICATE_VIEWER_HTML" file="resources\certificate_viewer.html" type="BINDATA" /> <include name="IDR_CERTIFICATE_VIEWER_HTML" file="resources\certificate_viewer.html" type="BINDATA" />
......
...@@ -169,6 +169,8 @@ ...@@ -169,6 +169,8 @@
#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/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"
#include "gin/v8_initializer.h" #include "gin/v8_initializer.h"
...@@ -2963,6 +2965,9 @@ void ChromeContentBrowserClient::RegisterRenderFrameMojoInterfaces( ...@@ -2963,6 +2965,9 @@ void ChromeContentBrowserClient::RegisterRenderFrameMojoInterfaces(
base::Bind(&CreateWebUsbChooserService, render_frame_host)); base::Bind(&CreateWebUsbChooserService, render_frame_host));
} }
registry->AddInterface<bluetooth::mojom::Adapter>(
base::Bind(&bluetooth::Adapter::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.
registry->AddInterface( registry->AddInterface(
......
...@@ -7,6 +7,82 @@ ...@@ -7,6 +7,82 @@
* chrome://bluetooth-internals/. * chrome://bluetooth-internals/.
*/ */
document.addEventListener('DOMContentLoaded', function() { /**
console.log('Welcome to Bluetooth Internals.'); * The implementation of AdapterClient in
}); * device/bluetooth/public/interfaces/adapter.mojom.
*/
var AdapterClient = function() {};
AdapterClient.prototype = {
/**
* Prints added device to console.
* @param {!Object} device the device that was added
*/
deviceAdded: function(device) {
console.log('Device added');
console.log(device);
},
/**
* Prints removed device to console.
* @param {!Object} device the device that was removed
*/
deviceRemoved: function(device) {
console.log('Device removed');
console.log(device);
}
};
(function() {
var adapter = null;
var adapterClient = null;
var adapterClientHandle = null;
/**
* TODO: Move to shared location. See crbug.com/652361.
* Helper to convert callback-based define() API to a promise-based API.
* @param {!Array<string>} moduleNames
* @return {!Promise}
*/
function importModules(moduleNames) {
return new Promise(function(resolve, reject) {
define(moduleNames, function(var_args) {
resolve(Array.prototype.slice.call(arguments, 0));
});
});
}
/**
* Initializes Mojo proxies for page and Bluetooth services.
* @return {!Promise}
*/
function initializeProxies() {
return importModules([
'content/public/renderer/frame_interfaces',
'device/bluetooth/public/interfaces/adapter.mojom',
'mojo/public/js/connection',
]).then(function([frameInterfaces, bluetoothAdapter, connection]) {
console.log('Loaded modules');
// Hook up the instance properties.
AdapterClient.prototype.__proto__ =
bluetoothAdapter.AdapterClient.stubClass.prototype;
// Create a message pipe and bind one end to client
// implementation.
adapterClient = new AdapterClient();
adapterClientHandle = connection.bindStubDerivedImpl(adapterClient);
adapter = connection.bindHandleToProxy(
frameInterfaces.getInterface(bluetoothAdapter.Adapter.name),
bluetoothAdapter.Adapter);
adapter.setClient(adapterClientHandle);
});
}
document.addEventListener('DOMContentLoaded', function() {
initializeProxies()
.then(function() { return adapter.getDevices(); })
.then(function(response) { console.log(response.devices); });
});
})();
...@@ -560,6 +560,7 @@ split_static_library("ui") { ...@@ -560,6 +560,7 @@ split_static_library("ui") {
"//content/app/resources", "//content/app/resources",
"//content/public/common", "//content/public/common",
"//crypto", "//crypto",
"//device/bluetooth/public/interfaces:experimental_interfaces",
"//device/core", "//device/core",
"//device/usb", "//device/usb",
"//media", "//media",
......
...@@ -20,6 +20,9 @@ BluetoothInternalsUI::BluetoothInternalsUI(content::WebUI* web_ui) ...@@ -20,6 +20,9 @@ BluetoothInternalsUI::BluetoothInternalsUI(content::WebUI* web_ui)
IDR_BLUETOOTH_INTERNALS_CSS); IDR_BLUETOOTH_INTERNALS_CSS);
html_source->AddResourcePath("bluetooth_internals.js", html_source->AddResourcePath("bluetooth_internals.js",
IDR_BLUETOOTH_INTERNALS_JS); IDR_BLUETOOTH_INTERNALS_JS);
html_source->AddResourcePath(
"device/bluetooth/public/interfaces/adapter.mojom",
IDR_BLUETOOTH_MOJO_JS);
html_source->SetDefaultResource(IDR_BLUETOOTH_INTERNALS_HTML); html_source->SetDefaultResource(IDR_BLUETOOTH_INTERNALS_HTML);
Profile* profile = Profile::FromWebUI(web_ui); Profile* profile = Profile::FromWebUI(web_ui);
......
...@@ -20,6 +20,18 @@ config("bluetooth_config") { ...@@ -20,6 +20,18 @@ config("bluetooth_config") {
} }
} }
source_set("mojo") {
sources = [
"adapter.cc",
"adapter.h",
]
public_deps = [
":bluetooth",
"//device/bluetooth/public/interfaces:experimental_interfaces",
]
}
component("bluetooth") { component("bluetooth") {
sources = [ sources = [
"android/bluetooth_jni_registrar.cc", "android/bluetooth_jni_registrar.cc",
......
// 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 <string>
#include <utility>
#include <vector>
#include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.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/strong_binding.h"
namespace bluetooth {
Adapter::Adapter() : client_(nullptr), weak_ptr_factory_(this) {}
Adapter::~Adapter() {
if (adapter_) {
adapter_->RemoveObserver(this);
adapter_ = nullptr;
}
}
// static
void Adapter::Create(mojom::AdapterRequest request) {
mojo::MakeStrongBinding(base::MakeUnique<Adapter>(), std::move(request));
}
void Adapter::GetDevices(const GetDevicesCallback& callback) {
if (!adapter_) {
if (device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) {
base::Closure c = base::Bind(&Adapter::GetDevicesImpl,
weak_ptr_factory_.GetWeakPtr(), callback);
device::BluetoothAdapterFactory::GetAdapter(base::Bind(
&Adapter::OnGetAdapter, weak_ptr_factory_.GetWeakPtr(), c));
return;
}
callback.Run(std::vector<mojom::DeviceInfoPtr>());
return;
}
GetDevicesImpl(callback);
}
void Adapter::SetClient(mojom::AdapterClientPtr client) {
client_ = std::move(client);
}
void Adapter::DeviceAdded(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device) {
if (client_) {
auto device_info = ConstructDeviceInfoStruct(device);
client_->DeviceAdded(std::move(device_info));
}
}
void Adapter::DeviceRemoved(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device) {
if (client_) {
auto device_info = ConstructDeviceInfoStruct(device);
client_->DeviceRemoved(std::move(device_info));
}
}
mojom::DeviceInfoPtr Adapter::ConstructDeviceInfoStruct(
const device::BluetoothDevice* device) const {
mojom::DeviceInfoPtr device_info = mojom::DeviceInfo::New();
device_info->name = device->GetName();
device_info->name_for_display =
base::UTF16ToUTF8(device->GetNameForDisplay());
device_info->id = device->GetIdentifier();
device_info->address = device->GetAddress();
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
// 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_H_
#define DEVICE_BLUETOOTH_ADAPTER_H_
#include "base/macros.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/public/interfaces/adapter.mojom.h"
namespace bluetooth {
// Implementation of Mojo BluetoothAdapter located in
// device/bluetooth/public/interfaces/bluetooth.mojom.
// It handles requests for Bluetooth adapter capabilities
// and devices and uses the platform abstraction of device/bluetooth.
class Adapter : public mojom::Adapter,
public device::BluetoothAdapter::Observer {
public:
Adapter();
~Adapter() override;
// Creates an Adapter with a strong Mojo binding to |request|
static void Create(mojom::AdapterRequest request);
// mojom::Adapter overrides:
void GetDevices(const GetDevicesCallback& callback) override;
void SetClient(mojom::AdapterClientPtr client) override;
// device::BluetoothAdapter::Observer overrides:
void DeviceAdded(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device) override;
void DeviceRemoved(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device) override;
private:
mojom::DeviceInfoPtr ConstructDeviceInfoStruct(
const device::BluetoothDevice* device) const;
void GetDevicesImpl(const GetDevicesCallback& callback);
void OnGetAdapter(const base::Closure& continuation,
scoped_refptr<device::BluetoothAdapter> adapter);
// The current Bluetooth adapter.
scoped_refptr<device::BluetoothAdapter> adapter_;
// The adapter client that listens to this service.
mojom::AdapterClientPtr client_;
base::WeakPtrFactory<Adapter> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(Adapter);
};
} // namespace bluetooth
#endif // DEVICE_BLUETOOTH_ADAPTER_H_
...@@ -4,10 +4,22 @@ ...@@ -4,10 +4,22 @@
import("//mojo/public/tools/bindings/mojom.gni") import("//mojo/public/tools/bindings/mojom.gni")
mojom("bluetooth_mojom_bluetooth_uuid") { mojom("interfaces") {
sources = [ sources = [
"uuid.mojom", "uuid.mojom",
] ]
use_new_wrapper_types = false use_new_wrapper_types = false
} }
mojom("experimental_interfaces") {
sources = [
"adapter.mojom",
]
visibility = [
"//device/bluetooth:mojo",
"//chrome/browser:*",
"//chrome/browser/ui:*",
]
}
// 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.
module bluetooth.mojom;
struct DeviceInfo {
string? name;
string name_for_display;
string id;
string address;
};
interface Adapter {
// Retrieves the list of the devices known by the adapter including Connected
// Devices, GATT Connected Devices, Paired Devices and Devices discovered
// during a classic or low-energy scan.
GetDevices() => (array<DeviceInfo> devices);
// Sets the client that listens for the adapter's events.
SetClient(AdapterClient client);
};
interface AdapterClient {
// Called the first time a device is discovered.
DeviceAdded(DeviceInfo device);
// Called after the device hasn't been seen for 3 minutes.
DeviceRemoved(DeviceInfo device);
};
...@@ -644,7 +644,7 @@ mojom("mojo_bindings") { ...@@ -644,7 +644,7 @@ mojom("mojo_bindings") {
public_deps = [ public_deps = [
":android_mojo_bindings", ":android_mojo_bindings",
":new_wrapper_types_mojo_bindings", ":new_wrapper_types_mojo_bindings",
"//device/bluetooth/public/interfaces:bluetooth_mojom_bluetooth_uuid", "//device/bluetooth/public/interfaces",
"//mojo/common:common_custom_types", "//mojo/common:common_custom_types",
"//url/mojo:url_mojom_origin", "//url/mojo:url_mojom_origin",
] ]
......
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