Commit d42a5bc8 authored by Ovidio Henriquez's avatar Ovidio Henriquez Committed by Commit Bot

bluetooth: FakeBluetoothChooser stub impl.

This change adds a new FakeBluetoothChooser interface stub to expand on.
The design for this class is detailed in the following document:
https://docs.google.com/document/d/1XFl_4ZAgO8ddM6U53A9AfUuZeWgJnlYD5wtbXqEpzeg

BUG=719827

Change-Id: I34169ce62dd5b35796639b7643d899b8315cc4c7
Reviewed-on: https://chromium-review.googlesource.com/909726
Commit-Queue: Ovidio Henriquez <odejesush@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarConley Owens <cco3@chromium.org>
Reviewed-by: default avatarGiovanni Ortuño Urquidi <ortuno@chromium.org>
Cr-Commit-Position: refs/heads/master@{#543479}
parent 1a058abb
......@@ -60,6 +60,8 @@ static_library("content_shell_lib") {
"browser/layout_test/blink_test_controller.h",
"browser/layout_test/devtools_protocol_test_bindings.cc",
"browser/layout_test/devtools_protocol_test_bindings.h",
"browser/layout_test/fake_bluetooth_chooser.cc",
"browser/layout_test/fake_bluetooth_chooser.h",
"browser/layout_test/layout_test_bluetooth_adapter_provider.cc",
"browser/layout_test/layout_test_bluetooth_adapter_provider.h",
"browser/layout_test/layout_test_bluetooth_chooser_factory.cc",
......@@ -816,6 +818,7 @@ if (is_mac) {
mojom("mojo_bindings") {
sources = [
"common/layout_test.mojom",
"common/layout_test/fake_bluetooth_chooser.mojom",
"common/layout_test/layout_test_bluetooth_fake_adapter_setter.mojom",
"common/power_monitor_test.mojom",
]
......
......@@ -6,6 +6,7 @@
"renderer": [
"content::mojom::LayoutTestBluetoothFakeAdapterSetter",
"content::mojom::MojoLayoutTestHelper",
"content::mojom::FakeBluetoothChooser",
"bluetooth::mojom::FakeBluetooth"
]
},
......
......@@ -53,6 +53,7 @@
#include "content/public/common/url_constants.h"
#include "content/public/test/layouttest_support.h"
#include "content/shell/browser/layout_test/devtools_protocol_test_bindings.h"
#include "content/shell/browser/layout_test/fake_bluetooth_chooser.h"
#include "content/shell/browser/layout_test/layout_test_bluetooth_chooser_factory.h"
#include "content/shell/browser/layout_test/layout_test_content_browser_client.h"
#include "content/shell/browser/layout_test/layout_test_devtools_bindings.h"
......@@ -553,10 +554,18 @@ bool BlinkTestController::IsMainWindow(WebContents* web_contents) const {
std::unique_ptr<BluetoothChooser> BlinkTestController::RunBluetoothChooser(
RenderFrameHost* frame,
const BluetoothChooser::EventHandler& event_handler) {
// TODO(https://crbug.com/509038): Remove |bluetooth_chooser_factory_| once
// all of the Web Bluetooth tests are migrated to external/wpt/.
if (bluetooth_chooser_factory_) {
return bluetooth_chooser_factory_->RunBluetoothChooser(frame,
event_handler);
}
auto next_fake_bluetooth_chooser =
LayoutTestContentBrowserClient::Get()->GetNextFakeBluetoothChooser();
if (next_fake_bluetooth_chooser) {
next_fake_bluetooth_chooser->SetEventHandler(event_handler);
return next_fake_bluetooth_chooser;
}
return std::make_unique<LayoutTestFirstDeviceBluetoothChooser>(event_handler);
}
......
// Copyright 2018 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/layout_test/fake_bluetooth_chooser.h"
#include <string>
#include <utility>
#include "content/public/browser/bluetooth_chooser.h"
#include "content/shell/common/layout_test/fake_bluetooth_chooser.mojom.h"
namespace content {
FakeBluetoothChooser::~FakeBluetoothChooser() = default;
// static
std::unique_ptr<FakeBluetoothChooser> FakeBluetoothChooser::Create(
mojom::FakeBluetoothChooserRequest request) {
return std::unique_ptr<FakeBluetoothChooser>(
new FakeBluetoothChooser(std::move(request)));
}
void FakeBluetoothChooser::SetEventHandler(const EventHandler& event_handler) {
event_handler_ = event_handler;
}
// 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(
const std::string& peripheral_address,
SelectPeripheralCallback callback) {
// TODO(https://crbug.com/719826): Record the event and send a
// BluetoothChooser::SELECTED event to |event_handler_|.
NOTREACHED();
}
void FakeBluetoothChooser::Cancel(CancelCallback callback) {
// TODO(https://crbug.com/719826): Record the event and send a
// BluetoothChooser::CANCELLED event to |event_handler_|.
NOTREACHED();
}
void FakeBluetoothChooser::Rescan(RescanCallback callback) {
// TODO(https://crbug.com/719826): Record the event and send a
// BluetoothChooser::RESCAN event to |event_handler_|.
NOTREACHED();
}
// BluetoothChooser overrides
void FakeBluetoothChooser::SetAdapterPresence(AdapterPresence presence) {
// TODO(https://crbug.com/719826): Record the event.
NOTREACHED();
}
void FakeBluetoothChooser::ShowDiscoveryState(DiscoveryState state) {
// TODO(https://crbug.com/719826): Record the event.
NOTREACHED();
}
void FakeBluetoothChooser::AddOrUpdateDevice(const std::string& device_id,
bool should_update_name,
const base::string16& device_name,
bool is_gatt_connected,
bool is_paired,
int signal_strength_level) {
// TODO(https://crbug.com/719826): Record the event.
NOTREACHED();
}
// private
FakeBluetoothChooser::FakeBluetoothChooser(
mojom::FakeBluetoothChooserRequest request)
: binding_(this, std::move(request)) {}
} // namespace content
// Copyright 2018 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_LAYOUT_TEST_FAKE_BLUETOOTH_CHOOSER_H_
#define CONTENT_SHELL_BROWSER_LAYOUT_TEST_FAKE_BLUETOOTH_CHOOSER_H_
#include <memory>
#include "content/public/browser/bluetooth_chooser.h"
#include "content/shell/common/layout_test/fake_bluetooth_chooser.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
namespace content {
// Implementation of FakeBluetoothChooser in
// src/content/shell/common/layout_test/fake_bluetooth_chooser.mojom
// to provide a method of controlling the Bluetooth chooser during a test.
// Serves as a Bluetooth chooser factory for choosers that can be manually
// controlled through the Mojo API. Only one instance of this class will exist
// while the chooser is active.
//
// 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 FakeBluetoothChooser : public mojom::FakeBluetoothChooser,
public BluetoothChooser {
public:
~FakeBluetoothChooser() override;
// LayoutTestContentBrowserClient will create an instance of this class when a
// 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.
static std::unique_ptr<FakeBluetoothChooser> Create(
mojom::FakeBluetoothChooserRequest request);
// Sets the EventHandler that will handle events produced by the chooser.
void SetEventHandler(const EventHandler& event_handler);
// mojom::FakeBluetoothChooser overrides:
void WaitForEvents(uint32_t num_of_events,
WaitForEventsCallback callback) override;
void SelectPeripheral(const std::string& peripheral_address,
SelectPeripheralCallback callback) override;
void Cancel(CancelCallback callback) override;
void Rescan(RescanCallback callback) override;
// BluetoothChooser overrides:
void SetAdapterPresence(AdapterPresence presence) override;
void ShowDiscoveryState(DiscoveryState state) override;
void AddOrUpdateDevice(const std::string& device_id,
bool should_update_name,
const base::string16& device_name,
bool is_gatt_connected,
bool is_paired,
int signal_strength_level) override;
private:
explicit FakeBluetoothChooser(mojom::FakeBluetoothChooserRequest request);
// Stores the callback function that handles chooser events.
EventHandler event_handler_;
mojo::Binding<mojom::FakeBluetoothChooser> binding_;
DISALLOW_COPY_AND_ASSIGN(FakeBluetoothChooser);
};
} // namespace content
#endif // CONTENT_SHELL_BROWSER_LAYOUT_TEST_FAKE_BLUETOOTH_CHOOSER_H_
......@@ -14,6 +14,7 @@
#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/shell/browser/layout_test/blink_test_controller.h"
#include "content/shell/browser/layout_test/fake_bluetooth_chooser.h"
#include "content/shell/browser/layout_test/layout_test_bluetooth_fake_adapter_setter_impl.h"
#include "content/shell/browser/layout_test/layout_test_browser_context.h"
#include "content/shell/browser/layout_test/layout_test_browser_main_parts.h"
......@@ -65,6 +66,11 @@ void LayoutTestContentBrowserClient::SetPopupBlockingEnabled(
block_popups_ = block_popups;
}
std::unique_ptr<FakeBluetoothChooser>
LayoutTestContentBrowserClient::GetNextFakeBluetoothChooser() {
return std::move(next_fake_bluetooth_chooser_);
}
LayoutTestNotificationManager*
LayoutTestContentBrowserClient::GetLayoutTestNotificationManager() {
return layout_test_notification_manager_.get();
......@@ -93,12 +99,21 @@ void LayoutTestContentBrowserClient::ExposeInterfacesToRenderer(
content::BrowserThread::GetTaskRunnerForThread(
content::BrowserThread::UI);
registry->AddInterface(
base::Bind(&LayoutTestBluetoothFakeAdapterSetterImpl::Create),
base::BindRepeating(&LayoutTestBluetoothFakeAdapterSetterImpl::Create),
ui_task_runner);
registry->AddInterface(base::Bind(&bluetooth::FakeBluetooth::Create),
registry->AddInterface(base::BindRepeating(&bluetooth::FakeBluetooth::Create),
ui_task_runner);
// This class outlives |render_process_host|, which owns |registry|. Since
// CreateFakeBluetoothChooser will not be called after |registry| is deleted
// and |registry| is outlived by this class, it is safe to use
// base::Unretained.
registry->AddInterface(
base::BindRepeating(
&LayoutTestContentBrowserClient::CreateFakeBluetoothChooser,
base::Unretained(this)),
ui_task_runner);
registry->AddInterface(base::Bind(&MojoLayoutTestHelper::Create));
registry->AddInterface(base::BindRepeating(&MojoLayoutTestHelper::Create));
}
void LayoutTestContentBrowserClient::OverrideWebkitPrefs(
......@@ -201,4 +216,12 @@ LayoutTestContentBrowserClient::CreateLoginDelegate(
return nullptr;
}
// private
void LayoutTestContentBrowserClient::CreateFakeBluetoothChooser(
mojom::FakeBluetoothChooserRequest request) {
DCHECK(!next_fake_bluetooth_chooser_);
next_fake_bluetooth_chooser_ =
FakeBluetoothChooser::Create(std::move(request));
}
} // namespace content
......@@ -6,9 +6,11 @@
#define CONTENT_SHELL_BROWSER_LAYOUT_TEST_LAYOUT_TEST_CONTENT_BROWSER_CLIENT_H_
#include "content/shell/browser/shell_content_browser_client.h"
#include "content/shell/common/layout_test/fake_bluetooth_chooser.mojom.h"
namespace content {
class FakeBluetoothChooser;
class LayoutTestBrowserContext;
class LayoutTestNotificationManager;
......@@ -23,6 +25,9 @@ class LayoutTestContentBrowserClient : public ShellContentBrowserClient {
LayoutTestBrowserContext* GetLayoutTestBrowserContext();
void SetPopupBlockingEnabled(bool block_popups_);
// Retrieves the last created FakeBluetoothChooser instance.
std::unique_ptr<FakeBluetoothChooser> GetNextFakeBluetoothChooser();
// Implements the PlatformNotificationService interface.
LayoutTestNotificationManager* GetLayoutTestNotificationManager();
......@@ -77,9 +82,16 @@ class LayoutTestContentBrowserClient : public ShellContentBrowserClient {
auth_required_callback) override;
private:
// Creates and stores a FakeBluetoothChooser instance.
void CreateFakeBluetoothChooser(mojom::FakeBluetoothChooserRequest request);
std::unique_ptr<LayoutTestNotificationManager>
layout_test_notification_manager_;
bool block_popups_ = false;
// Stores the next instance of FakeBluetoothChooser that is to be returned
// when GetNextFakeBluetoothChooser is called.
std::unique_ptr<FakeBluetoothChooser> next_fake_bluetooth_chooser_;
};
} // content
......
per-file *_messages*.h=set noparent
per-file *_messages*.h=file://ipc/SECURITY_OWNERS
per-file *.mojom=set noparent
per-file *.mojom=file://ipc/SECURITY_OWNERS
// Copyright 2018 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 content.mojom;
// This interface is being developed to support Web Platform Tests for Web
// Bluetooth.
// https://docs.google.com/document/d/1Nhv_oVDCodd1pEH_jj9k8gF4rPGb_84VYaZ9IG8M_WY
//
// These interfaces are not intended to be used directly.
// `web-bluetooth-test.js` makes the Fake Bluetooth interface easier to work
// with.
// * Calls are synchronous.
// * IDs are cached.
//
// If another C++ client intends to use FakeBluetooth a C++ wrapper similar to
// `web-bluetooth-test.js` should be created.
//
// The implementation details of FakeBluetoothChooser can be found in the Web
// Bluetooth Test Scanning design document.
// https://docs.google.com/document/d/1XFl_4ZAgO8ddM6U53A9AfUuZeWgJnlYD5wtbXqEpzeg
// Indicates the types of Bluetooth chooser events.
enum ChooserEventType {
CHOOSER_OPENED,
SCAN_STARTED,
DEVICE_UPDATE,
ADAPTER_REMOVED,
ADAPTER_DISABLED,
ADAPTER_ENABLED,
DISCOVERY_FAILED_TO_START,
DISCOVERING,
DISCOVERY_IDLE,
ADD_DEVICE,
};
// FakeBluetoothChooser allows clients to control the global state of the
// Bluetooth chooser during a layout test.
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
// chooser.
SelectPeripheral(string peripheral_address) => ();
// Calls the event handler function with the CANCELLED event.
Cancel() => ();
// Calls the event handler function with the RESCAN event.
Rescan() => ();
};
// FakeBluetoothChooserEvent describes the type of chooser event that has been
// produced by the FakeBluetoothChooser.
struct FakeBluetoothChooserEvent {
ChooserEventType type;
// Describes the origin the chooser is currently displaying.
// This field will be used by the |CHOOSER_OPENED| event type.
string? origin;
// Describes the MAC address of the Bluetooth device.
string? peripheral_address;
};
<!DOCTYPE html>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="../../../resources/testdriver.js"></script>
<script src="../../../resources/testdriver-vendor.js"></script>
<script src="../../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
// TODO(https://crbug.com/719826): This is a temporary test to try the
// FakeBluetoothChooser API as it is implemented. This test should be delete after
// the feature is completed. The implementation details can be found in the design
// document.
// https://docs.google.com/document/d/1XFl_4ZAgO8ddM6U53A9AfUuZeWgJnlYD5wtbXqEpzeg
const test_desc = 'Ensure that the FakeBluetoothChooser API works correctly.';
bluetooth_test(() => navigator.bluetooth.test.simulateCentral({
state: 'powered-on'
})
.then(() => navigator.bluetooth.test.getManualChooser())
.then(chooser => assert_true(typeof chooser !== 'undefined')),
test_desc);
</script>
......@@ -42,6 +42,7 @@ function performChromiumSetup() {
`${prefix}/mojo_layouttest_test.mojom.js`,
`${prefix}/uuid.mojom.js`,
`${prefix}/fake_bluetooth.mojom.js`,
`${prefix}/fake_bluetooth_chooser.mojom.js`,
`${prefix}/web-bluetooth-test.js`,
].concat(extra))
// Call setBluetoothFakeAdapter() to clean up any fake adapters left over
......
// Copyright 2014 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.
'use strict';
(function() {
var mojomId = 'content/shell/common/layout_test/fake_bluetooth_chooser.mojom';
if (mojo.internal.isMojomLoaded(mojomId)) {
console.warn('The following mojom is loaded multiple times: ' + mojomId);
return;
}
mojo.internal.markMojomLoaded(mojomId);
var bindings = mojo;
var associatedBindings = mojo;
var codec = mojo.internal;
var validator = mojo.internal;
var exports = mojo.internal.exposeNamespace('content.mojom');
var ChooserEventType = {};
ChooserEventType.CHOOSER_OPENED = 0;
ChooserEventType.SCAN_STARTED = ChooserEventType.CHOOSER_OPENED + 1;
ChooserEventType.DEVICE_UPDATE = ChooserEventType.SCAN_STARTED + 1;
ChooserEventType.ADAPTER_REMOVED = ChooserEventType.DEVICE_UPDATE + 1;
ChooserEventType.ADAPTER_DISABLED = ChooserEventType.ADAPTER_REMOVED + 1;
ChooserEventType.ADAPTER_ENABLED = ChooserEventType.ADAPTER_DISABLED + 1;
ChooserEventType.DISCOVERY_FAILED_TO_START = ChooserEventType.ADAPTER_ENABLED + 1;
ChooserEventType.DISCOVERING = ChooserEventType.DISCOVERY_FAILED_TO_START + 1;
ChooserEventType.DISCOVERY_IDLE = ChooserEventType.DISCOVERING + 1;
ChooserEventType.ADD_DEVICE = ChooserEventType.DISCOVERY_IDLE + 1;
ChooserEventType.isKnownEnumValue = function(value) {
switch (value) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
return true;
}
return false;
};
ChooserEventType.validate = function(enumValue) {
var isExtensible = false;
if (isExtensible || this.isKnownEnumValue(enumValue))
return validator.validationError.NONE;
return validator.validationError.UNKNOWN_ENUM_VALUE;
};
function FakeBluetoothChooserEvent(values) {
this.initDefaults_();
this.initFields_(values);
}
FakeBluetoothChooserEvent.prototype.initDefaults_ = function() {
this.type = 0;
this.origin = null;
this.peripheralAddress = null;
};
FakeBluetoothChooserEvent.prototype.initFields_ = function(fields) {
for(var field in fields) {
if (this.hasOwnProperty(field))
this[field] = fields[field];
}
};
FakeBluetoothChooserEvent.validate = function(messageValidator, offset) {
var err;
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
if (err !== validator.validationError.NONE)
return err;
var kVersionSizes = [
{version: 0, numBytes: 32}
];
err = messageValidator.validateStructVersion(offset, kVersionSizes);
if (err !== validator.validationError.NONE)
return err;
// validate FakeBluetoothChooserEvent.type
err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, ChooserEventType);
if (err !== validator.validationError.NONE)
return err;
// validate FakeBluetoothChooserEvent.origin
err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, true)
if (err !== validator.validationError.NONE)
return err;
// validate FakeBluetoothChooserEvent.peripheralAddress
err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, true)
if (err !== validator.validationError.NONE)
return err;
return validator.validationError.NONE;
};
FakeBluetoothChooserEvent.encodedSize = codec.kStructHeaderSize + 24;
FakeBluetoothChooserEvent.decode = function(decoder) {
var packed;
var val = new FakeBluetoothChooserEvent();
var numberOfBytes = decoder.readUint32();
var version = decoder.readUint32();
val.type = decoder.decodeStruct(codec.Int32);
decoder.skip(1);
decoder.skip(1);
decoder.skip(1);
decoder.skip(1);
val.origin = decoder.decodeStruct(codec.NullableString);
val.peripheralAddress = decoder.decodeStruct(codec.NullableString);
return val;
};
FakeBluetoothChooserEvent.encode = function(encoder, val) {
var packed;
encoder.writeUint32(FakeBluetoothChooserEvent.encodedSize);
encoder.writeUint32(0);
encoder.encodeStruct(codec.Int32, val.type);
encoder.skip(1);
encoder.skip(1);
encoder.skip(1);
encoder.skip(1);
encoder.encodeStruct(codec.NullableString, val.origin);
encoder.encodeStruct(codec.NullableString, val.peripheralAddress);
};
function FakeBluetoothChooser_WaitForEvents_Params(values) {
this.initDefaults_();
this.initFields_(values);
}
FakeBluetoothChooser_WaitForEvents_Params.prototype.initDefaults_ = function() {
this.numOfEvents = 0;
};
FakeBluetoothChooser_WaitForEvents_Params.prototype.initFields_ = function(fields) {
for(var field in fields) {
if (this.hasOwnProperty(field))
this[field] = fields[field];
}
};
FakeBluetoothChooser_WaitForEvents_Params.validate = function(messageValidator, offset) {
var err;
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
if (err !== validator.validationError.NONE)
return err;
var kVersionSizes = [
{version: 0, numBytes: 16}
];
err = messageValidator.validateStructVersion(offset, kVersionSizes);
if (err !== validator.validationError.NONE)
return err;
return validator.validationError.NONE;
};
FakeBluetoothChooser_WaitForEvents_Params.encodedSize = codec.kStructHeaderSize + 8;
FakeBluetoothChooser_WaitForEvents_Params.decode = function(decoder) {
var packed;
var val = new FakeBluetoothChooser_WaitForEvents_Params();
var numberOfBytes = decoder.readUint32();
var version = decoder.readUint32();
val.numOfEvents = decoder.decodeStruct(codec.Uint32);
decoder.skip(1);
decoder.skip(1);
decoder.skip(1);
decoder.skip(1);
return val;
};
FakeBluetoothChooser_WaitForEvents_Params.encode = function(encoder, val) {
var packed;
encoder.writeUint32(FakeBluetoothChooser_WaitForEvents_Params.encodedSize);
encoder.writeUint32(0);
encoder.encodeStruct(codec.Uint32, val.numOfEvents);
encoder.skip(1);
encoder.skip(1);
encoder.skip(1);
encoder.skip(1);
};
function FakeBluetoothChooser_WaitForEvents_ResponseParams(values) {
this.initDefaults_();
this.initFields_(values);
}
FakeBluetoothChooser_WaitForEvents_ResponseParams.prototype.initDefaults_ = function() {
this.events = null;
};
FakeBluetoothChooser_WaitForEvents_ResponseParams.prototype.initFields_ = function(fields) {
for(var field in fields) {
if (this.hasOwnProperty(field))
this[field] = fields[field];
}
};
FakeBluetoothChooser_WaitForEvents_ResponseParams.validate = function(messageValidator, offset) {
var err;
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
if (err !== validator.validationError.NONE)
return err;
var kVersionSizes = [
{version: 0, numBytes: 16}
];
err = messageValidator.validateStructVersion(offset, kVersionSizes);
if (err !== validator.validationError.NONE)
return err;
// validate FakeBluetoothChooser_WaitForEvents_ResponseParams.events
err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 8, new codec.PointerTo(FakeBluetoothChooserEvent), false, [0], 0);
if (err !== validator.validationError.NONE)
return err;
return validator.validationError.NONE;
};
FakeBluetoothChooser_WaitForEvents_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
FakeBluetoothChooser_WaitForEvents_ResponseParams.decode = function(decoder) {
var packed;
var val = new FakeBluetoothChooser_WaitForEvents_ResponseParams();
var numberOfBytes = decoder.readUint32();
var version = decoder.readUint32();
val.events = decoder.decodeArrayPointer(new codec.PointerTo(FakeBluetoothChooserEvent));
return val;
};
FakeBluetoothChooser_WaitForEvents_ResponseParams.encode = function(encoder, val) {
var packed;
encoder.writeUint32(FakeBluetoothChooser_WaitForEvents_ResponseParams.encodedSize);
encoder.writeUint32(0);
encoder.encodeArrayPointer(new codec.PointerTo(FakeBluetoothChooserEvent), val.events);
};
function FakeBluetoothChooser_SelectPeripheral_Params(values) {
this.initDefaults_();
this.initFields_(values);
}
FakeBluetoothChooser_SelectPeripheral_Params.prototype.initDefaults_ = function() {
this.peripheralAddress = null;
};
FakeBluetoothChooser_SelectPeripheral_Params.prototype.initFields_ = function(fields) {
for(var field in fields) {
if (this.hasOwnProperty(field))
this[field] = fields[field];
}
};
FakeBluetoothChooser_SelectPeripheral_Params.validate = function(messageValidator, offset) {
var err;
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
if (err !== validator.validationError.NONE)
return err;
var kVersionSizes = [
{version: 0, numBytes: 16}
];
err = messageValidator.validateStructVersion(offset, kVersionSizes);
if (err !== validator.validationError.NONE)
return err;
// validate FakeBluetoothChooser_SelectPeripheral_Params.peripheralAddress
err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
if (err !== validator.validationError.NONE)
return err;
return validator.validationError.NONE;
};
FakeBluetoothChooser_SelectPeripheral_Params.encodedSize = codec.kStructHeaderSize + 8;
FakeBluetoothChooser_SelectPeripheral_Params.decode = function(decoder) {
var packed;
var val = new FakeBluetoothChooser_SelectPeripheral_Params();
var numberOfBytes = decoder.readUint32();
var version = decoder.readUint32();
val.peripheralAddress = decoder.decodeStruct(codec.String);
return val;
};
FakeBluetoothChooser_SelectPeripheral_Params.encode = function(encoder, val) {
var packed;
encoder.writeUint32(FakeBluetoothChooser_SelectPeripheral_Params.encodedSize);
encoder.writeUint32(0);
encoder.encodeStruct(codec.String, val.peripheralAddress);
};
function FakeBluetoothChooser_SelectPeripheral_ResponseParams(values) {
this.initDefaults_();
this.initFields_(values);
}
FakeBluetoothChooser_SelectPeripheral_ResponseParams.prototype.initDefaults_ = function() {
};
FakeBluetoothChooser_SelectPeripheral_ResponseParams.prototype.initFields_ = function(fields) {
for(var field in fields) {
if (this.hasOwnProperty(field))
this[field] = fields[field];
}
};
FakeBluetoothChooser_SelectPeripheral_ResponseParams.validate = function(messageValidator, offset) {
var err;
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
if (err !== validator.validationError.NONE)
return err;
var kVersionSizes = [
{version: 0, numBytes: 8}
];
err = messageValidator.validateStructVersion(offset, kVersionSizes);
if (err !== validator.validationError.NONE)
return err;
return validator.validationError.NONE;
};
FakeBluetoothChooser_SelectPeripheral_ResponseParams.encodedSize = codec.kStructHeaderSize + 0;
FakeBluetoothChooser_SelectPeripheral_ResponseParams.decode = function(decoder) {
var packed;
var val = new FakeBluetoothChooser_SelectPeripheral_ResponseParams();
var numberOfBytes = decoder.readUint32();
var version = decoder.readUint32();
return val;
};
FakeBluetoothChooser_SelectPeripheral_ResponseParams.encode = function(encoder, val) {
var packed;
encoder.writeUint32(FakeBluetoothChooser_SelectPeripheral_ResponseParams.encodedSize);
encoder.writeUint32(0);
};
function FakeBluetoothChooser_Cancel_Params(values) {
this.initDefaults_();
this.initFields_(values);
}
FakeBluetoothChooser_Cancel_Params.prototype.initDefaults_ = function() {
};
FakeBluetoothChooser_Cancel_Params.prototype.initFields_ = function(fields) {
for(var field in fields) {
if (this.hasOwnProperty(field))
this[field] = fields[field];
}
};
FakeBluetoothChooser_Cancel_Params.validate = function(messageValidator, offset) {
var err;
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
if (err !== validator.validationError.NONE)
return err;
var kVersionSizes = [
{version: 0, numBytes: 8}
];
err = messageValidator.validateStructVersion(offset, kVersionSizes);
if (err !== validator.validationError.NONE)
return err;
return validator.validationError.NONE;
};
FakeBluetoothChooser_Cancel_Params.encodedSize = codec.kStructHeaderSize + 0;
FakeBluetoothChooser_Cancel_Params.decode = function(decoder) {
var packed;
var val = new FakeBluetoothChooser_Cancel_Params();
var numberOfBytes = decoder.readUint32();
var version = decoder.readUint32();
return val;
};
FakeBluetoothChooser_Cancel_Params.encode = function(encoder, val) {
var packed;
encoder.writeUint32(FakeBluetoothChooser_Cancel_Params.encodedSize);
encoder.writeUint32(0);
};
function FakeBluetoothChooser_Cancel_ResponseParams(values) {
this.initDefaults_();
this.initFields_(values);
}
FakeBluetoothChooser_Cancel_ResponseParams.prototype.initDefaults_ = function() {
};
FakeBluetoothChooser_Cancel_ResponseParams.prototype.initFields_ = function(fields) {
for(var field in fields) {
if (this.hasOwnProperty(field))
this[field] = fields[field];
}
};
FakeBluetoothChooser_Cancel_ResponseParams.validate = function(messageValidator, offset) {
var err;
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
if (err !== validator.validationError.NONE)
return err;
var kVersionSizes = [
{version: 0, numBytes: 8}
];
err = messageValidator.validateStructVersion(offset, kVersionSizes);
if (err !== validator.validationError.NONE)
return err;
return validator.validationError.NONE;
};
FakeBluetoothChooser_Cancel_ResponseParams.encodedSize = codec.kStructHeaderSize + 0;
FakeBluetoothChooser_Cancel_ResponseParams.decode = function(decoder) {
var packed;
var val = new FakeBluetoothChooser_Cancel_ResponseParams();
var numberOfBytes = decoder.readUint32();
var version = decoder.readUint32();
return val;
};
FakeBluetoothChooser_Cancel_ResponseParams.encode = function(encoder, val) {
var packed;
encoder.writeUint32(FakeBluetoothChooser_Cancel_ResponseParams.encodedSize);
encoder.writeUint32(0);
};
function FakeBluetoothChooser_Rescan_Params(values) {
this.initDefaults_();
this.initFields_(values);
}
FakeBluetoothChooser_Rescan_Params.prototype.initDefaults_ = function() {
};
FakeBluetoothChooser_Rescan_Params.prototype.initFields_ = function(fields) {
for(var field in fields) {
if (this.hasOwnProperty(field))
this[field] = fields[field];
}
};
FakeBluetoothChooser_Rescan_Params.validate = function(messageValidator, offset) {
var err;
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
if (err !== validator.validationError.NONE)
return err;
var kVersionSizes = [
{version: 0, numBytes: 8}
];
err = messageValidator.validateStructVersion(offset, kVersionSizes);
if (err !== validator.validationError.NONE)
return err;
return validator.validationError.NONE;
};
FakeBluetoothChooser_Rescan_Params.encodedSize = codec.kStructHeaderSize + 0;
FakeBluetoothChooser_Rescan_Params.decode = function(decoder) {
var packed;
var val = new FakeBluetoothChooser_Rescan_Params();
var numberOfBytes = decoder.readUint32();
var version = decoder.readUint32();
return val;
};
FakeBluetoothChooser_Rescan_Params.encode = function(encoder, val) {
var packed;
encoder.writeUint32(FakeBluetoothChooser_Rescan_Params.encodedSize);
encoder.writeUint32(0);
};
function FakeBluetoothChooser_Rescan_ResponseParams(values) {
this.initDefaults_();
this.initFields_(values);
}
FakeBluetoothChooser_Rescan_ResponseParams.prototype.initDefaults_ = function() {
};
FakeBluetoothChooser_Rescan_ResponseParams.prototype.initFields_ = function(fields) {
for(var field in fields) {
if (this.hasOwnProperty(field))
this[field] = fields[field];
}
};
FakeBluetoothChooser_Rescan_ResponseParams.validate = function(messageValidator, offset) {
var err;
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
if (err !== validator.validationError.NONE)
return err;
var kVersionSizes = [
{version: 0, numBytes: 8}
];
err = messageValidator.validateStructVersion(offset, kVersionSizes);
if (err !== validator.validationError.NONE)
return err;
return validator.validationError.NONE;
};
FakeBluetoothChooser_Rescan_ResponseParams.encodedSize = codec.kStructHeaderSize + 0;
FakeBluetoothChooser_Rescan_ResponseParams.decode = function(decoder) {
var packed;
var val = new FakeBluetoothChooser_Rescan_ResponseParams();
var numberOfBytes = decoder.readUint32();
var version = decoder.readUint32();
return val;
};
FakeBluetoothChooser_Rescan_ResponseParams.encode = function(encoder, val) {
var packed;
encoder.writeUint32(FakeBluetoothChooser_Rescan_ResponseParams.encodedSize);
encoder.writeUint32(0);
};
var kFakeBluetoothChooser_WaitForEvents_Name = 457051710;
var kFakeBluetoothChooser_SelectPeripheral_Name = 1924310743;
var kFakeBluetoothChooser_Cancel_Name = 1388880682;
var kFakeBluetoothChooser_Rescan_Name = 2112671529;
function FakeBluetoothChooserPtr(handleOrPtrInfo) {
this.ptr = new bindings.InterfacePtrController(FakeBluetoothChooser,
handleOrPtrInfo);
}
function FakeBluetoothChooserAssociatedPtr(associatedInterfacePtrInfo) {
this.ptr = new associatedBindings.AssociatedInterfacePtrController(
FakeBluetoothChooser, associatedInterfacePtrInfo);
}
FakeBluetoothChooserAssociatedPtr.prototype =
Object.create(FakeBluetoothChooserPtr.prototype);
FakeBluetoothChooserAssociatedPtr.prototype.constructor =
FakeBluetoothChooserAssociatedPtr;
function FakeBluetoothChooserProxy(receiver) {
this.receiver_ = receiver;
}
FakeBluetoothChooserPtr.prototype.waitForEvents = function() {
return FakeBluetoothChooserProxy.prototype.waitForEvents
.apply(this.ptr.getProxy(), arguments);
};
FakeBluetoothChooserProxy.prototype.waitForEvents = function(numOfEvents) {
var params = new FakeBluetoothChooser_WaitForEvents_Params();
params.numOfEvents = numOfEvents;
return new Promise(function(resolve, reject) {
var builder = new codec.MessageV1Builder(
kFakeBluetoothChooser_WaitForEvents_Name,
codec.align(FakeBluetoothChooser_WaitForEvents_Params.encodedSize),
codec.kMessageExpectsResponse, 0);
builder.encodeStruct(FakeBluetoothChooser_WaitForEvents_Params, params);
var message = builder.finish();
this.receiver_.acceptAndExpectResponse(message).then(function(message) {
var reader = new codec.MessageReader(message);
var responseParams =
reader.decodeStruct(FakeBluetoothChooser_WaitForEvents_ResponseParams);
resolve(responseParams);
}).catch(function(result) {
reject(Error("Connection error: " + result));
});
}.bind(this));
};
FakeBluetoothChooserPtr.prototype.selectPeripheral = function() {
return FakeBluetoothChooserProxy.prototype.selectPeripheral
.apply(this.ptr.getProxy(), arguments);
};
FakeBluetoothChooserProxy.prototype.selectPeripheral = function(peripheralAddress) {
var params = new FakeBluetoothChooser_SelectPeripheral_Params();
params.peripheralAddress = peripheralAddress;
return new Promise(function(resolve, reject) {
var builder = new codec.MessageV1Builder(
kFakeBluetoothChooser_SelectPeripheral_Name,
codec.align(FakeBluetoothChooser_SelectPeripheral_Params.encodedSize),
codec.kMessageExpectsResponse, 0);
builder.encodeStruct(FakeBluetoothChooser_SelectPeripheral_Params, params);
var message = builder.finish();
this.receiver_.acceptAndExpectResponse(message).then(function(message) {
var reader = new codec.MessageReader(message);
var responseParams =
reader.decodeStruct(FakeBluetoothChooser_SelectPeripheral_ResponseParams);
resolve(responseParams);
}).catch(function(result) {
reject(Error("Connection error: " + result));
});
}.bind(this));
};
FakeBluetoothChooserPtr.prototype.cancel = function() {
return FakeBluetoothChooserProxy.prototype.cancel
.apply(this.ptr.getProxy(), arguments);
};
FakeBluetoothChooserProxy.prototype.cancel = function() {
var params = new FakeBluetoothChooser_Cancel_Params();
return new Promise(function(resolve, reject) {
var builder = new codec.MessageV1Builder(
kFakeBluetoothChooser_Cancel_Name,
codec.align(FakeBluetoothChooser_Cancel_Params.encodedSize),
codec.kMessageExpectsResponse, 0);
builder.encodeStruct(FakeBluetoothChooser_Cancel_Params, params);
var message = builder.finish();
this.receiver_.acceptAndExpectResponse(message).then(function(message) {
var reader = new codec.MessageReader(message);
var responseParams =
reader.decodeStruct(FakeBluetoothChooser_Cancel_ResponseParams);
resolve(responseParams);
}).catch(function(result) {
reject(Error("Connection error: " + result));
});
}.bind(this));
};
FakeBluetoothChooserPtr.prototype.rescan = function() {
return FakeBluetoothChooserProxy.prototype.rescan
.apply(this.ptr.getProxy(), arguments);
};
FakeBluetoothChooserProxy.prototype.rescan = function() {
var params = new FakeBluetoothChooser_Rescan_Params();
return new Promise(function(resolve, reject) {
var builder = new codec.MessageV1Builder(
kFakeBluetoothChooser_Rescan_Name,
codec.align(FakeBluetoothChooser_Rescan_Params.encodedSize),
codec.kMessageExpectsResponse, 0);
builder.encodeStruct(FakeBluetoothChooser_Rescan_Params, params);
var message = builder.finish();
this.receiver_.acceptAndExpectResponse(message).then(function(message) {
var reader = new codec.MessageReader(message);
var responseParams =
reader.decodeStruct(FakeBluetoothChooser_Rescan_ResponseParams);
resolve(responseParams);
}).catch(function(result) {
reject(Error("Connection error: " + result));
});
}.bind(this));
};
function FakeBluetoothChooserStub(delegate) {
this.delegate_ = delegate;
}
FakeBluetoothChooserStub.prototype.waitForEvents = function(numOfEvents) {
return this.delegate_ && this.delegate_.waitForEvents && this.delegate_.waitForEvents(numOfEvents);
}
FakeBluetoothChooserStub.prototype.selectPeripheral = function(peripheralAddress) {
return this.delegate_ && this.delegate_.selectPeripheral && this.delegate_.selectPeripheral(peripheralAddress);
}
FakeBluetoothChooserStub.prototype.cancel = function() {
return this.delegate_ && this.delegate_.cancel && this.delegate_.cancel();
}
FakeBluetoothChooserStub.prototype.rescan = function() {
return this.delegate_ && this.delegate_.rescan && this.delegate_.rescan();
}
FakeBluetoothChooserStub.prototype.accept = function(message) {
var reader = new codec.MessageReader(message);
switch (reader.messageName) {
default:
return false;
}
};
FakeBluetoothChooserStub.prototype.acceptWithResponder =
function(message, responder) {
var reader = new codec.MessageReader(message);
switch (reader.messageName) {
case kFakeBluetoothChooser_WaitForEvents_Name:
var params = reader.decodeStruct(FakeBluetoothChooser_WaitForEvents_Params);
this.waitForEvents(params.numOfEvents).then(function(response) {
var responseParams =
new FakeBluetoothChooser_WaitForEvents_ResponseParams();
responseParams.events = response.events;
var builder = new codec.MessageV1Builder(
kFakeBluetoothChooser_WaitForEvents_Name,
codec.align(FakeBluetoothChooser_WaitForEvents_ResponseParams.encodedSize),
codec.kMessageIsResponse, reader.requestID);
builder.encodeStruct(FakeBluetoothChooser_WaitForEvents_ResponseParams,
responseParams);
var message = builder.finish();
responder.accept(message);
});
return true;
case kFakeBluetoothChooser_SelectPeripheral_Name:
var params = reader.decodeStruct(FakeBluetoothChooser_SelectPeripheral_Params);
this.selectPeripheral(params.peripheralAddress).then(function(response) {
var responseParams =
new FakeBluetoothChooser_SelectPeripheral_ResponseParams();
var builder = new codec.MessageV1Builder(
kFakeBluetoothChooser_SelectPeripheral_Name,
codec.align(FakeBluetoothChooser_SelectPeripheral_ResponseParams.encodedSize),
codec.kMessageIsResponse, reader.requestID);
builder.encodeStruct(FakeBluetoothChooser_SelectPeripheral_ResponseParams,
responseParams);
var message = builder.finish();
responder.accept(message);
});
return true;
case kFakeBluetoothChooser_Cancel_Name:
var params = reader.decodeStruct(FakeBluetoothChooser_Cancel_Params);
this.cancel().then(function(response) {
var responseParams =
new FakeBluetoothChooser_Cancel_ResponseParams();
var builder = new codec.MessageV1Builder(
kFakeBluetoothChooser_Cancel_Name,
codec.align(FakeBluetoothChooser_Cancel_ResponseParams.encodedSize),
codec.kMessageIsResponse, reader.requestID);
builder.encodeStruct(FakeBluetoothChooser_Cancel_ResponseParams,
responseParams);
var message = builder.finish();
responder.accept(message);
});
return true;
case kFakeBluetoothChooser_Rescan_Name:
var params = reader.decodeStruct(FakeBluetoothChooser_Rescan_Params);
this.rescan().then(function(response) {
var responseParams =
new FakeBluetoothChooser_Rescan_ResponseParams();
var builder = new codec.MessageV1Builder(
kFakeBluetoothChooser_Rescan_Name,
codec.align(FakeBluetoothChooser_Rescan_ResponseParams.encodedSize),
codec.kMessageIsResponse, reader.requestID);
builder.encodeStruct(FakeBluetoothChooser_Rescan_ResponseParams,
responseParams);
var message = builder.finish();
responder.accept(message);
});
return true;
default:
return false;
}
};
function validateFakeBluetoothChooserRequest(messageValidator) {
var message = messageValidator.message;
var paramsClass = null;
switch (message.getName()) {
case kFakeBluetoothChooser_WaitForEvents_Name:
if (message.expectsResponse())
paramsClass = FakeBluetoothChooser_WaitForEvents_Params;
break;
case kFakeBluetoothChooser_SelectPeripheral_Name:
if (message.expectsResponse())
paramsClass = FakeBluetoothChooser_SelectPeripheral_Params;
break;
case kFakeBluetoothChooser_Cancel_Name:
if (message.expectsResponse())
paramsClass = FakeBluetoothChooser_Cancel_Params;
break;
case kFakeBluetoothChooser_Rescan_Name:
if (message.expectsResponse())
paramsClass = FakeBluetoothChooser_Rescan_Params;
break;
}
if (paramsClass === null)
return validator.validationError.NONE;
return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
}
function validateFakeBluetoothChooserResponse(messageValidator) {
var message = messageValidator.message;
var paramsClass = null;
switch (message.getName()) {
case kFakeBluetoothChooser_WaitForEvents_Name:
if (message.isResponse())
paramsClass = FakeBluetoothChooser_WaitForEvents_ResponseParams;
break;
case kFakeBluetoothChooser_SelectPeripheral_Name:
if (message.isResponse())
paramsClass = FakeBluetoothChooser_SelectPeripheral_ResponseParams;
break;
case kFakeBluetoothChooser_Cancel_Name:
if (message.isResponse())
paramsClass = FakeBluetoothChooser_Cancel_ResponseParams;
break;
case kFakeBluetoothChooser_Rescan_Name:
if (message.isResponse())
paramsClass = FakeBluetoothChooser_Rescan_ResponseParams;
break;
}
if (paramsClass === null)
return validator.validationError.NONE;
return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
}
var FakeBluetoothChooser = {
name: 'content::mojom::FakeBluetoothChooser',
kVersion: 0,
ptrClass: FakeBluetoothChooserPtr,
proxyClass: FakeBluetoothChooserProxy,
stubClass: FakeBluetoothChooserStub,
validateRequest: validateFakeBluetoothChooserRequest,
validateResponse: validateFakeBluetoothChooserResponse,
};
FakeBluetoothChooserStub.prototype.validator = validateFakeBluetoothChooserRequest;
FakeBluetoothChooserProxy.prototype.validator = validateFakeBluetoothChooserResponse;
exports.ChooserEventType = ChooserEventType;
exports.FakeBluetoothChooserEvent = FakeBluetoothChooserEvent;
exports.FakeBluetoothChooser = FakeBluetoothChooser;
exports.FakeBluetoothChooserPtr = FakeBluetoothChooserPtr;
exports.FakeBluetoothChooserAssociatedPtr = FakeBluetoothChooserAssociatedPtr;
})();
\ No newline at end of file
......@@ -65,7 +65,7 @@ class FakeBluetooth {
constructor() {
this.fake_bluetooth_ptr_ = new bluetooth.mojom.FakeBluetoothPtr();
Mojo.bindInterface(bluetooth.mojom.FakeBluetooth.name,
mojo.makeRequest(this.fake_bluetooth_ptr_).handle, "process");
mojo.makeRequest(this.fake_bluetooth_ptr_).handle, 'process');
}
// Set it to indicate whether the platform supports BLE. For example,
......@@ -102,6 +102,15 @@ class FakeBluetooth {
let {consumed} = await this.fake_bluetooth_ptr_.allResponsesConsumed();
return consumed;
}
// Returns a promise that resolves with a FakeChooser that clients can use to
// simulate chooser events.
async getManualChooser() {
if (typeof this.fake_chooser_ === 'undefined') {
this.fake_chooser_ = new FakeChooser();
}
return this.fake_chooser_;
}
}
// FakeCentral allows clients to simulate events that a device in the
......@@ -437,6 +446,17 @@ class FakeRemoteGATTDescriptor {
}
}
// FakeChooser allows clients to simulate events that a user would trigger when
// using the Bluetooth chooser, and monitor the events that are produced.
class FakeChooser {
constructor() {
this.fake_bluetooth_chooser_ptr_ =
new content.mojom.FakeBluetoothChooserPtr();
Mojo.bindInterface(content.mojom.FakeBluetoothChooser.name,
mojo.makeRequest(this.fake_bluetooth_chooser_ptr_).handle, 'process');
}
}
// If this line fails, it means that current environment does not support the
// Web Bluetooth Test API.
try {
......
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