Commit 8c56b632 authored by Ovidio Henriquez's avatar Ovidio Henriquez Committed by Commit Bot

bluetooth: FakeBluetoothChooserClient impl.

Adds a FakeBluetoothChooserClient associated interface that will be used by
FakeBluetoothChooser to send FakeBluetoothChooserEvents to the client as
they happen. Since this feature completes the Fake Bluetooth scanning
API, this change also converts a test to use the new API.

BUG=719827

Change-Id: I2770b3642ae93339e16b594591e4b4075e8246c5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/961719
Commit-Queue: Ovidio de Jesús Ruiz-Henríquez <odejesush@chromium.org>
Reviewed-by: default avatarMike West <mkwst@chromium.org>
Reviewed-by: default avatarGiovanni Ortuño Urquidi <ortuno@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Cr-Commit-Position: refs/heads/master@{#659096}
parent 019cb348
...@@ -166,6 +166,8 @@ jumbo_static_library("content_shell_lib") { ...@@ -166,6 +166,8 @@ jumbo_static_library("content_shell_lib") {
"browser/web_test/devtools_protocol_test_bindings.h", "browser/web_test/devtools_protocol_test_bindings.h",
"browser/web_test/fake_bluetooth_chooser.cc", "browser/web_test/fake_bluetooth_chooser.cc",
"browser/web_test/fake_bluetooth_chooser.h", "browser/web_test/fake_bluetooth_chooser.h",
"browser/web_test/fake_bluetooth_chooser_factory.cc",
"browser/web_test/fake_bluetooth_chooser_factory.h",
"browser/web_test/fake_bluetooth_scanning_prompt.cc", "browser/web_test/fake_bluetooth_scanning_prompt.cc",
"browser/web_test/fake_bluetooth_scanning_prompt.h", "browser/web_test/fake_bluetooth_scanning_prompt.h",
"browser/web_test/leak_detector.cc", "browser/web_test/leak_detector.cc",
......
...@@ -156,21 +156,21 @@ int GetCrashSignalFD(const base::CommandLine& command_line) { ...@@ -156,21 +156,21 @@ int GetCrashSignalFD(const base::CommandLine& command_line) {
#endif // defined(OS_ANDROID) #endif // defined(OS_ANDROID)
const service_manager::Manifest& GetContentBrowserOverlayManifest() { const service_manager::Manifest& GetContentBrowserOverlayManifest() {
static base::NoDestructor<service_manager::Manifest> manifest { static base::NoDestructor<service_manager::Manifest> manifest{
service_manager::ManifestBuilder() service_manager::ManifestBuilder()
.ExposeCapability( .ExposeCapability(
"renderer", "renderer",
service_manager::Manifest::InterfaceList< service_manager::Manifest::InterfaceList<
mojom::MojoWebTestHelper, mojom::FakeBluetoothChooser, mojom::MojoWebTestHelper, mojom::FakeBluetoothChooser,
mojom::WebTestBluetoothFakeAdapterSetter, mojom::FakeBluetoothChooserFactory,
bluetooth::mojom::FakeBluetooth>()) mojom::WebTestBluetoothFakeAdapterSetter,
.RequireCapability(echo::mojom::kServiceName, "echo") bluetooth::mojom::FakeBluetooth>())
.ExposeInterfaceFilterCapability_Deprecated( .RequireCapability(echo::mojom::kServiceName, "echo")
"navigation:frame", "renderer", .ExposeInterfaceFilterCapability_Deprecated(
service_manager::Manifest::InterfaceList< "navigation:frame", "renderer",
mojom::MojoWebTestHelper>()) service_manager::Manifest::InterfaceList<
.Build() mojom::MojoWebTestHelper>())
}; .Build()};
return *manifest; return *manifest;
} }
......
...@@ -776,12 +776,16 @@ std::unique_ptr<BluetoothChooser> BlinkTestController::RunBluetoothChooser( ...@@ -776,12 +776,16 @@ std::unique_ptr<BluetoothChooser> BlinkTestController::RunBluetoothChooser(
return bluetooth_chooser_factory_->RunBluetoothChooser(frame, return bluetooth_chooser_factory_->RunBluetoothChooser(frame,
event_handler); event_handler);
} }
auto next_fake_bluetooth_chooser = auto next_fake_bluetooth_chooser =
WebTestContentBrowserClient::Get()->GetNextFakeBluetoothChooser(); WebTestContentBrowserClient::Get()->GetNextFakeBluetoothChooser();
if (next_fake_bluetooth_chooser) { if (next_fake_bluetooth_chooser) {
next_fake_bluetooth_chooser->SetEventHandler(event_handler); const url::Origin origin = frame->GetLastCommittedOrigin();
DCHECK(!origin.opaque());
next_fake_bluetooth_chooser->OnRunBluetoothChooser(event_handler, origin);
return next_fake_bluetooth_chooser; return next_fake_bluetooth_chooser;
} }
return std::make_unique<WebTestFirstDeviceBluetoothChooser>(event_handler); return std::make_unique<WebTestFirstDeviceBluetoothChooser>(event_handler);
} }
......
...@@ -13,66 +13,89 @@ ...@@ -13,66 +13,89 @@
namespace content { namespace content {
FakeBluetoothChooser::FakeBluetoothChooser(
mojom::FakeBluetoothChooserRequest request,
mojom::FakeBluetoothChooserClientAssociatedPtrInfo client_ptr_info)
: binding_(this, std::move(request)),
client_ptr_(std::move(client_ptr_info)) {
SetTestBluetoothScanDuration(BluetoothTestScanDurationSetting::kNeverTimeout);
}
FakeBluetoothChooser::~FakeBluetoothChooser() { FakeBluetoothChooser::~FakeBluetoothChooser() {
SetTestBluetoothScanDuration( SetTestBluetoothScanDuration(
BluetoothTestScanDurationSetting::kImmediateTimeout); BluetoothTestScanDurationSetting::kImmediateTimeout);
// TODO(https://crbug.com/719826): Send a
// mojom::ChooserEventType::CHOOSER_CLOSED event to the client.
}
// static client_ptr_->OnEvent(mojom::FakeBluetoothChooserEvent::New(
std::unique_ptr<FakeBluetoothChooser> FakeBluetoothChooser::Create( mojom::ChooserEventType::CHOOSER_CLOSED, /*origin=*/base::nullopt,
mojom::FakeBluetoothChooserRequest request) { /*peripheral_address=*/base::nullopt));
SetTestBluetoothScanDuration(BluetoothTestScanDurationSetting::kNeverTimeout);
return std::unique_ptr<FakeBluetoothChooser>(
new FakeBluetoothChooser(std::move(request)));
} }
void FakeBluetoothChooser::SetEventHandler(const EventHandler& event_handler) { void FakeBluetoothChooser::OnRunBluetoothChooser(
const EventHandler& event_handler,
const url::Origin& origin) {
event_handler_ = event_handler; event_handler_ = event_handler;
client_ptr_->OnEvent(mojom::FakeBluetoothChooserEvent::New(
mojom::ChooserEventType::CHOOSER_OPENED, origin,
/*peripheral_address=*/base::nullopt));
} }
// mojom::FakeBluetoothChooser overrides // mojom::FakeBluetoothChooser overrides
void FakeBluetoothChooser::WaitForEvents(uint32_t num_of_events,
WaitForEventsCallback callback) {
// TODO(https://crbug.com/719826): Implement this function according to the
// Web Bluetooth Test Scanning design document.
// https://docs.google.com/document/d/1XFl_4ZAgO8ddM6U53A9AfUuZeWgJnlYD5wtbXqEpzeg
NOTREACHED();
}
void FakeBluetoothChooser::SelectPeripheral( void FakeBluetoothChooser::SelectPeripheral(
const std::string& peripheral_address) { const std::string& peripheral_address) {
DCHECK(event_handler_);
event_handler_.Run(BluetoothChooser::Event::SELECTED, peripheral_address); event_handler_.Run(BluetoothChooser::Event::SELECTED, peripheral_address);
} }
void FakeBluetoothChooser::Cancel() { void FakeBluetoothChooser::Cancel() {
// TODO(https://crbug.com/719826): Send a BluetoothChooser::CANCELLED event to DCHECK(event_handler_);
// |event_handler_| and a mojom::ChooserEventType::CHOOSER_CLOSED to the event_handler_.Run(BluetoothChooser::Event::CANCELLED, std::string());
// client. client_ptr_->OnEvent(mojom::FakeBluetoothChooserEvent::New(
NOTREACHED(); mojom::ChooserEventType::CHOOSER_CLOSED, /*origin=*/base::nullopt,
/*peripheral_address=*/base::nullopt));
} }
void FakeBluetoothChooser::Rescan() { void FakeBluetoothChooser::Rescan() {
// TODO(https://crbug.com/719826): Send a BluetoothChooser::RESCAN event to DCHECK(event_handler_);
// |event_handler_| and the appropriate mojom::ChooserEventType to describe event_handler_.Run(BluetoothChooser::Event::RESCAN, std::string());
// the discovery session. client_ptr_->OnEvent(mojom::FakeBluetoothChooserEvent::New(
NOTREACHED(); mojom::ChooserEventType::DISCOVERING, /*origin=*/base::nullopt,
/*peripheral_address=*/base::nullopt));
} }
// BluetoothChooser overrides // BluetoothChooser overrides
void FakeBluetoothChooser::SetAdapterPresence(AdapterPresence presence) { void FakeBluetoothChooser::SetAdapterPresence(AdapterPresence presence) {
// TODO(https://crbug.com/719826): Send the appropriate mojom::FakeBluetoothChooserEventPtr event_ptr =
// mojom::ChooserEventType to the client. mojom::FakeBluetoothChooserEvent::New();
NOTREACHED(); switch (presence) {
case AdapterPresence::ABSENT:
event_ptr->type = mojom::ChooserEventType::ADAPTER_REMOVED;
break;
case AdapterPresence::POWERED_OFF:
event_ptr->type = mojom::ChooserEventType::ADAPTER_DISABLED;
break;
case AdapterPresence::POWERED_ON:
event_ptr->type = mojom::ChooserEventType::ADAPTER_ENABLED;
break;
}
client_ptr_->OnEvent(std::move(event_ptr));
} }
void FakeBluetoothChooser::ShowDiscoveryState(DiscoveryState state) { void FakeBluetoothChooser::ShowDiscoveryState(DiscoveryState state) {
// TODO(https://crbug.com/719826): Send the appropriate mojom::FakeBluetoothChooserEventPtr event_ptr =
// mojom::ChooserEventType to the client. mojom::FakeBluetoothChooserEvent::New();
NOTREACHED(); switch (state) {
case DiscoveryState::FAILED_TO_START:
event_ptr->type = mojom::ChooserEventType::DISCOVERY_FAILED_TO_START;
break;
case DiscoveryState::DISCOVERING:
event_ptr->type = mojom::ChooserEventType::DISCOVERING;
break;
case DiscoveryState::IDLE:
event_ptr->type = mojom::ChooserEventType::DISCOVERY_IDLE;
break;
}
client_ptr_->OnEvent(std::move(event_ptr));
} }
void FakeBluetoothChooser::AddOrUpdateDevice(const std::string& device_id, void FakeBluetoothChooser::AddOrUpdateDevice(const std::string& device_id,
...@@ -81,15 +104,9 @@ void FakeBluetoothChooser::AddOrUpdateDevice(const std::string& device_id, ...@@ -81,15 +104,9 @@ void FakeBluetoothChooser::AddOrUpdateDevice(const std::string& device_id,
bool is_gatt_connected, bool is_gatt_connected,
bool is_paired, bool is_paired,
int signal_strength_level) { int signal_strength_level) {
// TODO(https://crbug.com/719826): Send a client_ptr_->OnEvent(mojom::FakeBluetoothChooserEvent::New(
// mojom::ChooserEventType::ADD_OR_UPDATE_DEVICE to the client. mojom::ChooserEventType::ADD_OR_UPDATE_DEVICE,
NOTREACHED(); /*origin=*/base::nullopt, /*peripheral_address=*/device_id));
} }
// private
FakeBluetoothChooser::FakeBluetoothChooser(
mojom::FakeBluetoothChooserRequest request)
: binding_(this, std::move(request)) {}
} // namespace content } // namespace content
...@@ -9,7 +9,9 @@ ...@@ -9,7 +9,9 @@
#include "content/public/browser/bluetooth_chooser.h" #include "content/public/browser/bluetooth_chooser.h"
#include "content/shell/common/web_test/fake_bluetooth_chooser.mojom.h" #include "content/shell/common/web_test/fake_bluetooth_chooser.mojom.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
#include "url/origin.h"
namespace content { namespace content {
...@@ -28,24 +30,25 @@ namespace content { ...@@ -28,24 +30,25 @@ namespace content {
class FakeBluetoothChooser : public mojom::FakeBluetoothChooser, class FakeBluetoothChooser : public mojom::FakeBluetoothChooser,
public BluetoothChooser { public BluetoothChooser {
public: public:
// Resets the test scan duration to timeout immediately. // FakeBluetoothChooserFactory will create an instance of this class when its
~FakeBluetoothChooser() override; // CreateFakeBluetoothChooser() method is called. It will maintain ownership
// of the instance temporarily until the chooser is opened. When the chooser
// WebTestContentBrowserClient will create an instance of this class when a // is opened, ownership of this instance will shift to the caller of
// request is bound. It will maintain ownership of the instance temporarily
// until the chooser is opened. When the chooser is opened, ownership of this
// instance will shift to the caller of
// WebContentsDelegate::RunBluetoothChooser. // WebContentsDelegate::RunBluetoothChooser.
static std::unique_ptr<FakeBluetoothChooser> Create( FakeBluetoothChooser(
mojom::FakeBluetoothChooserRequest request); mojom::FakeBluetoothChooserRequest request,
mojom::FakeBluetoothChooserClientAssociatedPtrInfo client_ptr_info);
// Sets the EventHandler that will handle events produced by the chooser. // Resets the test scan duration to timeout immediately and sends a
void SetEventHandler(const EventHandler& event_handler); // |CHOOSER_CLOSED| event to the client.
~FakeBluetoothChooser() override;
// mojom::FakeBluetoothChooser overrides: // Sets the EventHandler that will handle events produced by the chooser, and
// sends a |CHOOSER_OPENED| event to the client with the |origin|.
void OnRunBluetoothChooser(const EventHandler& event_handler,
const url::Origin& origin);
void WaitForEvents(uint32_t num_of_events, // mojom::FakeBluetoothChooser overrides:
WaitForEventsCallback callback) override;
void SelectPeripheral(const std::string& peripheral_address) override; void SelectPeripheral(const std::string& peripheral_address) override;
void Cancel() override; void Cancel() override;
void Rescan() override; void Rescan() override;
...@@ -62,13 +65,15 @@ class FakeBluetoothChooser : public mojom::FakeBluetoothChooser, ...@@ -62,13 +65,15 @@ class FakeBluetoothChooser : public mojom::FakeBluetoothChooser,
int signal_strength_level) override; int signal_strength_level) override;
private: private:
explicit FakeBluetoothChooser(mojom::FakeBluetoothChooserRequest request);
// Stores the callback function that handles chooser events. // Stores the callback function that handles chooser events.
EventHandler event_handler_; EventHandler event_handler_;
mojo::Binding<mojom::FakeBluetoothChooser> binding_; mojo::Binding<mojom::FakeBluetoothChooser> binding_;
// Stores the associated pointer to the client that will be receiving events
// from FakeBluetoothChooser.
mojom::FakeBluetoothChooserClientAssociatedPtr client_ptr_;
DISALLOW_COPY_AND_ASSIGN(FakeBluetoothChooser); DISALLOW_COPY_AND_ASSIGN(FakeBluetoothChooser);
}; };
......
// Copyright 2019 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 "content/shell/browser/web_test/fake_bluetooth_chooser_factory.h"
#include "content/shell/browser/web_test/fake_bluetooth_chooser.h"
namespace content {
FakeBluetoothChooserFactory::~FakeBluetoothChooserFactory() {}
void FakeBluetoothChooserFactory::CreateFakeBluetoothChooser(
mojom::FakeBluetoothChooserRequest request,
mojom::FakeBluetoothChooserClientAssociatedPtrInfo client_ptr_info) {
DCHECK(!next_fake_bluetooth_chooser_);
next_fake_bluetooth_chooser_ = std::make_unique<FakeBluetoothChooser>(
std::move(request), std::move(client_ptr_info));
}
std::unique_ptr<FakeBluetoothChooser>
FakeBluetoothChooserFactory::GetNextFakeBluetoothChooser() {
return std::move(next_fake_bluetooth_chooser_);
}
FakeBluetoothChooserFactory::FakeBluetoothChooserFactory(
mojom::FakeBluetoothChooserFactoryRequest request)
: binding_(this, std::move(request)) {}
} // namespace content
// Copyright 2019 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 CONTENT_SHELL_BROWSER_WEB_TEST_FAKE_BLUETOOTH_CHOOSER_FACTORY_H_
#define CONTENT_SHELL_BROWSER_WEB_TEST_FAKE_BLUETOOTH_CHOOSER_FACTORY_H_
#include <memory>
#include "content/shell/common/web_test/fake_bluetooth_chooser.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
namespace content {
class FakeBluetoothChooser;
// Implementation of FakeBluetoothChooserFactory in
// src/content/shell/common/web_test/fake_bluetooth_chooser.mojom to create
// FakeBluetoothChoosers with a FakeBluetoothChooserClientAssociatedPtr that
// they can use to send events to the client.
//
// The implementation details for FakeBluetoothChooser can be found in the Web
// Bluetooth Test Scanning design document.
// https://docs.google.com/document/d/1XFl_4ZAgO8ddM6U53A9AfUuZeWgJnlYD5wtbXqEpzeg
//
// Intended to only be used through the FakeBluetoothChooser Mojo interface.
class FakeBluetoothChooserFactory : public mojom::FakeBluetoothChooserFactory {
public:
~FakeBluetoothChooserFactory() override;
// WebTestContentBrowserClient will create an instance of this class when a
// request is bound. It will maintain ownership of the instance.
static std::unique_ptr<FakeBluetoothChooserFactory> Create(
mojom::FakeBluetoothChooserFactoryRequest request) {
return std::unique_ptr<FakeBluetoothChooserFactory>(
new FakeBluetoothChooserFactory(std::move(request)));
}
// Creates an instance of FakeBluetoothChooser and stores it in
// |next_fake_bluetooth_chooser_|. This will DCHECK if
// |next_fake_bluetooth_chooser_| is not null.
void CreateFakeBluetoothChooser(
mojom::FakeBluetoothChooserRequest request,
mojom::FakeBluetoothChooserClientAssociatedPtrInfo client_ptr_info)
override;
// Transfers ownership of |next_fake_bluetooth_chooser_| to the caller.
std::unique_ptr<FakeBluetoothChooser> GetNextFakeBluetoothChooser();
private:
explicit FakeBluetoothChooserFactory(
mojom::FakeBluetoothChooserFactoryRequest request);
mojo::Binding<mojom::FakeBluetoothChooserFactory> binding_;
std::unique_ptr<FakeBluetoothChooser> next_fake_bluetooth_chooser_;
};
} // namespace content
#endif // CONTENT_SHELL_BROWSER_WEB_TEST_FAKE_BLUETOOTH_CHOOSER_FACTORY_H_
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "content/shell/browser/shell_browser_context.h" #include "content/shell/browser/shell_browser_context.h"
#include "content/shell/browser/web_test/blink_test_controller.h" #include "content/shell/browser/web_test/blink_test_controller.h"
#include "content/shell/browser/web_test/fake_bluetooth_chooser.h" #include "content/shell/browser/web_test/fake_bluetooth_chooser.h"
#include "content/shell/browser/web_test/fake_bluetooth_chooser_factory.h"
#include "content/shell/browser/web_test/mojo_web_test_helper.h" #include "content/shell/browser/web_test/mojo_web_test_helper.h"
#include "content/shell/browser/web_test/web_test_bluetooth_fake_adapter_setter_impl.h" #include "content/shell/browser/web_test/web_test_bluetooth_fake_adapter_setter_impl.h"
#include "content/shell/browser/web_test/web_test_browser_context.h" #include "content/shell/browser/web_test/web_test_browser_context.h"
...@@ -114,7 +115,9 @@ void WebTestContentBrowserClient::ResetMockClipboardHost() { ...@@ -114,7 +115,9 @@ void WebTestContentBrowserClient::ResetMockClipboardHost() {
std::unique_ptr<FakeBluetoothChooser> std::unique_ptr<FakeBluetoothChooser>
WebTestContentBrowserClient::GetNextFakeBluetoothChooser() { WebTestContentBrowserClient::GetNextFakeBluetoothChooser() {
return std::move(next_fake_bluetooth_chooser_); if (!fake_bluetooth_chooser_factory_)
return nullptr;
return fake_bluetooth_chooser_factory_->GetNextFakeBluetoothChooser();
} }
void WebTestContentBrowserClient::RenderProcessWillLaunch( void WebTestContentBrowserClient::RenderProcessWillLaunch(
...@@ -148,7 +151,7 @@ void WebTestContentBrowserClient::ExposeInterfacesToRenderer( ...@@ -148,7 +151,7 @@ void WebTestContentBrowserClient::ExposeInterfacesToRenderer(
// base::Unretained in all binders. // base::Unretained in all binders.
registry->AddInterface( registry->AddInterface(
base::BindRepeating( base::BindRepeating(
&WebTestContentBrowserClient::CreateFakeBluetoothChooser, &WebTestContentBrowserClient::CreateFakeBluetoothChooserFactory,
base::Unretained(this)), base::Unretained(this)),
ui_task_runner); ui_task_runner);
registry->AddInterface(base::BindRepeating(&MojoWebTestHelper::Create)); registry->AddInterface(base::BindRepeating(&MojoWebTestHelper::Create));
...@@ -327,11 +330,11 @@ std::unique_ptr<LoginDelegate> WebTestContentBrowserClient::CreateLoginDelegate( ...@@ -327,11 +330,11 @@ std::unique_ptr<LoginDelegate> WebTestContentBrowserClient::CreateLoginDelegate(
} }
// private // private
void WebTestContentBrowserClient::CreateFakeBluetoothChooser( void WebTestContentBrowserClient::CreateFakeBluetoothChooserFactory(
mojom::FakeBluetoothChooserRequest request) { mojom::FakeBluetoothChooserFactoryRequest request) {
DCHECK(!next_fake_bluetooth_chooser_); DCHECK(!fake_bluetooth_chooser_factory_);
next_fake_bluetooth_chooser_ = fake_bluetooth_chooser_factory_ =
FakeBluetoothChooser::Create(std::move(request)); FakeBluetoothChooserFactory::Create(std::move(request));
} }
} // namespace content } // namespace content
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
namespace content { namespace content {
class FakeBluetoothChooser; class FakeBluetoothChooser;
class FakeBluetoothChooserFactory;
class WebTestBrowserContext; class WebTestBrowserContext;
class MockClipboardHost; class MockClipboardHost;
class MockPlatformNotificationService; class MockPlatformNotificationService;
...@@ -88,17 +89,17 @@ class WebTestContentBrowserClient : public ShellContentBrowserClient { ...@@ -88,17 +89,17 @@ class WebTestContentBrowserClient : public ShellContentBrowserClient {
LoginAuthRequiredCallback auth_required_callback) override; LoginAuthRequiredCallback auth_required_callback) override;
private: private:
// Creates and stores a FakeBluetoothChooser instance. // Creates and stores a FakeBluetoothChooserFactory instance.
void CreateFakeBluetoothChooser(mojom::FakeBluetoothChooserRequest request); void CreateFakeBluetoothChooserFactory(
mojom::FakeBluetoothChooserFactoryRequest request);
void BindClipboardHost(blink::mojom::ClipboardHostRequest request); void BindClipboardHost(blink::mojom::ClipboardHostRequest request);
std::unique_ptr<MockPlatformNotificationService> std::unique_ptr<MockPlatformNotificationService>
mock_platform_notification_service_; mock_platform_notification_service_;
bool block_popups_ = false; bool block_popups_ = false;
// Stores the next instance of FakeBluetoothChooser that is to be returned // Stores the FakeBluetoothChooserFactory that produces FakeBluetoothChoosers.
// when GetNextFakeBluetoothChooser is called. std::unique_ptr<FakeBluetoothChooserFactory> fake_bluetooth_chooser_factory_;
std::unique_ptr<FakeBluetoothChooser> next_fake_bluetooth_chooser_;
std::unique_ptr<MockClipboardHost> mock_clipboard_host_; std::unique_ptr<MockClipboardHost> mock_clipboard_host_;
}; };
......
...@@ -39,11 +39,6 @@ enum ChooserEventType { ...@@ -39,11 +39,6 @@ enum ChooserEventType {
// FakeBluetoothChooser allows clients to control the global state of the // FakeBluetoothChooser allows clients to control the global state of the
// Bluetooth chooser during a web test. // Bluetooth chooser during a web test.
interface FakeBluetoothChooser { interface FakeBluetoothChooser {
// Waits until at least |num_of_events| have been recorded before returning
// |num_of_events| FakeBluetoothChooserEvents.
WaitForEvents(
uint32 num_of_events) => (array<FakeBluetoothChooserEvent> events);
// Simulates a user selecting the given |peripheral_address| in the Bluetooth // Simulates a user selecting the given |peripheral_address| in the Bluetooth
// chooser. // chooser.
SelectPeripheral(string peripheral_address); SelectPeripheral(string peripheral_address);
...@@ -55,6 +50,13 @@ interface FakeBluetoothChooser { ...@@ -55,6 +50,13 @@ interface FakeBluetoothChooser {
Rescan(); Rescan();
}; };
// FakeBluetoothChooserFactory ensures that FakeBluetoothChoosers are created
// with an associated FakeBluetoothChooserClient.
interface FakeBluetoothChooserFactory {
CreateFakeBluetoothChooser(FakeBluetoothChooser& fake_chooser,
associated FakeBluetoothChooserClient client);
};
// FakeBluetoothChooserEvent describes the type of chooser event that has been // FakeBluetoothChooserEvent describes the type of chooser event that has been
// produced by the FakeBluetoothChooser. // produced by the FakeBluetoothChooser.
struct FakeBluetoothChooserEvent { struct FakeBluetoothChooserEvent {
...@@ -67,3 +69,8 @@ struct FakeBluetoothChooserEvent { ...@@ -67,3 +69,8 @@ struct FakeBluetoothChooserEvent {
// Describes the MAC address of the Bluetooth device. // Describes the MAC address of the Bluetooth device.
string? peripheral_address; string? peripheral_address;
}; };
// Classes that implement this interface will be notified of chooser events.
interface FakeBluetoothChooserClient {
OnEvent(FakeBluetoothChooserEvent event);
};
...@@ -4628,7 +4628,6 @@ crbug.com/825733 [ Win ] media/color-profile-video-seek-filter.html [ Pass Timeo ...@@ -4628,7 +4628,6 @@ crbug.com/825733 [ Win ] media/color-profile-video-seek-filter.html [ Pass Timeo
crbug.com/754986 media/video-transformed.html [ Pass Failure ] crbug.com/754986 media/video-transformed.html [ Pass Failure ]
# Sheriff 2018-03-29 # Sheriff 2018-03-29
crbug.com/827088 bluetooth/requestDevice/chooser/new-scan-device-added.html [ Pass Crash ]
crbug.com/827209 [ Win ] fast/events/middleClickAutoscroll-latching.html [ Pass Timeout Failure ] crbug.com/827209 [ Win ] fast/events/middleClickAutoscroll-latching.html [ Pass Timeout Failure ]
crbug.com/827209 [ Linux ] fast/events/middleClickAutoscroll-latching.html [ Pass Timeout Failure ] crbug.com/827209 [ Linux ] fast/events/middleClickAutoscroll-latching.html [ Pass Timeout Failure ]
crbug.com/827209 [ Win ] virtual/mouseevent_fractional/fast/events/middleClickAutoscroll-latching.html [ Pass Timeout Failure ] crbug.com/827209 [ Win ] virtual/mouseevent_fractional/fast/events/middleClickAutoscroll-latching.html [ Pass Timeout Failure ]
......
...@@ -6,23 +6,44 @@ ...@@ -6,23 +6,44 @@
<script src="../../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script> <script src="../../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script>
<script> <script>
'use strict'; 'use strict';
bluetooth_test(() => { const test_desc = 'The chooser should display newly detected devices.';
setBluetoothManualChooser(true);
bluetooth_test(async () => {
let requestDevicePromise = setBluetoothFakeAdapter('DeviceEventAdapter') let fake_central =
.then( await navigator.bluetooth.test.simulateCentral({state: 'powered-on'});
() => requestDeviceWithTrustedClick( let fake_chooser = await navigator.bluetooth.test.getManualChooser();
{filters: [{services: ['glucose']}]}));
return getBluetoothManualChooserEvents(4).then(events => { // 1. Open the chooser.
assert_equals(events[0], 'chooser-opened(file://)'); let requestDevicePromise = requestDeviceWithTrustedClick({
assert_equals(events[1], 'discovering'); filters: [{services: ['health_thermometer']}]
let idsByName = new AddDeviceEventSet();
idsByName.assert_add_device_event(events[2]);
assert_true(idsByName.has('New Glucose Device'));
assert_equals(events[3], 'discovery-idle');
sendBluetoothManualChooserEvent(
'selected', idsByName.get('New Glucose Device'));
return requestDevicePromise;
}); });
});
let events = await fake_chooser.waitForEvents(2);
assert_equals(events.length, 2);
assert_equals(events[0].type, 'chooser-opened');
assert_equals(events[0].origin.scheme, 'file');
assert_equals(events[1].type, 'discovering');
// 2. Send the advertisement packet to central.
let fake_peripheral =
await fake_central.simulateAdvertisementReceived(
health_thermometer_ad_packet);
events = await fake_chooser.waitForEvents(1);
assert_equals(events.length, 1);
assert_equals(events[0].type, 'add-or-update-device');
assert_equals(events[0].peripheral_address,
health_thermometer_ad_packet.scanRecord.deviceAddress);
// 3. Select the device on the chooser.
await fake_chooser.selectPeripheral(fake_peripheral);
events = await fake_chooser.waitForEvents(1);
assert_equals(events.length, 1);
assert_equals(events[0].type, 'chooser-closed');
// 4. Check that the device and advertisement packet have the same name.
let device = await requestDevicePromise;
assert_equals(device.name, health_thermometer_ad_packet.scanRecord.name);
}, test_desc);
</script> </script>
...@@ -45,6 +45,22 @@ const CHARACTERISTIC_PROPERTIES_WEB_TO_MOJO = { ...@@ -45,6 +45,22 @@ const CHARACTERISTIC_PROPERTIES_WEB_TO_MOJO = {
extended_properties: 'extended_properties', extended_properties: 'extended_properties',
}; };
// Mapping of the Mojo ChooserEventType enum to a string.
const MOJO_CHOOSER_EVENT_TYPE_MAP = (() => {
const ChooserEventType = content.mojom.ChooserEventType;
return {
[ChooserEventType.CHOOSER_OPENED]: 'chooser-opened',
[ChooserEventType.CHOOSER_CLOSED]: 'chooser-closed',
[ChooserEventType.ADAPTER_REMOVED]: 'adapter-removed',
[ChooserEventType.ADAPTER_DISABLED]: 'adapter-disabled',
[ChooserEventType.ADAPTER_ENABLED]: 'adapter-enabled',
[ChooserEventType.DISCOVERY_FAILED_TO_START]: 'discovery-failed-to-start',
[ChooserEventType.DISCOVERING]: 'discovering',
[ChooserEventType.DISCOVERY_IDLE]: 'discovery-idle',
[ChooserEventType.ADD_OR_UPDATE_DEVICE]: 'add-or-update-device',
}
})();
function ArrayToMojoCharacteristicProperties(arr) { function ArrayToMojoCharacteristicProperties(arr) {
let struct = new bluetooth.mojom.CharacteristicProperties(); let struct = new bluetooth.mojom.CharacteristicProperties();
...@@ -504,14 +520,51 @@ class FakeRemoteGATTDescriptor { ...@@ -504,14 +520,51 @@ class FakeRemoteGATTDescriptor {
} }
} }
// FakeChooser allows clients to simulate events that a user would trigger when // FakeChooser allows clients to simulate user actions on a Bluetooth chooser,
// using the Bluetooth chooser, and monitor the events that are produced. // and records the events produced by the Bluetooth chooser.
class FakeChooser { class FakeChooser {
constructor() { constructor() {
let fakeBluetoothChooserFactoryPtr =
new content.mojom.FakeBluetoothChooserFactoryPtr();
Mojo.bindInterface(content.mojom.FakeBluetoothChooserFactory.name,
mojo.makeRequest(fakeBluetoothChooserFactoryPtr).handle, 'process');
this.fake_bluetooth_chooser_ptr_ = this.fake_bluetooth_chooser_ptr_ =
new content.mojom.FakeBluetoothChooserPtr(); new content.mojom.FakeBluetoothChooserPtr();
Mojo.bindInterface(content.mojom.FakeBluetoothChooser.name,
mojo.makeRequest(this.fake_bluetooth_chooser_ptr_).handle, 'process'); let clientPtrInfo = new mojo.AssociatedInterfacePtrInfo();
this.fake_bluetooth_chooser_client_binding_ =
new mojo.AssociatedBinding(content.mojom.FakeBluetoothChooserClient,
this, mojo.makeRequest(clientPtrInfo));
fakeBluetoothChooserFactoryPtr.createFakeBluetoothChooser(
mojo.makeRequest(this.fake_bluetooth_chooser_ptr_), clientPtrInfo);
this.events_ = new Array();
this.event_listener_ = null;
}
// If the chooser has received more events than |numOfEvents| this function
// will reject the promise, else it will wait until |numOfEvents| events are
// received before resolving with an array of |FakeBluetoothChooserEvent|
// objects.
async waitForEvents(numOfEvents) {
return new Promise(resolve => {
if (this.events_.length > numOfEvents) {
throw `Asked for ${numOfEvents} event(s), but received ` +
`${this.events_.length}.`;
}
this.event_listener_ = () => {
if (this.events_.length === numOfEvents) {
let result = Array.from(this.events_);
this.event_listener_ = null;
this.events_ = [];
resolve(result);
}
};
this.event_listener_();
});
} }
async selectPeripheral(peripheral) { async selectPeripheral(peripheral) {
...@@ -520,6 +573,22 @@ class FakeChooser { ...@@ -520,6 +573,22 @@ class FakeChooser {
} }
await this.fake_bluetooth_chooser_ptr_.selectPeripheral(peripheral.address); await this.fake_bluetooth_chooser_ptr_.selectPeripheral(peripheral.address);
} }
async cancel() {
await this.fake_bluetooth_chooser_ptr_.cancel();
}
async rescan() {
await this.fake_bluetooth_chooser_ptr_.rescan();
}
onEvent(chooserEvent) {
chooserEvent.type = MOJO_CHOOSER_EVENT_TYPE_MAP[chooserEvent.type];
this.events_.push(chooserEvent);
if (this.event_listener_ !== null) {
this.event_listener_();
}
}
} }
// If this line fails, it means that current environment does not support the // If this line fails, it means that current environment does not support the
......
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