summaryrefslogtreecommitdiff
path: root/chromium/third_party/nearby
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2021-09-01 11:08:40 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2021-10-01 12:16:21 +0000
commit03c549e0392f92c02536d3f86d5e1d8dfa3435ac (patch)
treefe49d170a929b34ba82cd10db1a0bd8e3760fa4b /chromium/third_party/nearby
parent5d013f5804a0d91fcf6c626b2d6fb6eca5c845b0 (diff)
downloadqtwebengine-chromium-03c549e0392f92c02536d3f86d5e1d8dfa3435ac.tar.gz
BASELINE: Update Chromium to 91.0.4472.160
Change-Id: I0def1f08a2412aeed79a9ab95dd50eb5c3f65f31 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/nearby')
-rw-r--r--chromium/third_party/nearby/BUILD.gn12
-rw-r--r--chromium/third_party/nearby/README.chromium2
-rw-r--r--chromium/third_party/nearby/src/cpp/core/BUILD5
-rw-r--r--chromium/third_party/nearby/src/cpp/core/core.cc17
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/base_bwu_handler.h2
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/base_endpoint_channel.cc42
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/base_endpoint_channel.h1
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/base_endpoint_channel_test.cc48
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/base_pcp_handler.cc689
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/base_pcp_handler.h30
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/base_pcp_handler_test.cc4
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/ble_endpoint_channel.h1
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/bluetooth_bwu_handler.h2
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/bluetooth_endpoint_channel.h1
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/bwu_handler.h1
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/bwu_manager.cc108
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/bwu_manager.h5
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/bwu_manager_test.cc38
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/client_proxy.h1
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/encryption_runner.cc2
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/endpoint_channel_manager.h4
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/endpoint_manager.cc172
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/endpoint_manager.h19
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/endpoint_manager_test.cc5
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/internal_payload.h1
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/internal_payload_factory.h1
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/mediums/BUILD24
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/mediums/ble.cc11
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/mediums/bluetooth_classic.cc28
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/mediums/utils.h1
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc.cc121
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc.h23
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/BUILD5
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/connection_flow.cc488
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/connection_flow.h135
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/connection_flow_test.cc221
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/data_channel_listener.h18
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/data_channel_observer_impl.cc42
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/data_channel_observer_impl.h49
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/peer_connection_observer_impl.cc104
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/peer_connection_observer_impl.h68
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/signaling_frames_test.cc4
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket.cc103
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket.h38
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket_test.cc82
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket_wrapper.h8
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc_test.cc4
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/mediums/wifi_lan.cc1
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/offline_frames.cc16
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/offline_frames.h8
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/offline_frames_test.cc9
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/offline_frames_validator.cc4
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/offline_frames_validator_test.cc21
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/offline_simulation_user.h10
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/p2p_cluster_pcp_handler.cc632
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/p2p_cluster_pcp_handler.h1
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/payload_manager.cc74
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/payload_manager.h5
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/pcp_handler.h1
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/service_controller_router.cc117
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/service_controller_router.h3
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/simulation_user.h10
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/webrtc_endpoint_channel.h1
-rw-r--r--chromium/third_party/nearby/src/cpp/core/internal/wifi_lan_endpoint_channel.h1
-rw-r--r--chromium/third_party/nearby/src/cpp/core/options.h4
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/api/BUILD1
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/api/log_message.h4
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/api/webrtc.h1
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/base/BUILD1
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/base/cancellation_flag.cc38
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/base/cancellation_flag.h31
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/base/cancellation_flag_listener.h43
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/base/cancellation_flag_test.cc127
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/base/feature_flags.h3
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/base/feature_flags_test.cc9
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/base/logging.h5
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/base/medium_environment.cc11
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/base/medium_environment.h6
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/g3/ble.cc10
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/g3/bluetooth_classic.cc6
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/g3/log_message.cc4
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/g3/webrtc.cc16
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/g3/webrtc.h5
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/g3/wifi_lan.cc6
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/shared/BUILD6
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/BUILD104
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/atomic_boolean.h47
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/atomic_reference.h43
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/ble.h155
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/bluetooth_adapter.h68
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/bluetooth_classic.h186
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/cancelable.h39
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/condition_variable.h54
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/count_down_latch.h47
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/crypto.cc54
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/crypto_test.cc50
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/executor.h48
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/future.h50
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/input_file.h50
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/listenable_future.h41
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/log_message.cc29
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/log_message.h50
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/mutex.h43
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/output_file.h47
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/platform.cc158
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/scheduled_executor.h59
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/server_sync.h90
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/settable_future.h51
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/submittable_executor.h55
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/system_clock.cc36
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/webrtc.h78
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/wifi.h98
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/impl/windows/wifi_lan.h160
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/public/BUILD4
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/public/ble_test.cc8
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/public/bluetooth_classic.h14
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/public/bluetooth_classic_test.cc28
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/public/count_down_latch_test.cc8
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/public/monitored_runnable.cc59
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/public/monitored_runnable.h48
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/public/pending_job_registry.cc92
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/public/pending_job_registry.h55
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/public/scheduled_executor.h9
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/public/single_thread_executor_test.cc19
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/public/submittable_executor.h13
-rw-r--r--chromium/third_party/nearby/src/cpp/platform/public/wifi_lan_test.cc9
-rw-r--r--chromium/third_party/nearby/src/proto/BUILD20
-rw-r--r--chromium/third_party/nearby/src/proto/connections/offline_wire_formats.proto2
-rw-r--r--chromium/third_party/nearby/src/proto/connections_enums.proto4
-rw-r--r--chromium/third_party/nearby/src/proto/discovery_enums.proto5
-rw-r--r--chromium/third_party/nearby/src/proto/magic_pair_enums.proto2
-rw-r--r--chromium/third_party/nearby/src/proto/nearby_event_codes.proto5
-rw-r--r--chromium/third_party/nearby/src/proto/sharing_enums.proto9
-rw-r--r--chromium/third_party/nearby/src/proto/uwb_enums.proto41
134 files changed, 4833 insertions, 1652 deletions
diff --git a/chromium/third_party/nearby/BUILD.gn b/chromium/third_party/nearby/BUILD.gn
index 61e188dac19..cf400abf858 100644
--- a/chromium/third_party/nearby/BUILD.gn
+++ b/chromium/third_party/nearby/BUILD.gn
@@ -193,7 +193,11 @@ source_set("platform_base_cancellation_flag") {
source_set("platform_public_types") {
public_configs = [ ":nearby_include_config" ]
- sources = [ "src/cpp/platform/public/pipe.cc" ]
+ sources = [
+ "src/cpp/platform/public/monitored_runnable.cc",
+ "src/cpp/platform/public/pending_job_registry.cc",
+ "src/cpp/platform/public/pipe.cc",
+ ]
public = [
"src/cpp/platform/public/atomic_boolean.h",
"src/cpp/platform/public/atomic_reference.h",
@@ -205,9 +209,11 @@ source_set("platform_public_types") {
"src/cpp/platform/public/file.h",
"src/cpp/platform/public/future.h",
"src/cpp/platform/public/logging.h",
+ "src/cpp/platform/public/monitored_runnable.h",
"src/cpp/platform/public/multi_thread_executor.h",
"src/cpp/platform/public/mutex.h",
"src/cpp/platform/public/mutex_lock.h",
+ "src/cpp/platform/public/pending_job_registry.h",
"src/cpp/platform/public/pipe.h",
"src/cpp/platform/public/scheduled_executor.h",
"src/cpp/platform/public/settable_future.h",
@@ -465,8 +471,6 @@ source_set("core_internal_mediums_webrtc") {
sources = [
"src/cpp/core/internal/mediums/utils.cc",
"src/cpp/core/internal/mediums/webrtc/connection_flow.cc",
- "src/cpp/core/internal/mediums/webrtc/data_channel_observer_impl.cc",
- "src/cpp/core/internal/mediums/webrtc/peer_connection_observer_impl.cc",
"src/cpp/core/internal/mediums/webrtc/peer_id.cc",
"src/cpp/core/internal/mediums/webrtc/signaling_frames.cc",
"src/cpp/core/internal/mediums/webrtc/webrtc_socket.cc",
@@ -475,9 +479,7 @@ source_set("core_internal_mediums_webrtc") {
"src/cpp/core/internal/mediums/utils.h",
"src/cpp/core/internal/mediums/webrtc/connection_flow.h",
"src/cpp/core/internal/mediums/webrtc/data_channel_listener.h",
- "src/cpp/core/internal/mediums/webrtc/data_channel_observer_impl.h",
"src/cpp/core/internal/mediums/webrtc/local_ice_candidate_listener.h",
- "src/cpp/core/internal/mediums/webrtc/peer_connection_observer_impl.h",
"src/cpp/core/internal/mediums/webrtc/peer_id.h",
"src/cpp/core/internal/mediums/webrtc/session_description_wrapper.h",
"src/cpp/core/internal/mediums/webrtc/signaling_frames.h",
diff --git a/chromium/third_party/nearby/README.chromium b/chromium/third_party/nearby/README.chromium
index 57f8ca0399b..d850a328ea0 100644
--- a/chromium/third_party/nearby/README.chromium
+++ b/chromium/third_party/nearby/README.chromium
@@ -1,7 +1,7 @@
Name: Nearby Connections Library
Short Name: Nearby
URL: https://github.com/google/nearby-connections
-Version: a7b99e7509c3734b94a151739bc4035de6497a37
+Version: 93eec2c07b588985da41af77a4589dd0de37c677
License: Apache 2.0
License File: LICENSE
Security Critical: yes
diff --git a/chromium/third_party/nearby/src/cpp/core/BUILD b/chromium/third_party/nearby/src/cpp/core/BUILD
index f0b551ee31a..6a6ebd27ce6 100644
--- a/chromium/third_party/nearby/src/cpp/core/BUILD
+++ b/chromium/third_party/nearby/src/cpp/core/BUILD
@@ -26,7 +26,7 @@ cc_library(
deps = [
":core_types",
"//core/internal",
- "//platform/public:comm",
+ "//platform/base",
"//platform/public:logging",
"//platform/public:types",
"//absl/strings",
@@ -54,8 +54,6 @@ cc_library(
deps = [
"//platform/base",
"//platform/base:util",
- "//platform/public:comm",
- "//platform/public:logging",
"//platform/public:types",
"//proto:connections_enums_portable_proto",
"//absl/strings",
@@ -81,7 +79,6 @@ cc_test(
"//core/internal:internal_test",
"//platform/base",
"//platform/impl/g3", # build_cleaner: keep
- "//platform/public:comm",
"//platform/public:logging",
"//platform/public:types",
"//testing/base/public:gunit_main",
diff --git a/chromium/third_party/nearby/src/cpp/core/core.cc b/chromium/third_party/nearby/src/cpp/core/core.cc
index 11dd795f61e..9c7813b1f71 100644
--- a/chromium/third_party/nearby/src/cpp/core/core.cc
+++ b/chromium/third_party/nearby/src/cpp/core/core.cc
@@ -18,6 +18,7 @@
#include <vector>
#include "core/options.h"
+#include "platform/base/feature_flags.h"
#include "platform/public/count_down_latch.h"
#include "platform/public/logging.h"
#include "absl/time/clock.h"
@@ -78,6 +79,22 @@ void Core::RequestConnection(absl::string_view endpoint_id,
ResultCallback callback) {
assert(!endpoint_id.empty());
+ // Assign the default from feature flags for the keep-alive frame interval and
+ // timeout values if client don't mind them or has the unexpected ones.
+ if (options.keep_alive_interval_millis == 0 ||
+ options.keep_alive_timeout_millis == 0 ||
+ options.keep_alive_interval_millis >= options.keep_alive_timeout_millis) {
+ NEARBY_LOG(
+ WARNING,
+ "Client request connection with keep-alive frame as interval=%d, "
+ "timeout=%d, which is un-expected. Change to default.",
+ options.keep_alive_interval_millis, options.keep_alive_timeout_millis);
+ options.keep_alive_interval_millis =
+ FeatureFlags::GetInstance().GetFlags().keep_alive_interval_millis;
+ options.keep_alive_timeout_millis =
+ FeatureFlags::GetInstance().GetFlags().keep_alive_timeout_millis;
+ }
+
router_.RequestConnection(&client_, endpoint_id, info, options, callback);
}
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/base_bwu_handler.h b/chromium/third_party/nearby/src/cpp/core/internal/base_bwu_handler.h
index 7bcde6f5263..71e35123967 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/base_bwu_handler.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/base_bwu_handler.h
@@ -22,12 +22,10 @@
#include "core/internal/bwu_handler.h"
#include "core/internal/client_proxy.h"
#include "core/internal/endpoint_channel_manager.h"
-#include "proto/connections/offline_wire_formats.pb.h"
#include "platform/public/cancelable_alarm.h"
#include "platform/public/count_down_latch.h"
#include "platform/public/scheduled_executor.h"
#include "platform/public/single_thread_executor.h"
-#include "proto/connections_enums.pb.h"
#include "absl/container/flat_hash_map.h"
#include "absl/time/clock.h"
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/base_endpoint_channel.cc b/chromium/third_party/nearby/src/cpp/core/internal/base_endpoint_channel.cc
index 30e8c8bec57..df5c2d5980e 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/base_endpoint_channel.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/base_endpoint_channel.cc
@@ -66,6 +66,7 @@ ExceptionOr<ByteArray> ReadExactly(InputStream* reader, std::int64_t size) {
ByteArray result = read_bytes.result();
if (result.Empty()) {
+ NEARBY_LOGS(WARNING) << __func__ << ": Empty result when reading bytes.";
return ExceptionOr<ByteArray>(Exception::kIo);
}
@@ -106,6 +107,8 @@ ExceptionOr<ByteArray> BaseEndpointChannel::Read() {
}
if (read_int.result() < 0 || read_int.result() > kMaxAllowedReadBytes) {
+ NEARBY_LOGS(WARNING) << __func__ << ": Read an invalid number of bytes: "
+ << read_int.result();
return ExceptionOr<ByteArray>(Exception::kIo);
}
@@ -134,12 +137,24 @@ ExceptionOr<ByteArray> BaseEndpointChannel::Read() {
// TODO(apolyudov): verify this happens at most once per session.
result = {};
auto parsed = parser::FromBytes(ByteArray(input));
- if (parsed.ok() &&
- parser::GetFrameType(parsed.result()) == V1Frame::KEEP_ALIVE) {
- result = ByteArray(input);
+ if (parsed.ok()) {
+ if (parser::GetFrameType(parsed.result()) == V1Frame::KEEP_ALIVE) {
+ NEARBY_LOGS(INFO)
+ << __func__
+ << ": Read unencrypted KEEP_ALIVE on encrypted channel.";
+ result = ByteArray(input);
+ } else {
+ NEARBY_LOGS(WARNING)
+ << __func__ << ": Read unexpected unencrypted frame of type "
+ << parser::GetFrameType(parsed.result());
+ }
+ } else {
+ NEARBY_LOGS(WARNING)
+ << __func__ << ": Unable to parse data as unencrypted message.";
}
}
if (result.Empty()) {
+ NEARBY_LOGS(WARNING) << __func__ << ": Unable to parse read result.";
return ExceptionOr<ByteArray>(Exception::kInvalidProtocolBuffer);
}
}
@@ -174,7 +189,10 @@ Exception BaseEndpointChannel::Write(const ByteArray& data) {
// If encryption is enabled, encode the message.
std::unique_ptr<std::string> encrypted =
crypto_context_->EncodeMessageToPeer(std::string(data));
- if (!encrypted) return {Exception::kIo};
+ if (!encrypted) {
+ NEARBY_LOGS(WARNING) << __func__ << ": Failed to encrypt data.";
+ return {Exception::kIo};
+ }
encrypted_data = ByteArray(std::move(*encrypted));
data_to_write = &encrypted_data;
}
@@ -183,14 +201,20 @@ Exception BaseEndpointChannel::Write(const ByteArray& data) {
Exception write_exception =
WriteInt(writer_, static_cast<std::int32_t>(data_to_write->size()));
if (write_exception.Raised()) {
+ NEARBY_LOGS(WARNING) << __func__ << ": Failed to write header: "
+ << write_exception.value;
return write_exception;
}
write_exception = writer_->Write(*data_to_write);
if (write_exception.Raised()) {
+ NEARBY_LOGS(WARNING) << __func__ << ": Failed to write data: "
+ << write_exception.value;
return write_exception;
}
Exception flush_exception = writer_->Flush();
if (flush_exception.Raised()) {
+ NEARBY_LOGS(WARNING) << __func__ << ": Failed to flush writer: "
+ << flush_exception.value;
return flush_exception;
}
}
@@ -216,7 +240,8 @@ void BaseEndpointChannel::CloseIo() {
// IO and Read() will proceed normally (with Exception::kIo).
Exception exception = reader_->Close();
if (!exception.Ok()) {
- // Add logging.
+ NEARBY_LOGS(WARNING) << __func__
+ << ": Exception closing reader: " << exception.value;
}
}
{
@@ -225,13 +250,16 @@ void BaseEndpointChannel::CloseIo() {
// IO and Write() will proceed normally (with Exception::kIo).
Exception exception = writer_->Close();
if (!exception.Ok()) {
- // Add logging.
+ NEARBY_LOGS(WARNING) << __func__
+ << ": Exception closing writer: " << exception.value;
}
}
}
void BaseEndpointChannel::Close(
proto::connections::DisconnectionReason reason) {
+ NEARBY_LOGS(INFO) << __func__
+ << ": Closing endpoint channel, reason: " << reason;
Close();
}
@@ -306,6 +334,8 @@ void BaseEndpointChannel::BlockUntilUnpaused() {
while (is_paused_) {
Exception wait_succeeded = is_paused_cond_.Wait();
if (!wait_succeeded.Ok()) {
+ NEARBY_LOGS(WARNING) << __func__ << ": Failure waiting to unpause: "
+ << wait_succeeded.value;
return;
}
}
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/base_endpoint_channel.h b/chromium/third_party/nearby/src/cpp/core/internal/base_endpoint_channel.h
index 5b64170c6ed..89688a5d9f9 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/base_endpoint_channel.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/base_endpoint_channel.h
@@ -27,7 +27,6 @@
#include "platform/public/condition_variable.h"
#include "platform/public/mutex.h"
#include "platform/public/system_clock.h"
-#include "proto/connections_enums.pb.h"
#include "securegcm/d2d_connection_context_v1.h"
#include "absl/base/thread_annotations.h"
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/base_endpoint_channel_test.cc b/chromium/third_party/nearby/src/cpp/core/internal/base_endpoint_channel_test.cc
index 80668a4414d..3a667c333b6 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/base_endpoint_channel_test.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/base_endpoint_channel_test.cc
@@ -17,7 +17,9 @@
#include <utility>
#include "core/internal/encryption_runner.h"
+#include "core/internal/offline_frames.h"
#include "platform/base/byte_array.h"
+#include "platform/base/exception.h"
#include "platform/base/input_stream.h"
#include "platform/base/output_stream.h"
#include "platform/public/count_down_latch.h"
@@ -26,7 +28,6 @@
#include "platform/public/pipe.h"
#include "platform/public/single_thread_executor.h"
#include "proto/connections_enums.pb.h"
-#include "proto/connections_enums.pb.h"
#include "securegcm/d2d_connection_context_v1.h"
#include "securegcm/ukey2_handshake.h"
#include "gmock/gmock.h"
@@ -354,6 +355,51 @@ TEST(BaseEndpointChannelTest, ReadAfterInputStreamClosed) {
ASSERT_TRUE(read_data.GetException().Raised(Exception::kIo));
}
+TEST(BaseEndpointChannelTest, ReadUnencryptedFrameOnEncryptedChannel) {
+ // Setup test communication environment.
+ Pipe pipe_a; // channel_a writes to pipe_a, reads from pipe_b.
+ Pipe pipe_b; // channel_b writes to pipe_b, reads from pipe_a.
+ TestEndpointChannel channel_a(&pipe_b.GetInputStream(),
+ &pipe_a.GetOutputStream());
+ TestEndpointChannel channel_b(&pipe_a.GetInputStream(),
+ &pipe_b.GetOutputStream());
+
+ ON_CALL(channel_a, GetMedium).WillByDefault([]() {
+ return Medium::BLUETOOTH;
+ });
+ ON_CALL(channel_b, GetMedium).WillByDefault([]() {
+ return Medium::BLUETOOTH;
+ });
+
+ // Run DH key exchange; setup encryption contexts for channels. But only
+ // encrypt |channel_b|.
+ auto [context_a, context_b] = DoDhKeyExchange(&channel_a, &channel_b);
+ ASSERT_NE(context_a, nullptr);
+ ASSERT_NE(context_b, nullptr);
+ channel_b.EnableEncryption(context_b);
+
+ EXPECT_EQ(channel_a.GetType(), "BLUETOOTH");
+ EXPECT_EQ(channel_b.GetType(), "ENCRYPTED_BLUETOOTH");
+
+ // An unencrypted KeepAlive should succeed.
+ ByteArray keep_alive_message = parser::ForKeepAlive();
+ channel_a.Write(keep_alive_message);
+ ExceptionOr<ByteArray> result = channel_b.Read();
+ EXPECT_TRUE(result.ok());
+ EXPECT_EQ(result.result(), keep_alive_message);
+
+ // An unencrypted data frame should fail.
+ ByteArray tx_message{"data message"};
+ channel_a.Write(tx_message);
+ result = channel_b.Read();
+ EXPECT_FALSE(result.ok());
+ EXPECT_EQ(result.exception(), Exception::kInvalidProtocolBuffer);
+
+ // Shutdown test environment.
+ channel_a.Close(DisconnectionReason::LOCAL_DISCONNECTION);
+ channel_b.Close(DisconnectionReason::REMOTE_DISCONNECTION);
+}
+
} // namespace
} // namespace connections
} // namespace nearby
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/base_pcp_handler.cc b/chromium/third_party/nearby/src/cpp/core/internal/base_pcp_handler.cc
index c41176a36af..720dc51eba3 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/base_pcp_handler.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/base_pcp_handler.cc
@@ -82,47 +82,50 @@ Status BasePcpHandler::StartAdvertising(ClientProxy* client,
NEARBY_LOG(INFO, "StartAdvertising with supported mediums: %s",
GetStringValueOfSupportedMediums(options).c_str());
ConnectionOptions advertising_options = options.CompatibleOptions();
- RunOnPcpHandlerThread([this, client, &service_id, &info, &advertising_options,
- &response]() RUN_ON_PCP_HANDLER_THREAD() {
- // The endpoint id inside of the advertisement is different to high
- // visibility and low visibility mode. In order to decide if client should
- // grab the high visibility or low visibility id, it needs to tell client
- // which one right now, before client#StartedAdvertising.
- if (ShouldEnterHighVisibilityMode(advertising_options)) {
- client->EnterHighVisibilityMode();
- }
-
- auto result =
- StartAdvertisingImpl(client, service_id, client->GetLocalEndpointId(),
- info.endpoint_info, advertising_options);
- if (!result.status.Ok()) {
- client->ExitHighVisibilityMode();
- response.Set(result.status);
- return;
- }
-
- // Now that we've succeeded, mark the client as advertising.
- // Save the advertising options for local reference in later process like
- // upgrading bandwidth.
- std::vector<proto::connections::Medium> supported_mediums =
- advertising_options.GetMediums();
- advertising_listener_ = info.listener;
- client->StartedAdvertising(service_id, GetStrategy(), info.listener,
- absl::MakeSpan(result.mediums),
- advertising_options);
- response.Set({Status::kSuccess});
- });
+ RunOnPcpHandlerThread(
+ "start-advertising",
+ [this, client, &service_id, &info, &advertising_options, &response]()
+ RUN_ON_PCP_HANDLER_THREAD() {
+ // The endpoint id inside of the advertisement is different to high
+ // visibility and low visibility mode. In order to decide if client
+ // should grab the high visibility or low visibility id, it needs to
+ // tell client which one right now, before
+ // client#StartedAdvertising.
+ if (ShouldEnterHighVisibilityMode(advertising_options)) {
+ client->EnterHighVisibilityMode();
+ }
+
+ auto result = StartAdvertisingImpl(
+ client, service_id, client->GetLocalEndpointId(),
+ info.endpoint_info, advertising_options);
+ if (!result.status.Ok()) {
+ client->ExitHighVisibilityMode();
+ response.Set(result.status);
+ return;
+ }
+
+ // Now that we've succeeded, mark the client as advertising.
+ // Save the advertising options for local reference in later process
+ // like upgrading bandwidth.
+ advertising_listener_ = info.listener;
+ client->StartedAdvertising(service_id, GetStrategy(), info.listener,
+ absl::MakeSpan(result.mediums),
+ advertising_options);
+ response.Set({Status::kSuccess});
+ });
return WaitForResult(absl::StrCat("StartAdvertising(", service_id, ")"),
client->GetClientId(), &response);
}
void BasePcpHandler::StopAdvertising(ClientProxy* client) {
+ NEARBY_LOGS(INFO) << "StopAdvertising id=" << client->GetLocalEndpointId();
CountDownLatch latch(1);
- RunOnPcpHandlerThread([this, client, &latch]() RUN_ON_PCP_HANDLER_THREAD() {
- StopAdvertisingImpl(client);
- client->StoppedAdvertising();
- latch.CountDown();
- });
+ RunOnPcpHandlerThread("stop-advertising",
+ [this, client, &latch]() RUN_ON_PCP_HANDLER_THREAD() {
+ StopAdvertisingImpl(client);
+ client->StoppedAdvertising();
+ latch.CountDown();
+ });
WaitForLatch("StopAdvertising", &latch);
}
@@ -143,6 +146,43 @@ bool BasePcpHandler::ShouldEnterHighVisibilityMode(
return !options.low_power && options.allowed.bluetooth;
}
+BooleanMediumSelector BasePcpHandler::ComputeIntersectionOfSupportedMediums(
+ const PendingConnectionInfo& connection_info) {
+ absl::flat_hash_set<Medium> intersection;
+ auto their_mediums = connection_info.supported_mediums;
+
+ // If no supported mediums were set, use the default upgrade medium.
+ if (their_mediums.empty()) {
+ their_mediums.push_back(GetDefaultUpgradeMedium());
+ }
+
+ for (Medium my_medium : GetConnectionMediumsByPriority()) {
+ if (std::find(their_mediums.begin(), their_mediums.end(), my_medium) !=
+ their_mediums.end()) {
+ // We use advertising options as a proxy to whether or not the local
+ // client does want to enable a WebRTC upgrade.
+ if (my_medium == location::nearby::proto::connections::Medium::WEB_RTC) {
+ ConnectionOptions advertising_options =
+ connection_info.client->GetAdvertisingOptions();
+
+ if (!advertising_options.enable_webrtc_listening &&
+ !advertising_options.allowed.web_rtc) {
+ // The local client does not allow WebRTC for listening or upgrades,
+ // ignore.
+ continue;
+ }
+ }
+
+ intersection.emplace(my_medium);
+ }
+ }
+
+ return {.bluetooth = intersection.contains(Medium::BLUETOOTH),
+ .ble = intersection.contains(Medium::BLE),
+ .web_rtc = intersection.contains(Medium::WEB_RTC),
+ .wifi_lan = intersection.contains(Medium::WIFI_LAN)};
+}
+
Status BasePcpHandler::StartDiscovery(ClientProxy* client,
const std::string& service_id,
const ConnectionOptions& options,
@@ -152,33 +192,36 @@ Status BasePcpHandler::StartDiscovery(ClientProxy* client,
NEARBY_LOG(INFO, "StartDiscovery with supported mediums: %s",
GetStringValueOfSupportedMediums(options).c_str());
- RunOnPcpHandlerThread([this, client, service_id, discovery_options, &listener,
- &response]() RUN_ON_PCP_HANDLER_THREAD() {
- // Ask the implementation to attempt to start discovery.
- auto result = StartDiscoveryImpl(client, service_id, discovery_options);
- if (!result.status.Ok()) {
- response.Set(result.status);
- return;
- }
+ RunOnPcpHandlerThread(
+ "start-discovery", [this, client, service_id, discovery_options,
+ &listener, &response]() RUN_ON_PCP_HANDLER_THREAD() {
+ // Ask the implementation to attempt to start discovery.
+ auto result = StartDiscoveryImpl(client, service_id, discovery_options);
+ if (!result.status.Ok()) {
+ response.Set(result.status);
+ return;
+ }
- // Now that we've succeeded, mark the client as discovering and clear
- // out any old endpoints we had discovered.
- discovered_endpoints_.clear();
- client->StartedDiscovery(service_id, GetStrategy(), listener,
- absl::MakeSpan(result.mediums), discovery_options);
- response.Set({Status::kSuccess});
- });
+ // Now that we've succeeded, mark the client as discovering and clear
+ // out any old endpoints we had discovered.
+ discovered_endpoints_.clear();
+ client->StartedDiscovery(service_id, GetStrategy(), listener,
+ absl::MakeSpan(result.mediums),
+ discovery_options);
+ response.Set({Status::kSuccess});
+ });
return WaitForResult(absl::StrCat("StartDiscovery(", service_id, ")"),
client->GetClientId(), &response);
}
void BasePcpHandler::StopDiscovery(ClientProxy* client) {
CountDownLatch latch(1);
- RunOnPcpHandlerThread([this, client, &latch]() RUN_ON_PCP_HANDLER_THREAD() {
- StopDiscoveryImpl(client);
- client->StoppedDiscovery();
- latch.CountDown();
- });
+ RunOnPcpHandlerThread("stop-discovery",
+ [this, client, &latch]() RUN_ON_PCP_HANDLER_THREAD() {
+ StopDiscoveryImpl(client);
+ client->StoppedDiscovery();
+ latch.CountDown();
+ });
WaitForLatch("StopDiscovery", &latch);
}
@@ -187,7 +230,8 @@ void BasePcpHandler::InjectEndpoint(
ClientProxy* client, const std::string& service_id,
const OutOfBandConnectionMetadata& metadata) {
CountDownLatch latch(1);
- RunOnPcpHandlerThread([this, client, service_id, metadata, &latch]()
+ RunOnPcpHandlerThread("inject-endpoint",
+ [this, client, service_id, metadata, &latch]()
RUN_ON_PCP_HANDLER_THREAD() {
InjectEndpointImpl(client, service_id, metadata);
latch.CountDown();
@@ -225,8 +269,9 @@ Status BasePcpHandler::WaitForResult(const std::string& method_name,
return result.result();
}
-void BasePcpHandler::RunOnPcpHandlerThread(Runnable runnable) {
- serial_executor_.Execute(std::move(runnable));
+void BasePcpHandler::RunOnPcpHandlerThread(const std::string& name,
+ Runnable runnable) {
+ serial_executor_.Execute(name, std::move(runnable));
}
EncryptionRunner::ResultListener BasePcpHandler::GetResultListener() {
@@ -237,6 +282,7 @@ EncryptionRunner::ResultListener BasePcpHandler::GetResultListener() {
const std::string& auth_token,
const ByteArray& raw_auth_token) {
RunOnPcpHandlerThread(
+ "encryption-success",
[this, endpoint_id, raw_ukey2 = ukey2.release(), auth_token,
raw_auth_token]() RUN_ON_PCP_HANDLER_THREAD() mutable {
OnEncryptionSuccessRunnable(
@@ -246,12 +292,13 @@ EncryptionRunner::ResultListener BasePcpHandler::GetResultListener() {
},
.on_failure_cb =
[this](const std::string& endpoint_id, EndpointChannel* channel) {
- RunOnPcpHandlerThread([this, endpoint_id,
- channel]() RUN_ON_PCP_HANDLER_THREAD() {
- NEARBY_LOG(ERROR, "Encryption failed for %s on medium %d",
- endpoint_id.c_str(), channel->GetMedium());
- OnEncryptionFailureRunnable(endpoint_id, channel);
- });
+ RunOnPcpHandlerThread(
+ "encryption-failure",
+ [this, endpoint_id, channel]() RUN_ON_PCP_HANDLER_THREAD() {
+ NEARBY_LOG(ERROR, "Encryption failed for %s on medium %d",
+ endpoint_id.c_str(), channel->GetMedium());
+ OnEncryptionFailureRunnable(endpoint_id, channel);
+ });
},
};
}
@@ -296,8 +343,30 @@ void BasePcpHandler::OnEncryptionSuccessRunnable(
.raw_authentication_token = raw_auth_token,
.is_incoming_connection = connection_info.is_incoming,
},
- connection_info.options, std::move(connection_info.channel),
- connection_info.listener);
+ {
+ .strategy = connection_info.options.strategy,
+ .allowed = ComputeIntersectionOfSupportedMediums(connection_info),
+ .auto_upgrade_bandwidth =
+ connection_info.options.auto_upgrade_bandwidth,
+ .enforce_topology_constraints =
+ connection_info.options.enforce_topology_constraints,
+ .low_power = connection_info.options.low_power,
+ .enable_bluetooth_listening =
+ connection_info.options.enable_bluetooth_listening,
+ .enable_webrtc_listening =
+ connection_info.options.enable_webrtc_listening,
+ .is_out_of_band_connection =
+ connection_info.options.is_out_of_band_connection,
+ .remote_bluetooth_mac_address =
+ connection_info.options.remote_bluetooth_mac_address,
+ .fast_advertisement_service_uuid =
+ connection_info.options.fast_advertisement_service_uuid,
+ .keep_alive_interval_millis =
+ connection_info.options.keep_alive_interval_millis,
+ .keep_alive_timeout_millis =
+ connection_info.options.keep_alive_timeout_millis,
+ },
+ std::move(connection_info.channel), connection_info.listener);
if (auto future_status = connection_info.result.lock()) {
NEARBY_LOG(INFO, "Connection established; Finalising future OK");
@@ -341,119 +410,128 @@ Status BasePcpHandler::RequestConnection(ClientProxy* client,
const ConnectionRequestInfo& info,
const ConnectionOptions& options) {
auto result = std::make_shared<Future<Status>>();
- RunOnPcpHandlerThread([this, client, &info, options, endpoint_id,
- result]() RUN_ON_PCP_HANDLER_THREAD() {
- absl::Time start_time = SystemClock::ElapsedRealtime();
-
- // If we already have a pending connection, then we shouldn't allow any more
- // outgoing connections to this endpoint.
- if (pending_connections_.count(endpoint_id)) {
- NEARBY_LOG(INFO, "Connection already exists: id=%s", endpoint_id.c_str());
- result->Set({Status::kAlreadyConnectedToEndpoint});
- return;
- }
-
- // If our child class says we can't send any more outgoing connections,
- // listen to them.
- if (ShouldEnforceTopologyConstraints(client->GetAdvertisingOptions()) &&
- !CanSendOutgoingConnection(client)) {
- NEARBY_LOG(INFO, "Outgoing connection not allowed: id=%s",
- endpoint_id.c_str());
- result->Set({Status::kOutOfOrderApiCall});
- return;
- }
-
- DiscoveredEndpoint* endpoint = GetDiscoveredEndpoint(endpoint_id);
- if (endpoint == nullptr) {
- NEARBY_LOG(INFO, "Discovered endpoint not found: id=%s",
- endpoint_id.c_str());
- result->Set({Status::kEndpointUnknown});
- return;
- }
+ RunOnPcpHandlerThread(
+ "request-connection", [this, client, &info, options, endpoint_id,
+ result]() RUN_ON_PCP_HANDLER_THREAD() {
+ absl::Time start_time = SystemClock::ElapsedRealtime();
+
+ // If we already have a pending connection, then we shouldn't allow any
+ // more outgoing connections to this endpoint.
+ if (pending_connections_.count(endpoint_id)) {
+ NEARBY_LOG(INFO, "Connection already exists: id=%s",
+ endpoint_id.c_str());
+ result->Set({Status::kAlreadyConnectedToEndpoint});
+ return;
+ }
- auto remote_bluetooth_mac_address =
- BluetoothUtils::ToString(options.remote_bluetooth_mac_address);
- if (!remote_bluetooth_mac_address.empty()) {
- if (AppendRemoteBluetoothMacAddressEndpoint(
- endpoint_id, remote_bluetooth_mac_address,
- client->GetDiscoveryOptions()))
- NEARBY_LOGS(INFO) << "Appended remote Bluetooth MAC Address endpoint "
- << "[" << remote_bluetooth_mac_address << "]";
- }
+ // If our child class says we can't send any more outgoing connections,
+ // listen to them.
+ if (ShouldEnforceTopologyConstraints(client->GetAdvertisingOptions()) &&
+ !CanSendOutgoingConnection(client)) {
+ NEARBY_LOG(INFO, "Outgoing connection not allowed: id=%s",
+ endpoint_id.c_str());
+ result->Set({Status::kOutOfOrderApiCall});
+ return;
+ }
- if (AppendWebRTCEndpoint(endpoint_id, client->GetDiscoveryOptions()))
- NEARBY_LOGS(INFO) << "Appended Web RTC endpoint.";
+ DiscoveredEndpoint* endpoint = GetDiscoveredEndpoint(endpoint_id);
+ if (endpoint == nullptr) {
+ NEARBY_LOG(INFO, "Discovered endpoint not found: id=%s",
+ endpoint_id.c_str());
+ result->Set({Status::kEndpointUnknown});
+ return;
+ }
- auto discovered_endpoints = GetDiscoveredEndpoints(endpoint_id);
- std::unique_ptr<EndpointChannel> channel;
- ConnectImplResult connect_impl_result;
+ auto remote_bluetooth_mac_address =
+ BluetoothUtils::ToString(options.remote_bluetooth_mac_address);
+ if (!remote_bluetooth_mac_address.empty()) {
+ if (AppendRemoteBluetoothMacAddressEndpoint(
+ endpoint_id, remote_bluetooth_mac_address,
+ client->GetDiscoveryOptions()))
+ NEARBY_LOGS(INFO)
+ << "Appended remote Bluetooth MAC Address endpoint "
+ << "[" << remote_bluetooth_mac_address << "]";
+ }
- for (auto connect_endpoint : discovered_endpoints) {
- if (!MediumSupportedByClientOptions(connect_endpoint->medium, options))
- continue;
- connect_impl_result = ConnectImpl(client, connect_endpoint);
- if (connect_impl_result.status.Ok()) {
- channel = std::move(connect_impl_result.endpoint_channel);
- break;
- }
- }
+ if (AppendWebRTCEndpoint(endpoint_id, client->GetDiscoveryOptions()))
+ NEARBY_LOGS(INFO) << "Appended Web RTC endpoint.";
+
+ auto discovered_endpoints = GetDiscoveredEndpoints(endpoint_id);
+ std::unique_ptr<EndpointChannel> channel;
+ ConnectImplResult connect_impl_result;
+
+ for (auto connect_endpoint : discovered_endpoints) {
+ if (!MediumSupportedByClientOptions(connect_endpoint->medium,
+ options))
+ continue;
+ connect_impl_result = ConnectImpl(client, connect_endpoint);
+ if (connect_impl_result.status.Ok()) {
+ channel = std::move(connect_impl_result.endpoint_channel);
+ break;
+ }
+ }
- if (channel == nullptr) {
- NEARBY_LOG(INFO, "Endpoint channel not available: id=%s",
- endpoint_id.c_str());
- ProcessPreConnectionInitiationFailure(
- endpoint_id, channel.get(), connect_impl_result.status, result.get());
- return;
- }
+ if (channel == nullptr) {
+ NEARBY_LOG(INFO, "Endpoint channel not available: id=%s",
+ endpoint_id.c_str());
+ ProcessPreConnectionInitiationFailure(endpoint_id, channel.get(),
+ connect_impl_result.status,
+ result.get());
+ return;
+ }
- NEARBY_LOG(INFO, "Sending connection request: id=%s", endpoint_id.c_str());
- // Generate the nonce to use for this connection.
- std::int32_t nonce = prng_.NextInt32();
-
- // The first message we have to send, after connecting, is to tell the
- // endpoint about ourselves.
- Exception write_exception = WriteConnectionRequestFrame(
- channel.get(), client->GetLocalEndpointId(), info.endpoint_info, nonce,
- GetSupportedConnectionMediumsByPriority(options));
- if (!write_exception.Ok()) {
- NEARBY_LOG(INFO, "Failed to send connection request: id=%s",
- endpoint_id.c_str());
- ProcessPreConnectionInitiationFailure(
- endpoint_id, channel.get(), {Status::kEndpointIoError}, result.get());
- return;
- }
+ NEARBY_LOG(INFO, "Sending connection request: id=%s",
+ endpoint_id.c_str());
+ // Generate the nonce to use for this connection.
+ std::int32_t nonce = prng_.NextInt32();
+
+ // The first message we have to send, after connecting, is to tell the
+ // endpoint about ourselves.
+ Exception write_exception = WriteConnectionRequestFrame(
+ channel.get(), client->GetLocalEndpointId(), info.endpoint_info,
+ nonce, GetSupportedConnectionMediumsByPriority(options),
+ options.keep_alive_interval_millis,
+ options.keep_alive_timeout_millis);
+ if (!write_exception.Ok()) {
+ NEARBY_LOG(INFO, "Failed to send connection request: id=%s",
+ endpoint_id.c_str());
+ ProcessPreConnectionInitiationFailure(endpoint_id, channel.get(),
+ {Status::kEndpointIoError},
+ result.get());
+ return;
+ }
- NEARBY_LOG(INFO, "adding connection to pending set: id=%s",
- endpoint_id.c_str());
+ NEARBY_LOG(INFO, "adding connection to pending set: id=%s",
+ endpoint_id.c_str());
- // We've successfully connected to the device, and are now about to jump on
- // to the EncryptionRunner thread to start running our encryption protocol.
- // We'll mark ourselves as pending in case we get another call to
- // RequestConnection or OnIncomingConnection, so that we can cancel the
- // connection if needed.
- EndpointChannel* endpoint_channel =
- pending_connections_
- .emplace(endpoint_id,
- PendingConnectionInfo{
- .client = client,
- .remote_endpoint_info = endpoint->endpoint_info,
- .nonce = nonce,
- .is_incoming = false,
- .start_time = start_time,
- .listener = info.listener,
- .options = options,
- .result = result,
- .channel = std::move(channel),
- })
- .first->second.channel.get();
-
- NEARBY_LOG(INFO, "Initiating secure connection: id=%s",
- endpoint_id.c_str());
- // Next, we'll set up encryption. When it's done, our future will return and
- // RequestConnection() will finish.
- encryption_runner_.StartClient(client, endpoint_id, endpoint_channel,
- GetResultListener());
- });
+ // We've successfully connected to the device, and are now about to jump
+ // on to the EncryptionRunner thread to start running our encryption
+ // protocol. We'll mark ourselves as pending in case we get another call
+ // to RequestConnection or OnIncomingConnection, so that we can cancel
+ // the connection if needed.
+ EndpointChannel* endpoint_channel =
+ pending_connections_
+ .emplace(endpoint_id,
+ PendingConnectionInfo{
+ .client = client,
+ .remote_endpoint_info = endpoint->endpoint_info,
+ .nonce = nonce,
+ .is_incoming = false,
+ .start_time = start_time,
+ .listener = info.listener,
+ .options = options,
+ .result = result,
+ .channel = std::move(channel),
+ })
+ .first->second.channel.get();
+
+ NEARBY_LOG(INFO, "Initiating secure connection: id=%s",
+ endpoint_id.c_str());
+ // Next, we'll set up encryption. When it's done, our future will return
+ // and RequestConnection() will finish.
+ encryption_runner_.StartClient(client, endpoint_id, endpoint_channel,
+ GetResultListener());
+ });
NEARBY_LOG(INFO, "Waiting for connection to complete: id=%s",
endpoint_id.c_str());
auto status =
@@ -562,11 +640,13 @@ bool BasePcpHandler::CanReceiveIncomingConnection(ClientProxy* client) const {
Exception BasePcpHandler::WriteConnectionRequestFrame(
EndpointChannel* endpoint_channel, const std::string& local_endpoint_id,
const ByteArray& local_endpoint_info, std::int32_t nonce,
- const std::vector<proto::connections::Medium>& supported_mediums) {
- // TODO(b/172178926): Add WifiLan 5GHz and BSSID support.
+ const std::vector<proto::connections::Medium>& supported_mediums,
+ std::int32_t keep_alive_interval_millis,
+ std::int32_t keep_alive_timeout_millis) {
return endpoint_channel->Write(parser::ForConnectionRequest(
local_endpoint_id, local_endpoint_info, nonce, /*supports_5_ghz =*/false,
- /*bssid=*/std::string{}, supported_mediums));
+ /*bssid=*/std::string{}, supported_mediums, keep_alive_interval_millis,
+ keep_alive_timeout_millis));
}
void BasePcpHandler::ProcessPreConnectionInitiationFailure(
@@ -619,8 +699,8 @@ Status BasePcpHandler::AcceptConnection(
const PayloadListener& payload_listener) {
Future<Status> response;
RunOnPcpHandlerThread(
- [this, client, endpoint_id, payload_listener,
- &response]() RUN_ON_PCP_HANDLER_THREAD() {
+ "accept-connection", [this, client, endpoint_id, payload_listener,
+ &response]() RUN_ON_PCP_HANDLER_THREAD() {
NEARBY_LOG(INFO, "AcceptConnection: id=%s", endpoint_id.c_str());
if (!pending_connections_.count(endpoint_id)) {
NEARBY_LOG(INFO, "AcceptConnection: no pending connection for id=%s",
@@ -673,51 +753,52 @@ Status BasePcpHandler::AcceptConnection(
Status BasePcpHandler::RejectConnection(ClientProxy* client,
const std::string& endpoint_id) {
Future<Status> response;
- RunOnPcpHandlerThread([this, client, endpoint_id,
- &response]() RUN_ON_PCP_HANDLER_THREAD() {
- NEARBY_LOG(INFO, "RejectConnection: id=%s", endpoint_id.c_str());
- if (!pending_connections_.count(endpoint_id)) {
- NEARBY_LOG(INFO, "RejectConnection: no pending connection for id=%s",
- endpoint_id.c_str());
- response.Set({Status::kEndpointUnknown});
- return;
- }
- auto& connection_info = pending_connections_[endpoint_id];
-
- // By this point in the flow, connection_info->endpoint_channel_ has been
- // nulled out because ownership of that EndpointChannel was passed on to
- // EndpointChannelManager via a call to
- // EndpointManager::registerEndpoint(), so we now need to get access to the
- // EndpointChannel from the authoritative owner.
- std::shared_ptr<EndpointChannel> channel =
- channel_manager_->GetChannelForEndpoint(endpoint_id);
- if (channel == nullptr) {
- NEARBY_LOG(
- ERROR,
- "Channel destroyed before Reject; bring down connection: id=%s",
- endpoint_id.c_str());
- ProcessPreConnectionResultFailure(client, endpoint_id);
- response.Set({Status::kEndpointUnknown});
- return;
- }
+ RunOnPcpHandlerThread(
+ "reject-connection",
+ [this, client, endpoint_id, &response]() RUN_ON_PCP_HANDLER_THREAD() {
+ NEARBY_LOG(INFO, "RejectConnection: id=%s", endpoint_id.c_str());
+ if (!pending_connections_.count(endpoint_id)) {
+ NEARBY_LOG(INFO, "RejectConnection: no pending connection for id=%s",
+ endpoint_id.c_str());
+ response.Set({Status::kEndpointUnknown});
+ return;
+ }
+ auto& connection_info = pending_connections_[endpoint_id];
- Exception write_exception = channel->Write(
- parser::ForConnectionResponse(Status::kConnectionRejected));
- if (!write_exception.Ok()) {
- NEARBY_LOG(INFO, "RejectConnection: failed to send response: id=%s",
- endpoint_id.c_str());
- ProcessPreConnectionResultFailure(client, endpoint_id);
- response.Set({Status::kEndpointIoError});
- return;
- }
+ // By this point in the flow, connection_info->endpoint_channel_ has
+ // been nulled out because ownership of that EndpointChannel was passed
+ // on to EndpointChannelManager via a call to
+ // EndpointManager::registerEndpoint(), so we now need to get access to
+ // the EndpointChannel from the authoritative owner.
+ std::shared_ptr<EndpointChannel> channel =
+ channel_manager_->GetChannelForEndpoint(endpoint_id);
+ if (channel == nullptr) {
+ NEARBY_LOG(
+ ERROR,
+ "Channel destroyed before Reject; bring down connection: id=%s",
+ endpoint_id.c_str());
+ ProcessPreConnectionResultFailure(client, endpoint_id);
+ response.Set({Status::kEndpointUnknown});
+ return;
+ }
- NEARBY_LOG(INFO, "RejectConnection: rejecting locally: id=%s",
- endpoint_id.c_str());
- connection_info.LocalEndpointRejectedConnection(endpoint_id);
- EvaluateConnectionResult(client, endpoint_id,
- false /* can_close_immediately */);
- response.Set({Status::kSuccess});
- });
+ Exception write_exception = channel->Write(
+ parser::ForConnectionResponse(Status::kConnectionRejected));
+ if (!write_exception.Ok()) {
+ NEARBY_LOG(INFO, "RejectConnection: failed to send response: id=%s",
+ endpoint_id.c_str());
+ ProcessPreConnectionResultFailure(client, endpoint_id);
+ response.Set({Status::kEndpointIoError});
+ return;
+ }
+
+ NEARBY_LOG(INFO, "RejectConnection: rejecting locally: id=%s",
+ endpoint_id.c_str());
+ connection_info.LocalEndpointRejectedConnection(endpoint_id);
+ EvaluateConnectionResult(client, endpoint_id,
+ false /* can_close_immediately */);
+ response.Set({Status::kSuccess});
+ });
return WaitForResult(absl::StrCat("RejectConnection(", endpoint_id, ")"),
client->GetClientId(), &response);
@@ -728,45 +809,46 @@ void BasePcpHandler::OnIncomingFrame(OfflineFrame& frame,
ClientProxy* client,
proto::connections::Medium medium) {
CountDownLatch latch(1);
- RunOnPcpHandlerThread([this, client, endpoint_id, frame,
- &latch]() RUN_ON_PCP_HANDLER_THREAD() {
- NEARBY_LOG(INFO, "OnConnectionResponse: id=%s", endpoint_id.c_str());
-
- if (client->HasRemoteEndpointResponded(endpoint_id)) {
- NEARBY_LOG(INFO, "OnConnectionResponse: already handled; id=%s",
- endpoint_id.c_str());
- return;
- }
+ RunOnPcpHandlerThread(
+ "incoming-frame",
+ [this, client, endpoint_id, frame, &latch]() RUN_ON_PCP_HANDLER_THREAD() {
+ NEARBY_LOG(INFO, "OnConnectionResponse: id=%s", endpoint_id.c_str());
- const ConnectionResponseFrame& connection_response =
- frame.v1().connection_response();
+ if (client->HasRemoteEndpointResponded(endpoint_id)) {
+ NEARBY_LOG(INFO, "OnConnectionResponse: already handled; id=%s",
+ endpoint_id.c_str());
+ return;
+ }
- // For backward compatible, here still check both status and
- // response parameters until the response feature is roll out in all
- // supported devices.
- bool accepted = false;
- if (connection_response.has_response()) {
- accepted =
- connection_response.response() == ConnectionResponseFrame::ACCEPT;
- } else {
- accepted = connection_response.status() == Status::kSuccess;
- }
- if (accepted) {
- NEARBY_LOG(INFO, "OnConnectionResponse: remote accepted; id=%s",
- endpoint_id.c_str());
- client->RemoteEndpointAcceptedConnection(endpoint_id);
- } else {
- NEARBY_LOG(INFO,
- "OnConnectionResponse: remote rejected; id=%s; status=%d",
- endpoint_id.c_str(), connection_response.status());
- client->RemoteEndpointRejectedConnection(endpoint_id);
- }
+ const ConnectionResponseFrame& connection_response =
+ frame.v1().connection_response();
+
+ // For backward compatible, here still check both status and
+ // response parameters until the response feature is roll out in all
+ // supported devices.
+ bool accepted = false;
+ if (connection_response.has_response()) {
+ accepted =
+ connection_response.response() == ConnectionResponseFrame::ACCEPT;
+ } else {
+ accepted = connection_response.status() == Status::kSuccess;
+ }
+ if (accepted) {
+ NEARBY_LOG(INFO, "OnConnectionResponse: remote accepted; id=%s",
+ endpoint_id.c_str());
+ client->RemoteEndpointAcceptedConnection(endpoint_id);
+ } else {
+ NEARBY_LOG(INFO,
+ "OnConnectionResponse: remote rejected; id=%s; status=%d",
+ endpoint_id.c_str(), connection_response.status());
+ client->RemoteEndpointRejectedConnection(endpoint_id);
+ }
- EvaluateConnectionResult(client, endpoint_id,
- /* can_close_immediately= */ true);
+ EvaluateConnectionResult(client, endpoint_id,
+ /* can_close_immediately= */ true);
- latch.CountDown();
- });
+ latch.CountDown();
+ });
WaitForLatch("OnIncomingFrame()", &latch);
}
@@ -777,17 +859,19 @@ void BasePcpHandler::OnEndpointDisconnect(ClientProxy* client,
barrier.CountDown();
return;
}
- RunOnPcpHandlerThread([this, client, endpoint_id,
- barrier]() RUN_ON_PCP_HANDLER_THREAD() mutable {
- auto item = pending_alarms_.find(endpoint_id);
- if (item != pending_alarms_.end()) {
- auto& alarm = item->second;
- alarm.Cancel();
- pending_alarms_.erase(item);
- }
- ProcessPreConnectionResultFailure(client, endpoint_id);
- barrier.CountDown();
- });
+ RunOnPcpHandlerThread("on-endpoint-disconnect",
+ [this, client, endpoint_id, barrier]()
+ RUN_ON_PCP_HANDLER_THREAD() mutable {
+ auto item = pending_alarms_.find(endpoint_id);
+ if (item != pending_alarms_.end()) {
+ auto& alarm = item->second;
+ alarm.Cancel();
+ pending_alarms_.erase(item);
+ }
+ ProcessPreConnectionResultFailure(client,
+ endpoint_id);
+ barrier.CountDown();
+ });
}
BluetoothDevice BasePcpHandler::GetRemoteBluetoothDevice(
@@ -969,6 +1053,32 @@ Exception BasePcpHandler::OnIncomingConnection(
? connection_request.endpoint_info()
: connection_request.endpoint_name()};
+ // Retrieve the keep-alive frame interval and timeout fields. If the frame
+ // doesn't have those fields, we need to get them as default from feature
+ // flags to prevent 0-values causing thread ill.
+ ConnectionOptions options = {.keep_alive_interval_millis = 0,
+ .keep_alive_timeout_millis = 0};
+ if (connection_request.has_keep_alive_interval_millis() &&
+ connection_request.has_keep_alive_timeout_millis()) {
+ options.keep_alive_interval_millis =
+ connection_request.keep_alive_interval_millis();
+ options.keep_alive_timeout_millis =
+ connection_request.keep_alive_timeout_millis();
+ }
+ if (options.keep_alive_interval_millis == 0 ||
+ options.keep_alive_timeout_millis == 0 ||
+ options.keep_alive_interval_millis >= options.keep_alive_timeout_millis) {
+ NEARBY_LOG(WARNING,
+ "Incoming connection has wrong keep-alive frame interval=%d, "
+ "timeout=%d values; correct them as default.",
+ options.keep_alive_interval_millis,
+ options.keep_alive_timeout_millis);
+ options.keep_alive_interval_millis =
+ FeatureFlags::GetInstance().GetFlags().keep_alive_interval_millis;
+ options.keep_alive_timeout_millis =
+ FeatureFlags::GetInstance().GetFlags().keep_alive_timeout_millis;
+ }
+
// We've successfully connected to the device, and are now about to jump on to
// the EncryptionRunner thread to start running our encryption protocol. We'll
// mark ourselves as pending in case we get another call to RequestConnection
@@ -983,6 +1093,7 @@ Exception BasePcpHandler::OnIncomingConnection(
.is_incoming = true,
.start_time = start_time,
.listener = advertising_listener_,
+ .options = options,
.supported_mediums =
parser::ConnectionRequestMediumsToMediums(
connection_request),
@@ -1043,48 +1154,6 @@ void BasePcpHandler::ProcessTieBreakLoss(
ProcessPreConnectionResultFailure(client, endpoint_id);
}
-void BasePcpHandler::InitiateBandwidthUpgrade(
- ClientProxy* client, const std::string& endpoint_id,
- const std::vector<Medium>& their_supported_mediums) {
- // There was comments for re-using the same highest medium for upgrading. But
- // given that end users may change data options all the time, it makes more
- // sense to dynamically select the proper medium for upgrading.
- // TODO(hais): when we add more mediums like Wifi Hotspot, we need to prevent
- // upgrading interfering with active connections.
- Medium bwu_medium = ChooseBestUpgradeMedium(their_supported_mediums,
- client->GetAdvertisingOptions());
-
- if (AutoUpgradeBandwidth(client->GetAdvertisingOptions()) &&
- bwu_medium != Medium::UNKNOWN_MEDIUM) {
- bwu_manager_->InitiateBwuForEndpoint(client, endpoint_id, bwu_medium);
- }
-}
-
-proto::connections::Medium BasePcpHandler::ChooseBestUpgradeMedium(
- const std::vector<proto::connections::Medium>& their_supported_mediums,
- const ConnectionOptions& local_advertising_options) {
- // If the remote side did not report their supported mediums, choose an
- // appropriate default.
- std::vector<proto::connections::Medium> their_mediums =
- their_supported_mediums;
- if (their_supported_mediums.empty()) {
- their_mediums.push_back(GetDefaultUpgradeMedium());
- }
-
- // Otherwise, pick the best medium we support.
- std::vector<proto::connections::Medium> my_mediums =
- GetSupportedConnectionMediumsByPriority(local_advertising_options);
- for (const auto& my_medium : my_mediums) {
- for (const auto& their_medium : their_mediums) {
- if (my_medium == their_medium) {
- return my_medium;
- }
- }
- }
-
- return proto::connections::Medium::UNKNOWN_MEDIUM;
-}
-
bool BasePcpHandler::AppendRemoteBluetoothMacAddressEndpoint(
const std::string& endpoint_id,
const std::string& remote_bluetooth_mac_address,
@@ -1239,9 +1308,9 @@ void BasePcpHandler::EvaluateConnectionResult(ClientProxy* client,
}
// Kick off the bandwidth upgrade for incoming connections.
- if (connection_info.is_incoming) {
- InitiateBandwidthUpgrade(client, endpoint_id,
- connection_info.supported_mediums);
+ if (connection_info.is_incoming &&
+ AutoUpgradeBandwidth(client->GetAdvertisingOptions())) {
+ bwu_manager_->InitiateBwuForEndpoint(client, endpoint_id);
}
}
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/base_pcp_handler.h b/chromium/third_party/nearby/src/cpp/core/internal/base_pcp_handler.h
index 9508cc1c1fc..f54ad96e41b 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/base_pcp_handler.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/base_pcp_handler.h
@@ -32,7 +32,6 @@
#include "core/listeners.h"
#include "core/options.h"
#include "core/status.h"
-#include "proto/connections/offline_wire_formats.pb.h"
#include "platform/base/byte_array.h"
#include "platform/base/prng.h"
#include "platform/public/atomic_boolean.h"
@@ -43,7 +42,6 @@
#include "platform/public/scheduled_executor.h"
#include "platform/public/single_thread_executor.h"
#include "platform/public/system_clock.h"
-#include "proto/connections_enums.pb.h"
#include "securegcm/d2d_connection_context_v1.h"
#include "securegcm/ukey2_handshake.h"
#include "absl/container/btree_map.h"
@@ -223,7 +221,7 @@ class BasePcpHandler : public PcpHandler,
std::unique_ptr<EndpointChannel> endpoint_channel;
};
- void RunOnPcpHandlerThread(Runnable runnable);
+ void RunOnPcpHandlerThread(const std::string& name, Runnable runnable);
BluetoothDevice GetRemoteBluetoothDevice(
const std::string& remote_bluetooth_mac_address);
@@ -376,7 +374,9 @@ class BasePcpHandler : public PcpHandler,
static Exception WriteConnectionRequestFrame(
EndpointChannel* endpoint_channel, const std::string& local_endpoint_id,
const ByteArray& local_endpoint_info, std::int32_t nonce,
- const std::vector<proto::connections::Medium>& supported_mediums);
+ const std::vector<proto::connections::Medium>& supported_mediums,
+ std::int32_t keep_alive_interval_millis,
+ std::int32_t keep_alive_timeout_millis);
static constexpr absl::Duration kConnectionRequestReadTimeout =
absl::Seconds(2);
@@ -410,23 +410,6 @@ class BasePcpHandler : public PcpHandler,
void ProcessTieBreakLoss(ClientProxy* client, const std::string& endpoint_id,
PendingConnectionInfo* info);
- // Called when an incoming connection has been accepted by both sides.
- //
- // @param client_proxy The client
- // @param endpoint_id The id of the remote device
- // @param supported_mediums The mediums supported by the remote device.
- // Empty
- // for outgoing connections and older devices that don't report their
- // supported mediums.
- void InitiateBandwidthUpgrade(
- ClientProxy* client, const std::string& endpoint_id,
- const std::vector<proto::connections::Medium>& supported_mediums);
-
- // Returns the optimal medium supported by both devices.
- proto::connections::Medium ChooseBestUpgradeMedium(
- const std::vector<proto::connections::Medium>& supported_mediums,
- const ConnectionOptions& local_advertising_options);
-
// Returns true if the bluetooth endpoint based on remote bluetooth mac
// address is created and appended into discovered_endpoints_ with key
// endpoint_id.
@@ -481,6 +464,11 @@ class BasePcpHandler : public PcpHandler,
// Bluetooth classic" (1P).
bool ShouldEnterHighVisibilityMode(const ConnectionOptions& options);
+ // Returns the intersection of supported mediums based on the mediums reported
+ // by the remote client and the local client's advertising options.
+ BooleanMediumSelector ComputeIntersectionOfSupportedMediums(
+ const PendingConnectionInfo& connection_info);
+
ScheduledExecutor alarm_executor_;
SingleThreadExecutor serial_executor_;
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/base_pcp_handler_test.cc b/chromium/third_party/nearby/src/cpp/core/internal/base_pcp_handler_test.cc
index fd1ac0301db..1d60f47362e 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/base_pcp_handler_test.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/base_pcp_handler_test.cc
@@ -329,6 +329,10 @@ class BasePcpHandlerTest
ConnectionOptions options{
.remote_bluetooth_mac_address =
ByteArray{std::string("\x12\x34\x56\x78\x9a\xbc")},
+ .keep_alive_interval_millis =
+ FeatureFlags::GetInstance().GetFlags().keep_alive_interval_millis,
+ .keep_alive_timeout_millis =
+ FeatureFlags::GetInstance().GetFlags().keep_alive_timeout_millis,
};
EXPECT_CALL(mock_discovery_listener_.endpoint_found_cb, Call);
EXPECT_CALL(*pcp_handler, CanSendOutgoingConnection)
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/ble_endpoint_channel.h b/chromium/third_party/nearby/src/cpp/core/internal/ble_endpoint_channel.h
index 3d358903e6a..18c6954e4d9 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/ble_endpoint_channel.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/ble_endpoint_channel.h
@@ -17,7 +17,6 @@
#include "core/internal/base_endpoint_channel.h"
#include "platform/public/ble.h"
-#include "proto/connections_enums.pb.h"
namespace location {
namespace nearby {
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/bluetooth_bwu_handler.h b/chromium/third_party/nearby/src/cpp/core/internal/bluetooth_bwu_handler.h
index 172d9f56cd3..d39aa55df30 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/bluetooth_bwu_handler.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/bluetooth_bwu_handler.h
@@ -21,10 +21,8 @@
#include "core/internal/client_proxy.h"
#include "core/internal/mediums/mediums.h"
#include "core/internal/mediums/utils.h"
-#include "proto/connections/offline_wire_formats.pb.h"
#include "platform/public/bluetooth_classic.h"
#include "platform/public/count_down_latch.h"
-#include "proto/connections_enums.pb.h"
namespace location {
namespace nearby {
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/bluetooth_endpoint_channel.h b/chromium/third_party/nearby/src/cpp/core/internal/bluetooth_endpoint_channel.h
index 06b919579a5..f9059348056 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/bluetooth_endpoint_channel.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/bluetooth_endpoint_channel.h
@@ -19,7 +19,6 @@
#include "core/internal/base_endpoint_channel.h"
#include "platform/public/bluetooth_classic.h"
-#include "proto/connections_enums.pb.h"
namespace location {
namespace nearby {
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/bwu_handler.h b/chromium/third_party/nearby/src/cpp/core/internal/bwu_handler.h
index 1297c9b2419..c31fa731529 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/bwu_handler.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/bwu_handler.h
@@ -19,7 +19,6 @@
#include "core/internal/endpoint_channel.h"
#include "core/internal/offline_frames.h"
#include "platform/public/count_down_latch.h"
-#include "proto/connections_enums.pb.h"
namespace location {
namespace nearby {
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/bwu_manager.cc b/chromium/third_party/nearby/src/cpp/core/internal/bwu_manager.cc
index d9c5814415e..b5063b8526b 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/bwu_manager.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/bwu_manager.cc
@@ -131,7 +131,7 @@ void BwuManager::InitiateBwuForEndpoint(ClientProxy* client,
Medium new_medium) {
NEARBY_LOG(INFO, "InitiateBwuForEndpoint for endpoint %s with medium %d",
endpoint_id.c_str(), new_medium);
- RunOnBwuManagerThread([this, client, endpoint_id, new_medium]() {
+ RunOnBwuManagerThread("bwu-init", [this, client, endpoint_id, new_medium]() {
Medium proposed_medium = ChooseBestUpgradeMedium(
client->GetUpgradeMediums(endpoint_id).GetMediums(true));
if (new_medium != Medium::UNKNOWN_MEDIUM) {
@@ -207,12 +207,14 @@ void BwuManager::OnIncomingFrame(OfflineFrame& frame,
return;
auto bwu_frame = frame.v1().bandwidth_upgrade_negotiation();
if (FeatureFlags::GetInstance().GetFlags().enable_async_bandwidth_upgrade) {
- RunOnBwuManagerThread([this, client, endpoint_id, bwu_frame]() {
- OnBwuNegotiationFrame(client, bwu_frame, endpoint_id);
- });
+ RunOnBwuManagerThread(
+ "bwu-on-incoming-frame", [this, client, endpoint_id, bwu_frame]() {
+ OnBwuNegotiationFrame(client, bwu_frame, endpoint_id);
+ });
} else {
CountDownLatch latch(1);
- RunOnBwuManagerThread([this, client, endpoint_id, bwu_frame, &latch]() {
+ RunOnBwuManagerThread("bwu-on-incoming-frame", [this, client, endpoint_id,
+ bwu_frame, &latch]() {
OnBwuNegotiationFrame(client, bwu_frame, endpoint_id);
latch.CountDown();
});
@@ -224,38 +226,40 @@ void BwuManager::OnEndpointDisconnect(ClientProxy* client,
const std::string& endpoint_id,
CountDownLatch barrier) {
NEARBY_LOG(INFO, "OnEndpointDisconnect for endpoint %s", endpoint_id.c_str());
- RunOnBwuManagerThread([this, client, endpoint_id, barrier]() mutable {
- if (medium_ == Medium::UNKNOWN_MEDIUM) {
- barrier.CountDown();
- return;
- }
-
- if (handler_) {
- handler_->OnEndpointDisconnect(client, endpoint_id);
- }
-
- auto item = previous_endpoint_channels_.extract(endpoint_id);
-
- if (!item.empty()) {
- auto old_channel = item.mapped();
- if (old_channel != nullptr) {
- old_channel->Close(DisconnectionReason::SHUTDOWN);
- }
- }
- in_progress_upgrades_.erase(endpoint_id);
- CancelRetryUpgradeAlarm(endpoint_id);
-
- successfully_upgraded_endpoints_.erase(endpoint_id);
-
- // If this was our very last endpoint:
- //
- // a) revert all the changes for currentBwuMedium.
- // b) reset currentBwuMedium.
- if (channel_manager_->GetConnectedEndpointsCount() <= 1) {
- Revert();
- }
- barrier.CountDown();
- });
+ RunOnBwuManagerThread(
+ "bwu-on-endpoint-disconnect",
+ [this, client, endpoint_id, barrier]() mutable {
+ if (medium_ == Medium::UNKNOWN_MEDIUM) {
+ barrier.CountDown();
+ return;
+ }
+
+ if (handler_) {
+ handler_->OnEndpointDisconnect(client, endpoint_id);
+ }
+
+ auto item = previous_endpoint_channels_.extract(endpoint_id);
+
+ if (!item.empty()) {
+ auto old_channel = item.mapped();
+ if (old_channel != nullptr) {
+ old_channel->Close(DisconnectionReason::SHUTDOWN);
+ }
+ }
+ in_progress_upgrades_.erase(endpoint_id);
+ CancelRetryUpgradeAlarm(endpoint_id);
+
+ successfully_upgraded_endpoints_.erase(endpoint_id);
+
+ // If this was our very last endpoint:
+ //
+ // a) revert all the changes for currentBwuMedium.
+ // b) reset currentBwuMedium.
+ if (channel_manager_->GetConnectedEndpointsCount() <= 1) {
+ Revert();
+ }
+ barrier.CountDown();
+ });
}
BwuHandler* BwuManager::SetCurrentBwuHandler(Medium medium) {
@@ -275,9 +279,9 @@ void BwuManager::Revert() {
NEARBY_LOG(INFO, "Revert reseting medium %d", medium_);
if (handler_) {
handler_->Revert();
- medium_ = Medium::UNKNOWN_MEDIUM;
handler_ = nullptr;
}
+ medium_ = Medium::UNKNOWN_MEDIUM;
}
void BwuManager::OnBwuNegotiationFrame(ClientProxy* client,
@@ -312,7 +316,8 @@ void BwuManager::OnIncomingConnection(
client->GetServiceId().c_str());
std::shared_ptr<BwuHandler::IncomingSocketConnection> connection(
mutable_connection.release());
- RunOnBwuManagerThread([this, client, connection]() {
+ RunOnBwuManagerThread("bwu-on-incoming-connection", [this, client,
+ connection]() {
EndpointChannel* channel = connection->channel.get();
if (channel == nullptr) {
connection->socket->Close();
@@ -356,8 +361,9 @@ void BwuManager::OnIncomingConnection(
});
}
-void BwuManager::RunOnBwuManagerThread(Runnable runnable) {
- serial_executor_.Execute(std::move(runnable));
+void BwuManager::RunOnBwuManagerThread(const std::string& name,
+ Runnable runnable) {
+ serial_executor_.Execute(name, std::move(runnable));
}
void BwuManager::RunUpgradeProtocol(
@@ -717,10 +723,12 @@ void BwuManager::ProcessSafeToClosePriorChannelEvent(
previous_endpoint_channel->DisableEncryption();
previous_endpoint_channel->Write(parser::ForDisconnection());
- // TODO(b/172380349): Match the Java implementation with no sleep call
-
- // Wait for in-flight messages to reach their peers.
- SystemClock::Sleep(absl::Seconds(1));
+ // Attempt to read the disconnect message from the previous channel. We don't
+ // care whether we successfully read it or whether we get an exception here.
+ // The idea is just to make sure the other side has had a chance to receive
+ // the full SAFE_TO_CLOSE_PRIOR_CHANNEL message before we actually close the
+ // channel. See b/172380349 for more context.
+ previous_endpoint_channel->Read();
previous_endpoint_channel->Close(DisconnectionReason::UPGRADED);
// Now that the old channel has been drained, we can unpause the new channel
@@ -910,7 +918,8 @@ void BwuManager::RetryUpgradesAfterDelay(ClientProxy* client,
CancelableAlarm alarm(
"BWU alarm",
[this, client, endpoint_id]() {
- RunOnBwuManagerThread([this, client, endpoint_id]() {
+ RunOnBwuManagerThread("bwu-retry-upgrade", [this, client,
+ endpoint_id]() {
if (!client->IsConnectedToEndpoint(endpoint_id)) {
return;
}
@@ -946,10 +955,13 @@ void BwuManager::CancelRetryUpgradeAlarm(const std::string& endpoint_id) {
void BwuManager::CancelAllRetryUpgradeAlarms() {
NEARBY_LOG(INFO, "CancelAllRetryUpgradeAlarms invoked");
- for (const auto& item : retry_upgrade_alarms_) {
+ for (auto& item : retry_upgrade_alarms_) {
const std::string& endpoint_id = item.first;
- CancelRetryUpgradeAlarm(endpoint_id);
+ CancelableAlarm& cancellable_alarm = item.second.first;
+ NEARBY_LOG(INFO, "CancelRetryUpgradeAlarm for %s", endpoint_id.c_str());
+ cancellable_alarm.Cancel();
}
+ retry_upgrade_alarms_.clear();
}
Medium BwuManager::GetEndpointMedium(const std::string& endpoint_id) {
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/bwu_manager.h b/chromium/third_party/nearby/src/cpp/core/internal/bwu_manager.h
index 2ba3766605f..f18ddebfa67 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/bwu_manager.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/bwu_manager.h
@@ -24,10 +24,8 @@
#include "core/internal/endpoint_manager.h"
#include "core/internal/mediums/mediums.h"
#include "core/options.h"
-#include "proto/connections/offline_wire_formats.pb.h"
#include "platform/base/byte_array.h"
#include "platform/public/scheduled_executor.h"
-#include "proto/connections_enums.pb.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/time/time.h"
@@ -103,7 +101,8 @@ class BwuManager : public EndpointManager::FrameProcessor {
absl::Seconds(5);
BwuHandler* SetCurrentBwuHandler(Medium medium);
void InitBwuHandlers();
- void RunOnBwuManagerThread(std::function<void()> runnable);
+ void RunOnBwuManagerThread(const std::string& name,
+ std::function<void()> runnable);
std::vector<Medium> StripOutUnavailableMediums(
const std::vector<Medium>& mediums);
Medium ChooseBestUpgradeMedium(const std::vector<Medium>& mediums);
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/bwu_manager_test.cc b/chromium/third_party/nearby/src/cpp/core/internal/bwu_manager_test.cc
index 52ab827846f..50f1905499c 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/bwu_manager_test.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/bwu_manager_test.cc
@@ -21,6 +21,7 @@
#include "core/internal/endpoint_manager.h"
#include "core/internal/mediums/mediums.h"
#include "core/internal/mediums/utils.h"
+#include "core/internal/offline_frames.h"
#include "platform/public/system_clock.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@@ -57,20 +58,49 @@ TEST(BwuManagerTest, CanInitiateBwu) {
bwu_manager.Shutdown();
}
-TEST(BwuManagerTest, CanProcessPathAvailableFrame) {
+TEST(BwuManagerTest, CanProcessBandwidthUpgradeFrames) {
ClientProxy client;
std::string endpoint_id("EP_A");
+ LocationHint location_hint = Utils::BuildLocationHint("US");
Mediums mediums;
EndpointChannelManager ecm;
EndpointManager em{&ecm};
BwuManager bwu_manager{mediums, em, ecm, {}, {}};
- LocationHint location_hint = Utils::BuildLocationHint("US");
- ExceptionOr<OfflineFrame> wrapped_frame = parser::FromBytes(
+ ExceptionOr<OfflineFrame> path_available_frame = parser::FromBytes(
parser::ForBwuWebrtcPathAvailable("my_id", location_hint));
+ bwu_manager.OnIncomingFrame(path_available_frame.result(), endpoint_id,
+ &client, Medium::WEB_RTC);
- bwu_manager.OnIncomingFrame(wrapped_frame.result(), endpoint_id, &client,
+ ExceptionOr<OfflineFrame> last_write_frame =
+ parser::FromBytes(parser::ForBwuLastWrite());
+ bwu_manager.OnIncomingFrame(last_write_frame.result(), endpoint_id, &client,
Medium::WEB_RTC);
+
+ ExceptionOr<OfflineFrame> safe_to_close_frame =
+ parser::FromBytes(parser::ForBwuSafeToClose());
+ bwu_manager.OnIncomingFrame(safe_to_close_frame.result(), endpoint_id,
+ &client, Medium::WEB_RTC);
+
+ bwu_manager.Shutdown();
+}
+
+TEST(BwuManagerTest, InitiateBwu_UpgradeFails_NoCrash) {
+ ClientProxy client;
+ std::string endpoint_id("EP_A");
+ Mediums mediums;
+ EndpointChannelManager ecm;
+ EndpointManager em{&ecm};
+ BwuManager bwu_manager{mediums, em, ecm, {}, {}};
+ parser::UpgradePathInfo upgrade_path_info;
+ upgrade_path_info.set_medium(parser::UpgradePathInfo::WEB_RTC);
+
+ bwu_manager.InitiateBwuForEndpoint(&client, endpoint_id);
+ ExceptionOr<OfflineFrame> bwu_failed_frame =
+ parser::FromBytes(parser::ForBwuFailure(upgrade_path_info));
+ bwu_manager.OnIncomingFrame(bwu_failed_frame.result(), endpoint_id, &client,
+ Medium::WEB_RTC);
+
bwu_manager.Shutdown();
}
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/client_proxy.h b/chromium/third_party/nearby/src/cpp/core/internal/client_proxy.h
index 9ecb6b2c463..92884e15fe5 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/client_proxy.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/client_proxy.h
@@ -28,7 +28,6 @@
#include "platform/base/prng.h"
#include "platform/public/cancelable_alarm.h"
#include "platform/public/mutex.h"
-#include "proto/connections_enums.pb.h"
// Prefer using absl:: versions of a set and a map; they tend to be more
// efficient: implementation is using open-addressing hash tables.
#include "absl/container/flat_hash_map.h"
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/encryption_runner.cc b/chromium/third_party/nearby/src/cpp/core/internal/encryption_runner.cc
index 24832a602d4..24833d758d4 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/encryption_runner.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/encryption_runner.cc
@@ -360,6 +360,7 @@ void EncryptionRunner::StartServer(
EndpointChannel* endpoint_channel,
EncryptionRunner::ResultListener&& listener) {
server_executor_.Execute(
+ "encryption-server",
[runnable{ServerRunnable(client, &alarm_executor_, endpoint_id,
endpoint_channel, std::move(listener))}]() {
runnable();
@@ -371,6 +372,7 @@ void EncryptionRunner::StartClient(
EndpointChannel* endpoint_channel,
EncryptionRunner::ResultListener&& listener) {
client_executor_.Execute(
+ "encryption-client",
[runnable{ClientRunnable(client, &alarm_executor_, endpoint_id,
endpoint_channel, std::move(listener))}]() {
runnable();
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/endpoint_channel_manager.h b/chromium/third_party/nearby/src/cpp/core/internal/endpoint_channel_manager.h
index 31ce2cd278c..fc30e24f82e 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/endpoint_channel_manager.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/endpoint_channel_manager.h
@@ -31,8 +31,8 @@ namespace connections {
// NOTE(std::string):
// All the strings in internal class public interfaces should be exchanged as
-// const std::string& if they are immutable, and as std::string
-// it they are mutable.
+// const std::string& if they are immutable, and as std::string if they are
+// mutable.
// This is to keep all the internal classes compatible with each other,
// and minimize resources spent on the type conversion.
// Project-wide, strings are either passed around as reference (which has
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/endpoint_manager.cc b/chromium/third_party/nearby/src/cpp/core/internal/endpoint_manager.cc
index 500b1e4a2ae..d0d4d0c0d54 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/endpoint_manager.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/endpoint_manager.cc
@@ -20,18 +20,16 @@
#include "core/internal/endpoint_channel.h"
#include "core/internal/offline_frames.h"
#include "platform/base/exception.h"
-#include "platform/base/feature_flags.h"
#include "platform/public/count_down_latch.h"
#include "platform/public/logging.h"
-#include "proto/connections_enums.pb.h"
+#include "platform/public/mutex_lock.h"
+
namespace location {
namespace nearby {
namespace connections {
using ::location::nearby::proto::connections::Medium;
-constexpr absl::Duration EndpointManager::kKeepAliveWriteInterval;
-constexpr absl::Duration EndpointManager::kKeepAliveReadTimeout;
constexpr absl::Duration EndpointManager::kProcessEndpointDisconnectionTimeout;
constexpr absl::Time EndpointManager::kInvalidTimestamp;
@@ -90,6 +88,8 @@ void EndpointManager::EndpointChannelLoopRunnable(
// will retry and attempt to pick another channel.
// If channel is deleted (no mapping), or it is still the same channel
// (same Medium) on which we got the Exception::kIo, we terminate the loop.
+ NEARBY_LOG(INFO, "Started worker loop name=%s, endpoint=%s",
+ runnable_name.c_str(), endpoint_id.c_str());
Medium last_failed_medium = Medium::UNKNOWN_MEDIUM;
while (true) {
// It's important to keep re-fetching the EndpointChannel for an endpoint
@@ -217,13 +217,13 @@ ExceptionOr<bool> EndpointManager::HandleData(
}
ExceptionOr<bool> EndpointManager::HandleKeepAlive(
- EndpointChannel* endpoint_channel) {
+ EndpointChannel* endpoint_channel, absl::Duration keep_alive_interval,
+ absl::Duration keep_alive_timeout) {
// Check if it has been too long since we received a frame from our
// endpoint.
auto last_read_time = endpoint_channel->GetLastReadTimestamp();
if (last_read_time != kInvalidTimestamp &&
- SystemClock::ElapsedRealtime() >
- (last_read_time + EndpointManager::kKeepAliveReadTimeout)) {
+ SystemClock::ElapsedRealtime() > (last_read_time + keep_alive_timeout)) {
NEARBY_LOG(INFO, "Receive timeout expired; aborting KeepAlive worker.");
return ExceptionOr<bool>(false);
}
@@ -241,8 +241,7 @@ ExceptionOr<bool> EndpointManager::HandleKeepAlive(
// switched out from under us in BandwidthUpgradeManager, our write will
// trigger an erroneous write to the encryption context that will cascade
// into all our remote endpoint's future reads failing.
- Exception sleep_exception =
- SystemClock::Sleep(EndpointManager::kKeepAliveWriteInterval);
+ Exception sleep_exception = SystemClock::Sleep(keep_alive_interval);
if (!sleep_exception.Ok()) {
return ExceptionOr<bool>(sleep_exception);
}
@@ -270,7 +269,7 @@ EndpointManager::EndpointManager(EndpointChannelManager* manager)
EndpointManager::~EndpointManager() {
NEARBY_LOG(INFO, "EndpointManager going down");
CountDownLatch latch(1);
- RunOnEndpointManagerThread([this, &latch]() {
+ RunOnEndpointManagerThread("bring-down-endpoints", [this, &latch]() {
NEARBY_LOG(INFO, "Bringing down endpoints");
for (auto& item : endpoints_) {
const std::string& endpoint_id = item.first;
@@ -304,22 +303,16 @@ EndpointManager::~EndpointManager() {
void EndpointManager::RegisterFrameProcessor(
V1Frame::FrameType frame_type, EndpointManager::FrameProcessor* processor) {
- CountDownLatch latch(1);
- RunOnEndpointManagerThread([this, frame_type, &latch, processor]() {
- auto it = frame_processors_.find(frame_type);
- if (it != frame_processors_.end()) {
- NEARBY_LOGS(INFO) << "Frame processor found: updated; type=" << frame_type
- << "; processor=" << processor << "; self=" << this;
- LockedFrameProcessor frame_processor_lock(&it->second);
- frame_processor_lock.set(processor);
- } else {
- NEARBY_LOGS(INFO) << "Frame processor added; type=" << frame_type
- << "; processor=" << processor << "; self=" << this;
- frame_processors_.emplace(frame_type, processor);
- }
- latch.CountDown();
- });
- latch.Await();
+ if (auto frame_processor = GetFrameProcessor(frame_type)) {
+ NEARBY_LOGS(INFO) << "Frame processor found: updated; type=" << frame_type
+ << "; processor=" << processor << "; self=" << this;
+ frame_processor.set(processor);
+ } else {
+ MutexLock lock(&frame_processors_lock_);
+ NEARBY_LOGS(INFO) << "Frame processor added; type=" << frame_type
+ << "; processor=" << processor << "; self=" << this;
+ frame_processors_.emplace(frame_type, processor);
+ }
}
void EndpointManager::UnregisterFrameProcessor(
@@ -328,20 +321,9 @@ void EndpointManager::UnregisterFrameProcessor(
NEARBY_LOGS(INFO) << "UnregisterFrameProcessor [enter]: processor ="
<< processor;
if (processor == nullptr) return;
- CountDownLatch latch(1);
- RunOnEndpointManagerThread([this, frame_type, processor, &latch]() {
- auto it = frame_processors_.find(frame_type);
- if (it == frame_processors_.end()) {
- NEARBY_LOGS(INFO) << "UnregisterFrameProcessor [not found]: processor="
- << processor;
- latch.CountDown();
- return;
- }
- NEARBY_LOGS(INFO) << "UnregisterFrameProcessor [found]: processor="
- << processor;
- LockedFrameProcessor frame_processor_lock(&it->second);
- if (frame_processor_lock.get() == processor) {
- frame_processor_lock.reset();
+ if (auto frame_processor = GetFrameProcessor(frame_type)) {
+ if (frame_processor.get() == processor) {
+ frame_processor.reset();
NEARBY_LOGS(INFO) << "Unregistered: type=" << frame_type
<< "; processor=" << processor << "; self=" << this;
} else {
@@ -349,17 +331,17 @@ void EndpointManager::UnregisterFrameProcessor(
INFO,
"Failed to unregister: type=%d; processor mismatch: passed=%p, "
"expected=%p",
- frame_type, processor, frame_processor_lock.get());
+ frame_type, processor, frame_processor.get());
}
- latch.CountDown();
- });
- latch.Await();
- NEARBY_LOGS(INFO) << "Unregistered [sync done]: type=" << frame_type
- << "; processor=" << processor << "; self=" << this;
+ } else {
+ NEARBY_LOGS(INFO) << "UnregisterFrameProcessor [not found]: processor="
+ << processor;
+ }
}
EndpointManager::LockedFrameProcessor EndpointManager::GetFrameProcessor(
V1Frame::FrameType frame_type) {
+ MutexLock lock(&frame_processors_lock_);
auto it = frame_processors_.find(frame_type);
if (it != frame_processors_.end()) {
return LockedFrameProcessor(&it->second);
@@ -408,9 +390,11 @@ void EndpointManager::RegisterEndpoint(ClientProxy* client,
// Instead, we release() a pointer, and pass a raw pointer, which is copyalbe.
// We ignore the risk of job not scheduled (and an associated risk of memory
// leak), because this may only happen during service shutdown.
- RunOnEndpointManagerThread([this, client, channel = channel.release(),
- &endpoint_id, &info, &options, &listener,
- &latch]() {
+ RunOnEndpointManagerThread("register-endpoint", [this, client,
+ channel = channel.release(),
+ &endpoint_id, &info,
+ &options, &listener,
+ &latch]() {
if (endpoints_.contains(endpoint_id)) {
NEARBY_LOG(WARNING, "Registing duplicate endpoint %s",
endpoint_id.c_str());
@@ -420,6 +404,18 @@ void EndpointManager::RegisterEndpoint(ClientProxy* client,
EnsureWorkersTerminated(endpoint_id);
}
}
+
+ absl::Duration keep_alive_interval =
+ absl::Milliseconds(options.keep_alive_interval_millis);
+ absl::Duration keep_alive_timeout =
+ absl::Milliseconds(options.keep_alive_timeout_millis);
+ NEARBY_LOGS(INFO) << "Registering endpoint " << endpoint_id.c_str()
+ << " for client " << client->GetClientId()
+ << " with keep-alive frame as interval="
+ << absl::FormatDuration(keep_alive_interval).c_str()
+ << ", timeout="
+ << absl::FormatDuration(keep_alive_timeout).c_str();
+
// Pass ownership of channel to EndpointChannelManager
NEARBY_LOG(INFO, "Registering endpoint with channel manager: id=%s",
endpoint_id.c_str());
@@ -455,8 +451,7 @@ void EndpointManager::RegisterEndpoint(ClientProxy* client,
// running on the keep_alive_executor_ pool. This instance will
// periodically send out a ping* to the endpoint while listening for an
// incoming pong**. If it fails to send the ping, or if no pong is heard
- // within kKeepAliveReadTimeoutMillis milliseconds, it initiates a
- // disconnection.
+ // within keep_alive_interval_, it initiates a disconnection.
//
// (*) Bluetooth requires a constant outgoing stream of messages. If
// there's silence, Android will break the socket. This is why we ping.
@@ -466,14 +461,17 @@ void EndpointManager::RegisterEndpoint(ClientProxy* client,
//
// Using weak_ptr just in case the barrier is freed, to save the UAF crash
// in b/179800119.
- StartEndpointKeepAliveManager([this, client, endpoint_id,
- barrier = std::weak_ptr<CountDownLatch>(
- endpoint_state.barrier)]() {
- EndpointChannelLoopRunnable("KeepAliveManager", client, endpoint_id,
- barrier, [this](EndpointChannel* channel) {
- return HandleKeepAlive(channel);
- });
- });
+ StartEndpointKeepAliveManager(
+ [this, client, endpoint_id, keep_alive_interval, keep_alive_timeout,
+ barrier = std::weak_ptr<CountDownLatch>(endpoint_state.barrier)]() {
+ EndpointChannelLoopRunnable(
+ "KeepAliveManager", client, endpoint_id, barrier,
+ [this, keep_alive_interval,
+ keep_alive_timeout](EndpointChannel* channel) {
+ return HandleKeepAlive(channel, keep_alive_interval,
+ keep_alive_timeout);
+ });
+ });
NEARBY_LOG(INFO, "Workers started, notifying client; id=%s",
endpoint_id.c_str());
@@ -489,11 +487,12 @@ void EndpointManager::UnregisterEndpoint(ClientProxy* client,
const std::string& endpoint_id) {
NEARBY_LOG(ERROR, "UnregisterEndpoint for endpoint %s", endpoint_id.c_str());
CountDownLatch latch(1);
- RunOnEndpointManagerThread([this, client, endpoint_id, &latch]() {
- RemoveEndpoint(client, endpoint_id,
- client->IsConnectedToEndpoint(endpoint_id));
- latch.CountDown();
- });
+ RunOnEndpointManagerThread(
+ "unregister-endpoint", [this, client, endpoint_id, &latch]() {
+ RemoveEndpoint(client, endpoint_id,
+ client->IsConnectedToEndpoint(endpoint_id));
+ latch.CountDown();
+ });
latch.Await();
}
@@ -525,7 +524,7 @@ std::vector<std::string> EndpointManager::SendPayloadChunk(
void EndpointManager::DiscardEndpoint(ClientProxy* client,
const std::string& endpoint_id) {
NEARBY_LOG(ERROR, "DiscardEndpoint for endpoint %s", endpoint_id.c_str());
- RunOnEndpointManagerThread([this, client, endpoint_id]() {
+ RunOnEndpointManagerThread("discard-endpoint", [this, client, endpoint_id]() {
RemoveEndpoint(client, endpoint_id,
/*notify=*/
client->IsConnectedToEndpoint(endpoint_id));
@@ -573,9 +572,28 @@ void EndpointManager::RemoveEndpoint(ClientProxy* client,
void EndpointManager::WaitForEndpointDisconnectionProcessing(
ClientProxy* client, const std::string& endpoint_id) {
NEARBY_LOGS(INFO) << "Wait: client=" << client << "; id=" << endpoint_id;
+ CountDownLatch barrier =
+ NotifyFrameProcessorsOnEndpointDisconnect(client, endpoint_id);
+
+ NEARBY_LOGS(INFO) << "Waiting for frame processors to disconnect from: "
+ << endpoint_id;
+ if (!barrier.Await(kProcessEndpointDisconnectionTimeout).result()) {
+ NEARBY_LOGS(INFO) << "Failed to disconnect frame processors from: "
+ << endpoint_id;
+ } else {
+ NEARBY_LOGS(INFO)
+ << "Finished waiting for frame processors to disconnect from: "
+ << endpoint_id;
+ }
+}
+
+CountDownLatch EndpointManager::NotifyFrameProcessorsOnEndpointDisconnect(
+ ClientProxy* client, const std::string& endpoint_id) {
+ NEARBY_LOGS(INFO) << "NotifyFrameProcessorsOnEndpointDisconnect: client="
+ << client << "; id=" << endpoint_id;
+ MutexLock lock(&frame_processors_lock_);
auto total_size = frame_processors_.size();
NEARBY_LOGS(INFO) << "Total frame processors: " << total_size;
- if (!total_size) return;
CountDownLatch barrier(total_size);
int valid = 0;
@@ -593,21 +611,10 @@ void EndpointManager::WaitForEndpointDisconnectionProcessing(
if (!valid) {
NEARBY_LOGS(INFO) << "No valid frame processors.";
- return;
} else {
NEARBY_LOGS(INFO) << "Valid frame processors: " << valid;
}
-
- NEARBY_LOGS(INFO) << "Waiting for " << valid
- << " frame processors to disconnect from: " << endpoint_id;
- if (!barrier.Await(kProcessEndpointDisconnectionTimeout).result()) {
- NEARBY_LOGS(INFO) << "Failed to disconnect frame processors from: "
- << endpoint_id;
- } else {
- NEARBY_LOGS(INFO)
- << "Finished waiting for frame processors to disconnect from: "
- << endpoint_id;
- }
+ return barrier;
}
std::vector<std::string> EndpointManager::SendTransferFrameBytes(
@@ -640,15 +647,16 @@ std::vector<std::string> EndpointManager::SendTransferFrameBytes(
}
void EndpointManager::StartEndpointReader(Runnable runnable) {
- handlers_executor_.Execute(std::move(runnable));
+ handlers_executor_.Execute("reader", std::move(runnable));
}
void EndpointManager::StartEndpointKeepAliveManager(Runnable runnable) {
- keep_alive_executor_.Execute(std::move(runnable));
+ keep_alive_executor_.Execute("keep-alive", std::move(runnable));
}
-void EndpointManager::RunOnEndpointManagerThread(Runnable runnable) {
- serial_executor_.Execute(std::move(runnable));
+void EndpointManager::RunOnEndpointManagerThread(const std::string& name,
+ Runnable runnable) {
+ serial_executor_.Execute(name, std::move(runnable));
}
} // namespace connections
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/endpoint_manager.h b/chromium/third_party/nearby/src/cpp/core/internal/endpoint_manager.h
index 02c0a7cc4b4..8105c23efcb 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/endpoint_manager.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/endpoint_manager.h
@@ -22,14 +22,13 @@
#include "core/internal/endpoint_channel.h"
#include "core/internal/endpoint_channel_manager.h"
#include "core/listeners.h"
-#include "proto/connections/offline_wire_formats.pb.h"
#include "platform/base/byte_array.h"
#include "platform/base/runnable.h"
#include "platform/public/count_down_latch.h"
#include "platform/public/multi_thread_executor.h"
#include "platform/public/single_thread_executor.h"
#include "platform/public/system_clock.h"
-#include "proto/connections_enums.pb.h"
+#include "absl/base/thread_annotations.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/time/time.h"
@@ -172,7 +171,9 @@ class EndpointManager {
ClientProxy* client_proxy,
EndpointChannel* endpoint_channel);
- ExceptionOr<bool> HandleKeepAlive(EndpointChannel* endpoint_channel);
+ ExceptionOr<bool> HandleKeepAlive(EndpointChannel* endpoint_channel,
+ absl::Duration keep_alive_interval,
+ absl::Duration keep_alive_timeout);
// Waits for a given endpoint EndpointChannelLoopRunnable() workers to
// terminate.
@@ -191,10 +192,6 @@ class EndpointManager {
static void WaitForLatch(const std::string& method_name,
CountDownLatch* latch, std::int32_t timeout_millis);
- static constexpr absl::Duration kKeepAliveWriteInterval =
- absl::Milliseconds(5000);
- static constexpr absl::Duration kKeepAliveReadTimeout =
- absl::Milliseconds(30000);
static constexpr absl::Duration kProcessEndpointDisconnectionTimeout =
absl::Milliseconds(2000);
static constexpr std::int32_t kMaxConcurrentEndpoints = 50;
@@ -212,6 +209,9 @@ class EndpointManager {
void WaitForEndpointDisconnectionProcessing(ClientProxy* client,
const std::string& endpoint_id);
+ CountDownLatch NotifyFrameProcessorsOnEndpointDisconnect(
+ ClientProxy* client, const std::string& endpoint_id);
+
std::vector<std::string> SendTransferFrameBytes(
const std::vector<std::string>& endpoint_ids,
const ByteArray& payload_transfer_frame_bytes, std::int64_t payload_id,
@@ -230,12 +230,13 @@ class EndpointManager {
void StartEndpointKeepAliveManager(Runnable runnable);
// Executes all jobs sequentially, on a serial_executor_.
- void RunOnEndpointManagerThread(Runnable runnable);
+ void RunOnEndpointManagerThread(const std::string& name, Runnable runnable);
EndpointChannelManager* channel_manager_;
+ RecursiveMutex frame_processors_lock_;
absl::flat_hash_map<V1Frame::FrameType, FrameProcessorWithMutex>
- frame_processors_;
+ frame_processors_ ABSL_GUARDED_BY(frame_processors_lock_);
// We keep track of all registered channel endpoints here.
absl::flat_hash_map<std::string, EndpointState> endpoints_;
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/endpoint_manager_test.cc b/chromium/third_party/nearby/src/cpp/core/internal/endpoint_manager_test.cc
index e5e1b7aaebb..137a49547aa 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/endpoint_manager_test.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/endpoint_manager_test.cc
@@ -176,8 +176,9 @@ TEST_F(EndpointManagerTest, RegisterFrameProcessorWorks) {
auto endpoint_channel = std::make_unique<MockEndpointChannel>();
auto connect_request = std::make_unique<MockFrameProcessor>();
ByteArray endpoint_info{"endpoint_name"};
- auto read_data = parser::ForConnectionRequest(
- "endpoint_id", endpoint_info, 1234, false, "", std::vector{Medium::BLE});
+ auto read_data =
+ parser::ForConnectionRequest("endpoint_id", endpoint_info, 1234, false,
+ "", std::vector{Medium::BLE}, 0, 0);
EXPECT_CALL(*connect_request, OnIncomingFrame);
EXPECT_CALL(*connect_request, OnEndpointDisconnect);
EXPECT_CALL(*endpoint_channel, Read())
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/internal_payload.h b/chromium/third_party/nearby/src/cpp/core/internal/internal_payload.h
index 8861f17eb5c..9a36fa88ef2 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/internal_payload.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/internal_payload.h
@@ -18,7 +18,6 @@
#include <cstdint>
#include "core/payload.h"
-#include "proto/connections/offline_wire_formats.pb.h"
#include "platform/base/byte_array.h"
#include "platform/base/exception.h"
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/internal_payload_factory.h b/chromium/third_party/nearby/src/cpp/core/internal/internal_payload_factory.h
index cd7efc568b9..a0387b77ed4 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/internal_payload_factory.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/internal_payload_factory.h
@@ -17,7 +17,6 @@
#include "core/internal/internal_payload.h"
#include "core/payload.h"
-#include "proto/connections/offline_wire_formats.pb.h"
namespace location {
namespace nearby {
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/BUILD b/chromium/third_party/nearby/src/cpp/core/internal/mediums/BUILD
index 6b9fb0303ba..9a721a3d8ce 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/BUILD
+++ b/chromium/third_party/nearby/src/cpp/core/internal/mediums/BUILD
@@ -88,21 +88,37 @@ cc_test(
"bluetooth_radio_test.cc",
"lost_entity_tracker_test.cc",
"uuid_test.cc",
- "webrtc_test.cc",
"wifi_lan_test.cc",
],
shard_count = 16,
deps = [
":mediums",
- "//core/internal/mediums/webrtc",
- "//platform/base",
"//platform/base:test_util",
"//platform/impl/g3", # build_cleaner: keep
"//platform/public:comm",
- "//platform/public:logging",
"//platform/public:types",
"//testing/base/public:gunit_main",
"//absl/strings",
"//absl/time",
],
)
+
+cc_test(
+ name = "core_internal_mediums_webrtc_test",
+ size = "small",
+ srcs = [
+ "webrtc_test.cc",
+ ],
+ shard_count = 16,
+ tags = ["notsan"], # NOTE(b/139734036): known data race in usrsctplib.
+ deps = [
+ ":mediums",
+ "//core/internal/mediums/webrtc",
+ "//platform/base",
+ "//platform/base:test_util",
+ "//platform/impl/g3", # build_cleaner: keep
+ "//platform/public:types",
+ "//testing/base/public:gunit_main",
+ "//absl/strings",
+ ],
+)
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble.cc
index 6085928f2fa..841d04a23e5 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble.cc
@@ -255,16 +255,14 @@ bool Ble::StartAcceptingConnections(const std::string& service_id,
if (IsAcceptingConnectionsLocked(service_id)) {
NEARBY_LOGS(INFO)
- << "Refusing to start accepting BLE connections for "
- << service_id
+ << "Refusing to start accepting BLE connections for " << service_id
<< " because another BLE peripheral socket is already in-progress.";
return false;
}
if (!radio_.IsEnabled()) {
NEARBY_LOGS(INFO) << "Can't start accepting BLE connections for "
- << service_id
- << " because Bluetooth isn't enabled.";
+ << service_id << " because Bluetooth isn't enabled.";
return false;
}
@@ -310,7 +308,6 @@ bool Ble::IsAcceptingConnectionsLocked(const std::string& service_id) {
return accepting_connections_info_.Existed(service_id);
}
-// TODO(b/169303284): Handles Cancellation and registration.
BleSocket Ble::Connect(BlePeripheral& peripheral, const std::string& service_id,
CancellationFlag* cancellation_flag) {
MutexLock lock(&mutex_);
@@ -324,8 +321,8 @@ BleSocket Ble::Connect(BlePeripheral& peripheral, const std::string& service_id,
}
if (!radio_.IsEnabled()) {
- NEARBY_LOGS(INFO) << "Can't create client BLE socket to "
- << &peripheral << " because Bluetooth isn't enabled.";
+ NEARBY_LOGS(INFO) << "Can't create client BLE socket to " << &peripheral
+ << " because Bluetooth isn't enabled.";
return socket;
}
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/bluetooth_classic.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/bluetooth_classic.cc
index ad0f49ecb14..6f870b17117 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/bluetooth_classic.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/mediums/bluetooth_classic.cc
@@ -271,19 +271,20 @@ bool BluetoothClassic::StartAcceptingConnections(
// Start the accept loop on a dedicated thread - this stays alive and
// listening for new incoming connections until StopAcceptingConnections() is
// invoked.
- accept_loops_runner_.Execute([callback = std::move(callback),
- server_socket = std::move(owned_socket),
- service_name]() mutable {
- while (true) {
- BluetoothSocket client_socket = server_socket.Accept();
- if (!client_socket.IsValid()) {
- server_socket.Close();
- break;
- }
-
- callback.accepted_cb(std::move(client_socket));
- }
- });
+ accept_loops_runner_.Execute(
+ "bt-accept",
+ [callback = std::move(callback), server_socket = std::move(owned_socket),
+ service_name]() mutable {
+ while (true) {
+ BluetoothSocket client_socket = server_socket.Accept();
+ if (!client_socket.IsValid()) {
+ server_socket.Close();
+ break;
+ }
+
+ callback.accepted_cb(std::move(client_socket));
+ }
+ });
return true;
}
@@ -344,7 +345,6 @@ bool BluetoothClassic::StopAcceptingConnections(
return true;
}
-// TODO(b/169303284): Handles Cancellation and registration.
BluetoothSocket BluetoothClassic::Connect(BluetoothDevice& bluetooth_device,
const std::string& service_name,
CancellationFlag* cancellation_flag) {
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/utils.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/utils.h
index 28f275cefca..c8957c783b1 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/utils.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/mediums/utils.h
@@ -18,7 +18,6 @@
#include <memory>
#include "proto/connections/offline_wire_formats.pb.h"
-#include "proto/connections/offline_wire_formats.pb.h"
#include "platform/base/byte_array.h"
namespace location {
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc.cc
index 1c839415f7c..929d60c02c0 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc.cc
@@ -62,15 +62,6 @@ WebRtc::~WebRtc() {
for (const auto& service_id : service_ids) {
StopAcceptingConnections(service_id);
}
-
- // Disconnect all connections
- absl::flat_hash_set<std::string> peer_ids;
- for (auto& item : sockets_) {
- peer_ids.emplace(item.first);
- }
- for (const auto& peer_id : peer_ids) {
- sockets_.find(peer_id)->second.Close();
- }
}
const std::string WebRtc::GetDefaultCountryCode() {
@@ -188,11 +179,10 @@ void WebRtc::StopAcceptingConnections(const std::string& service_id) {
// Skip fully connected connections in this step. If the connection was
// formed while we were accepting connections, then it will stay alive until
// it's explicitly closed.
- if (entry->second->GetState() == ConnectionFlow::State::kConnected) {
+ if (!entry->second->CloseIfNotConnected()) {
continue;
}
- entry->second->Close();
connection_flows_.erase(peer_id);
}
@@ -260,17 +250,14 @@ WebRtcSocketWrapper WebRtc::AttemptToConnect(
"Cannot connect to WebRTC peer %s because we failed to create a "
"SignalingMessenger.",
remote_peer_id.GetId().c_str());
- connection_flow->Close();
return WebRtcSocketWrapper();
}
// This registers ourselves w/ Tachyon, creating a room from the PeerId.
// This allows a remote device to message us over Tachyon.
- auto signaling_complete_callback = [this, &socket_future](bool success) {
+ auto signaling_complete_callback = [socket_future](bool success) mutable {
if (!success) {
- OffloadFromThread([&socket_future]() {
- socket_future.SetException({Exception::kFailed});
- });
+ socket_future.SetException({Exception::kFailed});
}
};
if (!info.signaling_messenger->StartReceivingMessages(
@@ -281,7 +268,6 @@ WebRtcSocketWrapper WebRtc::AttemptToConnect(
"receiving messages over Tachyon.",
remote_peer_id.GetId().c_str());
info.signaling_messenger.reset();
- connection_flow->Close();
return WebRtcSocketWrapper();
}
@@ -294,7 +280,6 @@ WebRtcSocketWrapper WebRtc::AttemptToConnect(
"the peer over Tachyon.",
remote_peer_id.GetId().c_str());
info.signaling_messenger.reset();
- connection_flow->Close();
return WebRtcSocketWrapper();
}
@@ -392,7 +377,7 @@ void WebRtc::ProcessLocalIceCandidate(
void WebRtc::OnSignalingMessage(const std::string& service_id,
const ByteArray& message) {
- OffloadFromThread([this, service_id, message]() {
+ OffloadFromThread("rtc-on-signaling-message", [this, service_id, message]() {
ProcessTachyonInboxMessage(service_id, message);
});
}
@@ -403,7 +388,7 @@ void WebRtc::OnSignalingComplete(const std::string& service_id, bool success) {
return;
}
- OffloadFromThread([this, service_id]() {
+ OffloadFromThread("rtc-on-signaling-complete", [this, service_id]() {
MutexLock lock(&mutex_);
const auto& info_entry = accepting_connections_info_.find(service_id);
if (info_entry == accepting_connections_info_.end()) {
@@ -657,27 +642,16 @@ void WebRtc::RestartTachyonReceiveMessages(const std::string& service_id) {
service_id.c_str());
}
-void WebRtc::ProcessDataChannelCreated(
- const std::string& service_id, const PeerId& remote_peer_id,
- rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel) {
+void WebRtc::ProcessDataChannelOpen(const std::string& service_id,
+ const PeerId& remote_peer_id,
+ WebRtcSocketWrapper socket_wrapper) {
MutexLock lock(&mutex_);
- // Transform the DataChannel into a socket.
- auto socket = std::make_unique<WebRtcSocket>("WebRtcSocket", data_channel);
- socket->SetOnSocketClosedListener({[this, remote_peer_id]() {
- OffloadFromThread(
- [this, remote_peer_id]() { ProcessDataChannelClosed(remote_peer_id); });
- }});
- WebRtcSocketWrapper wrapper = WebRtcSocketWrapper(std::move(socket));
-
- // Store this DataChannel so that we can update it later.
- sockets_.emplace(remote_peer_id.GetId(), wrapper);
-
// Notify the client of the newly formed socket.
const auto& connection_request_entry =
requesting_connections_info_.find(remote_peer_id.GetId());
if (connection_request_entry != requesting_connections_info_.end()) {
- connection_request_entry->second.socket_future.Set(wrapper);
+ connection_request_entry->second.socket_future.Set(socket_wrapper);
return;
}
@@ -685,49 +659,23 @@ void WebRtc::ProcessDataChannelCreated(
accepting_connections_info_.find(service_id);
if (accepting_connection_entry != accepting_connections_info_.end()) {
accepting_connection_entry->second.accepted_connection_callback.accepted_cb(
- wrapper);
+ socket_wrapper);
return;
}
// No one to handle the newly created DataChannel, so we'll just close it.
- wrapper.Close();
+ socket_wrapper.Close();
NEARBY_LOG(INFO,
"Ignoring new DataChannel because we "
"are not accepting connections for service %s.",
service_id.c_str());
}
-void WebRtc::ProcessDataChannelMessage(const PeerId& remote_peer_id,
- const ByteArray& message) {
- MutexLock lock(&mutex_);
- const auto& entry = sockets_.find(remote_peer_id.GetId());
- if (entry == sockets_.end()) {
- return;
- }
-
- entry->second.NotifyDataChannelMsgReceived(message);
-}
-
-void WebRtc::ProcessDataChannelBufferAmountChanged(
- const PeerId& remote_peer_id) {
- MutexLock lock(&mutex_);
- const auto& entry = sockets_.find(remote_peer_id.GetId());
- if (entry == sockets_.end()) {
- return;
- }
-
- entry->second.NotifyDataChannelBufferedAmountChanged();
-}
-
void WebRtc::ProcessDataChannelClosed(const PeerId& remote_peer_id) {
MutexLock lock(&mutex_);
- const auto& entry = sockets_.find(remote_peer_id.GetId());
- if (entry == sockets_.end()) {
- return;
- }
-
- entry->second.Close();
- sockets_.erase(remote_peer_id.GetId());
+ NEARBY_LOG(INFO,
+ "Data channel has closed, removing connection flow for peer %s.",
+ remote_peer_id.GetId().c_str());
RemoveConnectionFlow(remote_peer_id);
}
@@ -746,35 +694,24 @@ std::unique_ptr<ConnectionFlow> WebRtc::CreateConnectionFlow(
::location::nearby::mediums::IceCandidate encoded_ice_candidate =
webrtc_frames::EncodeIceCandidate(*ice_candidate);
OffloadFromThread(
+ "rtc-ice-candidates",
[this, service_id, remote_peer_id, encoded_ice_candidate]() {
ProcessLocalIceCandidate(service_id, remote_peer_id,
encoded_ice_candidate);
});
}}},
{
- .data_channel_created_cb =
- {[this, service_id,
- remote_peer_id](rtc::scoped_refptr<webrtc::DataChannelInterface>
- data_channel) {
- OffloadFromThread(
- [this, service_id, remote_peer_id, data_channel]() {
- ProcessDataChannelCreated(service_id, remote_peer_id,
- data_channel);
- });
- }},
- .data_channel_message_received_cb = {[this, remote_peer_id](
- const ByteArray& message) {
- OffloadFromThread([this, remote_peer_id, message]() {
- ProcessDataChannelMessage(remote_peer_id, message);
- });
- }},
- .data_channel_buffered_amount_changed_cb = {[this, remote_peer_id]() {
- OffloadFromThread([this, remote_peer_id]() {
- ProcessDataChannelBufferAmountChanged(remote_peer_id);
- });
+ .data_channel_open_cb = {[this, service_id, remote_peer_id](
+ WebRtcSocketWrapper socket_wrapper) {
+ OffloadFromThread(
+ "rtc-channel-created",
+ [this, service_id, remote_peer_id, socket_wrapper]() {
+ ProcessDataChannelOpen(service_id, remote_peer_id,
+ socket_wrapper);
+ });
}},
.data_channel_closed_cb = {[this, remote_peer_id]() {
- OffloadFromThread([this, remote_peer_id]() {
+ OffloadFromThread("rtc-channel-closed", [this, remote_peer_id]() {
ProcessDataChannelClosed(remote_peer_id);
});
}},
@@ -783,14 +720,10 @@ std::unique_ptr<ConnectionFlow> WebRtc::CreateConnectionFlow(
}
void WebRtc::RemoveConnectionFlow(const PeerId& remote_peer_id) {
- const auto& entry = connection_flows_.find(remote_peer_id.GetId());
- if (entry == connection_flows_.end()) {
+ if (!connection_flows_.erase(remote_peer_id.GetId())) {
return;
}
- entry->second->Close();
- connection_flows_.erase(remote_peer_id.GetId());
-
// If we had an outgoing connection request w/ this peer, report the failure
// to the future that's being waited on.
const auto& connection_request_entry =
@@ -801,8 +734,8 @@ void WebRtc::RemoveConnectionFlow(const PeerId& remote_peer_id) {
}
}
-void WebRtc::OffloadFromThread(Runnable runnable) {
- single_thread_executor_.Execute(std::move(runnable));
+void WebRtc::OffloadFromThread(const std::string& name, Runnable runnable) {
+ single_thread_executor_.Execute(name, std::move(runnable));
}
} // namespace mediums
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc.h
index ac3ae2c2324..b22315e4d91 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc.h
@@ -26,7 +26,6 @@
#include "core/internal/mediums/webrtc/webrtc_socket.h"
#include "core/internal/mediums/webrtc/webrtc_socket_wrapper.h"
#include "proto/connections/offline_wire_formats.pb.h"
-#include "proto/connections/offline_wire_formats.pb.h"
#include "platform/base/byte_array.h"
#include "platform/base/cancellation_flag.h"
#include "platform/base/listeners.h"
@@ -209,18 +208,9 @@ class WebRtc {
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Runs on |single_thread_executor_|.
- void ProcessDataChannelCreated(
- const std::string& service_id, const PeerId& remote_peer_id,
- rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel)
- ABSL_LOCKS_EXCLUDED(mutex_);
-
- // Runs on |single_thread_executor_|.
- void ProcessDataChannelMessage(const PeerId& remote_peer_id,
- const ByteArray& message)
- ABSL_LOCKS_EXCLUDED(mutex_);
-
- // Runs on |single_thread_executor_|.
- void ProcessDataChannelBufferAmountChanged(const PeerId& remote_peer_id)
+ void ProcessDataChannelOpen(const std::string& service_id,
+ const PeerId& remote_peer_id,
+ WebRtcSocketWrapper socket_wrapper)
ABSL_LOCKS_EXCLUDED(mutex_);
// Runs on |single_thread_executor_|.
@@ -241,7 +231,7 @@ class WebRtc {
void RestartTachyonReceiveMessages(const std::string& service_id)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
- void OffloadFromThread(Runnable runnable);
+ void OffloadFromThread(const std::string& name, Runnable runnable);
Mutex mutex_;
@@ -265,11 +255,6 @@ class WebRtc {
// a unique ConnectionFlow.
absl::flat_hash_map<std::string, std::unique_ptr<ConnectionFlow>>
connection_flows_ ABSL_GUARDED_BY(mutex_);
-
- // A map of a remote PeerId -> Socket. Non-empty while we have active
- // connections.
- absl::flat_hash_map<std::string, WebRtcSocketWrapper> sockets_
- ABSL_GUARDED_BY(mutex_);
};
} // namespace mediums
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/BUILD b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/BUILD
index a310c2aa2ee..ddff64b2f6f 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/BUILD
+++ b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/BUILD
@@ -16,8 +16,6 @@ cc_library(
name = "webrtc",
srcs = [
"connection_flow.cc",
- "data_channel_observer_impl.cc",
- "peer_connection_observer_impl.cc",
"peer_id.cc",
"signaling_frames.cc",
"webrtc_socket.cc",
@@ -25,9 +23,7 @@ cc_library(
hdrs = [
"connection_flow.h",
"data_channel_listener.h",
- "data_channel_observer_impl.h",
"local_ice_candidate_listener.h",
- "peer_connection_observer_impl.h",
"peer_id.h",
"session_description_wrapper.h",
"signaling_frames.h",
@@ -54,6 +50,7 @@ cc_library(
cc_test(
name = "webrtc_test",
+ timeout = "short",
srcs = [
"connection_flow_test.cc",
"peer_id_test.cc",
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/connection_flow.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/connection_flow.cc
index ff8582c92d1..af11aa945de 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/connection_flow.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/connection_flow.cc
@@ -18,6 +18,8 @@
#include <memory>
#include "core/internal/mediums/webrtc/session_description_wrapper.h"
+#include "core/internal/mediums/webrtc/webrtc_socket.h"
+#include "core/internal/mediums/webrtc/webrtc_socket_wrapper.h"
#include "platform/public/logging.h"
#include "platform/public/mutex_lock.h"
#include "platform/public/webrtc.h"
@@ -32,57 +34,87 @@ namespace connections {
namespace mediums {
constexpr absl::Duration ConnectionFlow::kTimeout;
+constexpr absl::Duration ConnectionFlow::kPeerConnectionTimeout;
-namespace {
// This is the same as the nearby data channel name.
-const char kDataChannelName[] = "dataChannel";
+constexpr char kDataChannelName[] = "dataChannel";
class CreateSessionDescriptionObserverImpl
: public webrtc::CreateSessionDescriptionObserver {
public:
- explicit CreateSessionDescriptionObserverImpl(
- Future<SessionDescriptionWrapper>* settable_future)
- : settable_future_(settable_future) {}
- ~CreateSessionDescriptionObserverImpl() override = default;
+ CreateSessionDescriptionObserverImpl(
+ ConnectionFlow* connection_flow,
+ Future<SessionDescriptionWrapper> settable_future,
+ ConnectionFlow::State expected_entry_state,
+ ConnectionFlow::State exit_state)
+ : connection_flow_{connection_flow},
+ settable_future_{settable_future},
+ expected_entry_state_{expected_entry_state},
+ exit_state_{exit_state} {}
// webrtc::CreateSessionDescriptionObserver
void OnSuccess(webrtc::SessionDescriptionInterface* desc) override {
- settable_future_->Set(SessionDescriptionWrapper{desc});
+ if (connection_flow_->TransitionState(expected_entry_state_, exit_state_)) {
+ settable_future_.Set(SessionDescriptionWrapper{desc});
+ } else {
+ settable_future_.SetException({Exception::kFailed});
+ }
}
void OnFailure(webrtc::RTCError error) override {
NEARBY_LOG(ERROR, "Error when creating session description: %s",
error.message());
- settable_future_->SetException({Exception::kFailed});
+ settable_future_.SetException({Exception::kFailed});
}
private:
- std::unique_ptr<Future<SessionDescriptionWrapper>> settable_future_;
+ ConnectionFlow* connection_flow_;
+ Future<SessionDescriptionWrapper> settable_future_;
+ ConnectionFlow::State expected_entry_state_;
+ ConnectionFlow::State exit_state_;
};
-class SetSessionDescriptionObserverImpl
- : public webrtc::SetSessionDescriptionObserver {
+class SetDescriptionObserverBase {
public:
- explicit SetSessionDescriptionObserverImpl(Future<bool>* settable_future)
- : settable_future_(settable_future) {}
-
- void OnSuccess() override { settable_future_->Set(true); }
+ ExceptionOr<bool> GetResult(absl::Duration timeout) {
+ return settable_future_.Get(timeout);
+ }
- void OnFailure(webrtc::RTCError error) override {
- NEARBY_LOG(ERROR, "Error when setting session description: %s",
- error.message());
- settable_future_->SetException({Exception::kFailed});
+ protected:
+ void OnSetDescriptionComplete(webrtc::RTCError error) {
+ // On success, |error.ok()| is true.
+ if (error.ok()) {
+ settable_future_.Set(true);
+ return;
+ }
+ settable_future_.SetException({Exception::kFailed});
}
private:
- std::unique_ptr<Future<bool>> settable_future_;
+ Future<bool> settable_future_;
+};
+
+class SetLocalDescriptionObserver
+ : public webrtc::SetLocalDescriptionObserverInterface,
+ public SetDescriptionObserverBase {
+ public:
+ void OnSetLocalDescriptionComplete(webrtc::RTCError error) override {
+ OnSetDescriptionComplete(error);
+ }
+};
+
+class SetRemoteDescriptionObserver
+ : public webrtc::SetRemoteDescriptionObserverInterface,
+ public SetDescriptionObserverBase {
+ public:
+ void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override {
+ OnSetDescriptionComplete(error);
+ }
};
using PeerConnectionState =
webrtc::PeerConnectionInterface::PeerConnectionState;
-} // namespace
-
std::unique_ptr<ConnectionFlow> ConnectionFlow::Create(
LocalIceCandidateListener local_ice_candidate_listener,
DataChannelListener data_channel_listener, WebRtcMedium& webrtc_medium) {
@@ -100,147 +132,222 @@ ConnectionFlow::ConnectionFlow(
LocalIceCandidateListener local_ice_candidate_listener,
DataChannelListener data_channel_listener)
: data_channel_listener_(std::move(data_channel_listener)),
- peer_connection_observer_(this, std::move(local_ice_candidate_listener)) {
-}
+ local_ice_candidate_listener_(std::move(local_ice_candidate_listener)) {}
-ConnectionFlow::~ConnectionFlow() { Close(); }
-
-ConnectionFlow::State ConnectionFlow::GetState() {
- MutexLock lock(&mutex_);
- return state_;
+ConnectionFlow::~ConnectionFlow() {
+ NEARBY_LOG(INFO, "~ConnectionFlow");
+ RunOnSignalingThread([this] { CloseOnSignalingThread(); });
+ shutdown_latch_.Await();
+ NEARBY_LOG(INFO, "~ConnectionFlow done");
}
SessionDescriptionWrapper ConnectionFlow::CreateOffer() {
- MutexLock lock(&mutex_);
-
- if (!TransitionState(State::kInitialized, State::kCreatingOffer)) {
+ CHECK(!IsRunningOnSignalingThread());
+ Future<SessionDescriptionWrapper> success_future;
+ if (!RunOnSignalingThread([this, success_future] {
+ CreateOfferOnSignalingThread(success_future);
+ })) {
+ NEARBY_LOG(ERROR, "Failed to create offer");
return SessionDescriptionWrapper();
}
+ ExceptionOr<SessionDescriptionWrapper> result = success_future.Get(kTimeout);
+ if (result.ok()) {
+ return std::move(result.result());
+ }
+ NEARBY_LOG(ERROR, "Failed to create offer: %d", result.exception());
+ return SessionDescriptionWrapper();
+}
+void ConnectionFlow::CreateOfferOnSignalingThread(
+ Future<SessionDescriptionWrapper> success_future) {
+ if (!TransitionState(State::kInitialized, State::kCreatingOffer)) {
+ success_future.SetException({Exception::kFailed});
+ return;
+ }
webrtc::DataChannelInit data_channel_init;
data_channel_init.reliable = true;
- rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel =
- peer_connection_->CreateDataChannel(kDataChannelName, &data_channel_init);
- data_channel->RegisterObserver(CreateDataChannelObserver(data_channel));
+ auto pc = GetPeerConnection();
+ CreateSocketFromDataChannel(
+ pc->CreateDataChannel(kDataChannelName, &data_channel_init));
- auto success_future = new Future<SessionDescriptionWrapper>();
webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options;
rtc::scoped_refptr<CreateSessionDescriptionObserverImpl> observer =
new rtc::RefCountedObject<CreateSessionDescriptionObserverImpl>(
- success_future);
- peer_connection_->CreateOffer(observer, options);
+ this, success_future, State::kCreatingOffer,
+ State::kWaitingForAnswer);
+ pc->CreateOffer(observer, options);
+}
- ExceptionOr<SessionDescriptionWrapper> result = success_future->Get(kTimeout);
- if (result.ok() &&
- TransitionState(State::kCreatingOffer, State::kWaitingForAnswer)) {
+SessionDescriptionWrapper ConnectionFlow::CreateAnswer() {
+ CHECK(!IsRunningOnSignalingThread());
+ Future<SessionDescriptionWrapper> success_future;
+ if (!RunOnSignalingThread([this, success_future] {
+ CreateAnswerOnSignalingThread(success_future);
+ })) {
+ NEARBY_LOG(ERROR, "Failed to create answer");
+ return SessionDescriptionWrapper();
+ }
+ ExceptionOr<SessionDescriptionWrapper> result = success_future.Get(kTimeout);
+ if (result.ok()) {
return std::move(result.result());
}
-
+ NEARBY_LOG(ERROR, "Failed to create answer: %d", result.exception());
return SessionDescriptionWrapper();
}
-SessionDescriptionWrapper ConnectionFlow::CreateAnswer() {
- MutexLock lock(&mutex_);
-
+void ConnectionFlow::CreateAnswerOnSignalingThread(
+ Future<SessionDescriptionWrapper> success_future) {
if (!TransitionState(State::kReceivedOffer, State::kCreatingAnswer)) {
- return SessionDescriptionWrapper();
+ success_future.SetException({Exception::kFailed});
+ return;
}
-
- auto success_future = new Future<SessionDescriptionWrapper>();
webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options;
rtc::scoped_refptr<CreateSessionDescriptionObserverImpl> observer =
new rtc::RefCountedObject<CreateSessionDescriptionObserverImpl>(
- success_future);
- peer_connection_->CreateAnswer(observer, options);
-
- ExceptionOr<SessionDescriptionWrapper> result = success_future->Get(kTimeout);
- if (result.ok() &&
- TransitionState(State::kCreatingAnswer, State::kWaitingToConnect)) {
- return std::move(result.result());
- }
-
- return SessionDescriptionWrapper();
+ this, success_future, State::kCreatingAnswer,
+ State::kWaitingToConnect);
+ auto pc = GetPeerConnection();
+ pc->CreateAnswer(observer, options);
}
bool ConnectionFlow::SetLocalSessionDescription(SessionDescriptionWrapper sdp) {
- MutexLock lock(&mutex_);
-
+ CHECK(!IsRunningOnSignalingThread());
if (!sdp.IsValid()) return false;
- auto success_future = new Future<bool>();
- rtc::scoped_refptr<SetSessionDescriptionObserverImpl> observer =
- new rtc::RefCountedObject<SetSessionDescriptionObserverImpl>(
- success_future);
+ rtc::scoped_refptr<SetLocalDescriptionObserver> observer =
+ new rtc::RefCountedObject<SetLocalDescriptionObserver>();
- peer_connection_->SetLocalDescription(observer, sdp.Release());
+ if (!RunOnSignalingThread([this, observer, sdp = std::move(sdp)]() mutable {
+ if (state_ == State::kEnded) {
+ observer->OnSetLocalDescriptionComplete(
+ webrtc::RTCError(webrtc::RTCErrorType::INVALID_STATE));
+ return;
+ }
+ auto pc = GetPeerConnection();
- ExceptionOr<bool> result = success_future->Get(kTimeout);
- return result.ok() && result.result();
+ pc->SetLocalDescription(
+ std::unique_ptr<webrtc::SessionDescriptionInterface>(sdp.Release()),
+ observer);
+ })) {
+ return false;
+ }
+
+ ExceptionOr<bool> result = observer->GetResult(kTimeout);
+ bool success = result.ok() && result.result();
+ if (!success) {
+ NEARBY_LOG(ERROR, "Failed to set local session description: %d",
+ result.exception());
+ }
+ return success;
}
-bool ConnectionFlow::SetRemoteSessionDescription(
- SessionDescriptionWrapper sdp) {
+bool ConnectionFlow::SetRemoteSessionDescription(SessionDescriptionWrapper sdp,
+ State expected_entry_state,
+ State exit_state) {
if (!sdp.IsValid()) return false;
- auto success_future = new Future<bool>();
- rtc::scoped_refptr<SetSessionDescriptionObserverImpl> observer =
- new rtc::RefCountedObject<SetSessionDescriptionObserverImpl>(
- success_future);
+ rtc::scoped_refptr<SetRemoteDescriptionObserver> observer =
+ new rtc::RefCountedObject<SetRemoteDescriptionObserver>();
- peer_connection_->SetRemoteDescription(observer, sdp.Release());
+ if (!RunOnSignalingThread([this, observer, sdp = std::move(sdp),
+ expected_entry_state, exit_state]() mutable {
+ if (!TransitionState(expected_entry_state, exit_state)) {
+ observer->OnSetRemoteDescriptionComplete(
+ webrtc::RTCError(webrtc::RTCErrorType::INVALID_STATE));
+ return;
+ }
+ auto pc = GetPeerConnection();
- ExceptionOr<bool> result = success_future->Get(kTimeout);
- return result.ok() && result.result();
+ pc->SetRemoteDescription(
+ std::unique_ptr<webrtc::SessionDescriptionInterface>(sdp.Release()),
+ observer);
+ })) {
+ return false;
+ }
+
+ ExceptionOr<bool> result = observer->GetResult(kTimeout);
+ bool success = result.ok() && result.result();
+ if (!success) {
+ NEARBY_LOG(ERROR, "Failed to set remote description: %d",
+ result.exception());
+ }
+ return success;
}
bool ConnectionFlow::OnOfferReceived(SessionDescriptionWrapper offer) {
- MutexLock lock(&mutex_);
-
- if (!TransitionState(State::kInitialized, State::kReceivedOffer)) {
- return false;
- }
- return SetRemoteSessionDescription(std::move(offer));
+ CHECK(!IsRunningOnSignalingThread());
+ return SetRemoteSessionDescription(std::move(offer), State::kInitialized,
+ State::kReceivedOffer);
}
bool ConnectionFlow::OnAnswerReceived(SessionDescriptionWrapper answer) {
- MutexLock lock(&mutex_);
+ CHECK(!IsRunningOnSignalingThread());
+ return SetRemoteSessionDescription(
+ std::move(answer), State::kWaitingForAnswer, State::kWaitingToConnect);
+}
+
+bool ConnectionFlow::OnRemoteIceCandidatesReceived(
+ std::vector<std::unique_ptr<webrtc::IceCandidateInterface>>
+ ice_candidates) {
+ CHECK(!IsRunningOnSignalingThread());
+ // We can't call RunOnSignalingThread because C++ wants to copy ice_candidates
+ // if we try. unique_ptr is not CopyConstructible and compilation fails.
+ auto pc = GetPeerConnection();
- if (!TransitionState(State::kWaitingForAnswer, State::kWaitingToConnect)) {
+ if (!pc) {
return false;
}
- return SetRemoteSessionDescription(std::move(answer));
+ pc->signaling_thread()->PostTask(
+ RTC_FROM_HERE, [this, can_run_tasks = std::weak_ptr<void>(can_run_tasks_),
+ candidates = std::move(ice_candidates)]() mutable {
+ // don't run the task if the weak_ptr is no longer valid.
+ if (!can_run_tasks.lock()) {
+ return;
+ }
+ AddIceCandidatesOnSignalingThread(std::move(candidates));
+ });
+ return true;
}
-bool ConnectionFlow::OnRemoteIceCandidatesReceived(
+void ConnectionFlow::AddIceCandidatesOnSignalingThread(
std::vector<std::unique_ptr<webrtc::IceCandidateInterface>>
ice_candidates) {
- MutexLock lock(&mutex_);
-
+ CHECK(IsRunningOnSignalingThread());
if (state_ == State::kEnded) {
NEARBY_LOG(WARNING,
"You cannot add ice candidates to a disconnected session.");
- return false;
+ return;
}
-
if (state_ != State::kWaitingToConnect && state_ != State::kConnected) {
cached_remote_ice_candidates_.insert(
cached_remote_ice_candidates_.end(),
std::make_move_iterator(ice_candidates.begin()),
std::make_move_iterator(ice_candidates.end()));
- return true;
+ return;
}
-
+ auto pc = GetPeerConnection();
for (auto&& ice_candidate : ice_candidates) {
- if (!peer_connection_->AddIceCandidate(ice_candidate.get())) {
+ if (!pc->AddIceCandidate(ice_candidate.get())) {
NEARBY_LOG(WARNING, "Unable to add remote ice candidate.");
}
}
- return true;
}
-bool ConnectionFlow::Close() {
- MutexLock lock(&mutex_);
- return CloseLocked();
+bool ConnectionFlow::CloseIfNotConnected() {
+ CHECK(!IsRunningOnSignalingThread());
+ Future<bool> closed;
+ if (RunOnSignalingThread([this, closed]() mutable {
+ if (state_ == State::kConnected) {
+ closed.Set(false);
+ } else {
+ CloseOnSignalingThread();
+ closed.Set(true);
+ }
+ })) {
+ auto result = closed.Get();
+ return result.ok() && result.result();
+ }
+ return true;
}
bool ConnectionFlow::InitPeerConnection(WebRtcMedium& webrtc_medium) {
@@ -250,7 +357,7 @@ bool ConnectionFlow::InitPeerConnection(WebRtcMedium& webrtc_medium) {
// to access, but it is not safe to access ConnectionFlow member variables
// unless the Future::Set() returns true.
webrtc_medium.CreatePeerConnection(
- &peer_connection_observer_,
+ this,
[this, success_future](rtc::scoped_refptr<webrtc::PeerConnectionInterface>
peer_connection) mutable {
if (!peer_connection) {
@@ -263,74 +370,107 @@ bool ConnectionFlow::InitPeerConnection(WebRtcMedium& webrtc_medium) {
// 1) this is the 2nd call of this callback (and this is a bug), or
// 2) Get(timeout) has set the future value as exception already.
if (success_future.IsSet()) return;
+ MutexLock lock(&mutex_);
peer_connection_ = peer_connection;
+ signaling_thread_for_dcheck_only_ =
+ peer_connection_->signaling_thread();
success_future.Set(true);
});
- ExceptionOr<bool> result = success_future.Get(kTimeout);
- return result.ok() && result.result();
+ ExceptionOr<bool> result = success_future.Get(kPeerConnectionTimeout);
+ bool success = result.ok() && result.result();
+ if (!success) {
+ shutdown_latch_.CountDown();
+ NEARBY_LOG(ERROR, "Failed to create peer connection: %d",
+ result.exception());
+ }
+ return success;
}
void ConnectionFlow::OnSignalingStable() {
- MutexLock lock(&mutex_);
-
if (state_ != State::kWaitingToConnect && state_ != State::kConnected) return;
-
+ auto pc = GetPeerConnection();
for (auto&& ice_candidate : cached_remote_ice_candidates_) {
- if (!peer_connection_->AddIceCandidate(ice_candidate.get())) {
+ if (!pc->AddIceCandidate(ice_candidate.get())) {
NEARBY_LOG(WARNING, "Unable to add remote ice candidate.");
}
}
cached_remote_ice_candidates_.clear();
}
-void ConnectionFlow::ProcessOnPeerConnectionChange(
- webrtc::PeerConnectionInterface::PeerConnectionState new_state) {
- if (new_state == PeerConnectionState::kClosed ||
- new_state == PeerConnectionState::kFailed ||
- new_state == PeerConnectionState::kDisconnected) {
- Close();
+void ConnectionFlow::CreateSocketFromDataChannel(
+ rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel) {
+ NEARBY_LOG(INFO, "Creating data channel socket");
+ auto socket =
+ std::make_unique<WebRtcSocket>("WebRtcSocket", std::move(data_channel));
+ socket->SetSocketListener({
+ .socket_ready_cb = {[this](WebRtcSocket* socket) {
+ CHECK(IsRunningOnSignalingThread());
+ if (!TransitionState(State::kWaitingToConnect, State::kConnected)) {
+ NEARBY_LOG(ERROR,
+ "Data channel socket is open but connection flow was not "
+ "in the required state");
+ socket->Close();
+ return;
+ }
+ // Pass socket wrapper by copy on purpose
+ data_channel_listener_.data_channel_open_cb(socket_wrapper_);
+ }},
+ .socket_closed_cb = [callback =
+ data_channel_listener_.data_channel_closed_cb](
+ WebRtcSocket*) { callback(); },
+ });
+ socket_wrapper_ = WebRtcSocketWrapper(std::move(socket));
+}
+
+void ConnectionFlow::OnIceCandidate(
+ const webrtc::IceCandidateInterface* candidate) {
+ CHECK(IsRunningOnSignalingThread());
+ local_ice_candidate_listener_.local_ice_candidate_found_cb(candidate);
+}
+
+void ConnectionFlow::OnSignalingChange(
+ webrtc::PeerConnectionInterface::SignalingState new_state) {
+ NEARBY_LOG(INFO, "OnSignalingChange: %d", new_state);
+ CHECK(IsRunningOnSignalingThread());
+ if (new_state == webrtc::PeerConnectionInterface::SignalingState::kStable) {
+ OnSignalingStable();
}
}
-void ConnectionFlow::ProcessDataChannelConnected(
+void ConnectionFlow::OnDataChannel(
rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel) {
- MutexLock lock(&mutex_);
- NEARBY_LOG(INFO, "Data channel state changed to connected.");
- if (!TransitionState(State::kWaitingToConnect, State::kConnected)) {
- data_channel->Close();
- return;
- }
+ NEARBY_LOG(INFO, "OnDataChannel");
+ CHECK(IsRunningOnSignalingThread());
+ CreateSocketFromDataChannel(std::move(data_channel));
+}
- data_channel_listener_.data_channel_created_cb(std::move(data_channel));
+void ConnectionFlow::OnIceGatheringChange(
+ webrtc::PeerConnectionInterface::IceGatheringState new_state) {
+ NEARBY_LOG(INFO, "OnIceGatheringChange: %d", new_state);
+ CHECK(IsRunningOnSignalingThread());
}
-webrtc::DataChannelObserver* ConnectionFlow::CreateDataChannelObserver(
- rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel) {
- if (!data_channel_observer_) {
- auto state_change_callback = [this,
- data_channel{std::move(data_channel)}]() {
- if (data_channel->state() ==
- webrtc::DataChannelInterface::DataState::kOpen) {
- OffloadFromSignalingThread(
- [this, data_channel{std::move(data_channel)}]() {
- ProcessDataChannelConnected(std::move(data_channel));
- });
- } else if (data_channel->state() ==
- webrtc::DataChannelInterface::DataState::kClosed) {
- data_channel->UnregisterObserver();
- data_channel_listener_.data_channel_closed_cb();
- }
- };
- data_channel_observer_ = absl::make_unique<DataChannelObserverImpl>(
- &data_channel_listener_, std::move(state_change_callback));
+void ConnectionFlow::OnConnectionChange(
+ webrtc::PeerConnectionInterface::PeerConnectionState new_state) {
+ NEARBY_LOG(INFO, "OnConnectionChange: %d", new_state);
+ CHECK(IsRunningOnSignalingThread());
+ if (new_state == PeerConnectionState::kClosed ||
+ new_state == PeerConnectionState::kFailed ||
+ new_state == PeerConnectionState::kDisconnected) {
+ NEARBY_LOG(INFO, "Closing due to peer connection state change: %d",
+ new_state);
+ CloseOnSignalingThread();
}
+}
- return reinterpret_cast<webrtc::DataChannelObserver*>(
- data_channel_observer_.get());
+void ConnectionFlow::OnRenegotiationNeeded() {
+ NEARBY_LOG(INFO, "OnRenegotiationNeeded");
+ CHECK(IsRunningOnSignalingThread());
}
bool ConnectionFlow::TransitionState(State current_state, State new_state) {
+ CHECK(IsRunningOnSignalingThread());
if (current_state != state_) {
NEARBY_LOG(
WARNING,
@@ -338,31 +478,79 @@ bool ConnectionFlow::TransitionState(State current_state, State new_state) {
new_state, state_, current_state);
return false;
}
+ NEARBY_LOG(INFO, "Transition: %d -> %d", state_, new_state);
state_ = new_state;
return true;
}
-bool ConnectionFlow::CloseLocked() {
- NEARBY_LOG(INFO, "Closing WebRTC connection.");
+bool ConnectionFlow::CloseOnSignalingThread() {
if (state_ == State::kEnded) {
return false;
}
state_ = State::kEnded;
+ // This prevents other tasks from queuing on the signaling thread for this
+ // object.
+ auto pc = GetAndResetPeerConnection();
+
+ NEARBY_LOG(INFO, "Closing WebRTC peer connection.");
+ // NOTE: Closing the peer conection will close the data channel and thus the
+ // socket implicitly.
+ if (pc) pc->Close();
+ NEARBY_LOG(INFO, "Closed WebRTC peer connection.");
+ // Prevent any already queued tasks from running on the signaling thread
+ can_run_tasks_.reset();
+ // If anyone was waiting for shutdown to be done let them know.
+ shutdown_latch_.CountDown();
+ return true;
+}
- single_threaded_signaling_offloader_.Shutdown();
- peer_connection_observer_.DisconnectConnectionFlow();
-
- if (peer_connection_) peer_connection_->Close();
-
- data_channel_observer_.reset();
- NEARBY_LOG(INFO, "Closed WebRTC connection.");
+bool ConnectionFlow::RunOnSignalingThread(Runnable&& runnable) {
+ CHECK(!IsRunningOnSignalingThread());
+ auto pc = GetPeerConnection();
+ if (!pc) {
+ NEARBY_LOG(WARNING,
+ "Peer connection not available. Cannot schedule tasks.");
+ return false;
+ }
+ // We are off signaling thread, so we can't use peer connection's methods
+ // but we can access the signaling thread handle.
+ pc->signaling_thread()->PostTask(
+ RTC_FROM_HERE, [can_run_tasks = std::weak_ptr<void>(can_run_tasks_),
+ task = std::move(runnable)] {
+ // don't run the task if the weak_ptr is no longer valid.
+ // shared_ptr |can_run_tasks_| is destroyed on the same thread
+ // (signaling thread). This guarantees that if the weak_ptr is valid
+ // when this task starts, it will stay valid until the task ends.
+ if (!can_run_tasks.lock()) {
+ NEARBY_LOG(INFO,
+ "Peer connection already closed. Cannot run tasks.");
+ return;
+ }
+ task();
+ });
return true;
}
-void ConnectionFlow::OffloadFromSignalingThread(Runnable runnable) {
- single_threaded_signaling_offloader_.Execute(std::move(runnable));
+bool ConnectionFlow::IsRunningOnSignalingThread() {
+ return signaling_thread_for_dcheck_only_ != nullptr &&
+ signaling_thread_for_dcheck_only_ == rtc::Thread::Current();
}
+rtc::scoped_refptr<webrtc::PeerConnectionInterface>
+ConnectionFlow::GetPeerConnection() {
+ // We must use a mutex to ensure that peer connection is
+ // fully initialized.
+ // We increase the peer_connection_'s refcount to keep it
+ // alive while we use it.
+ MutexLock lock(&mutex_);
+ return peer_connection_;
+}
+
+rtc::scoped_refptr<webrtc::PeerConnectionInterface>
+ConnectionFlow::GetAndResetPeerConnection() {
+ MutexLock lock(&mutex_);
+ return std::move(peer_connection_);
+}
} // namespace mediums
} // namespace connections
} // namespace nearby
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/connection_flow.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/connection_flow.h
index f524794a733..7ac24869c9f 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/connection_flow.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/connection_flow.h
@@ -18,11 +18,11 @@
#include <memory>
#include "core/internal/mediums/webrtc/data_channel_listener.h"
-#include "core/internal/mediums/webrtc/data_channel_observer_impl.h"
#include "core/internal/mediums/webrtc/local_ice_candidate_listener.h"
-#include "core/internal/mediums/webrtc/peer_connection_observer_impl.h"
#include "core/internal/mediums/webrtc/session_description_wrapper.h"
+#include "core/internal/mediums/webrtc/webrtc_socket_wrapper.h"
#include "platform/base/runnable.h"
+#include "platform/public/count_down_latch.h"
#include "platform/public/single_thread_executor.h"
#include "platform/public/webrtc.h"
#include "webrtc/api/data_channel_interface.h"
@@ -66,7 +66,7 @@ namespace mediums {
* previous states if we disconnect at any point in the flow.
* </ul>
*/
-class ConnectionFlow {
+class ConnectionFlow : public webrtc::PeerConnectionObserver {
public:
enum class State {
kInitialized,
@@ -80,90 +80,149 @@ class ConnectionFlow {
};
// This method blocks on the creation of the peer connection object.
+ // Can be called on any thread but never called on signaling thread.
static std::unique_ptr<ConnectionFlow> Create(
LocalIceCandidateListener local_ice_candidate_listener,
DataChannelListener data_channel_listener, WebRtcMedium& webrtc_medium);
- ~ConnectionFlow();
-
- // Returns the current state of the ConnectionFlow.
- State GetState() ABSL_LOCKS_EXCLUDED(mutex_);
+ ~ConnectionFlow() override;
// Create the offer that will be sent to the remote. Mirrors the behaviour of
// PeerConnectionInterface::CreateOffer.
+ // Can be called on any thread but never called on signaling thread.
SessionDescriptionWrapper CreateOffer() ABSL_LOCKS_EXCLUDED(mutex_);
// Create the answer that will be sent to the remote. Mirrors the behaviour of
// PeerConnectionInterface::CreateAnswer.
+ // Can be called on any thread but never called on signaling thread.
SessionDescriptionWrapper CreateAnswer() ABSL_LOCKS_EXCLUDED(mutex_);
// Set the local session description. |sdp| was created via CreateOffer()
// or CreateAnswer().
+ // Can be called on any thread but never called on signaling thread.
bool SetLocalSessionDescription(SessionDescriptionWrapper sdp)
ABSL_LOCKS_EXCLUDED(mutex_);
// Invoked when an offer was received from a remote; this will set the remote
// session description on the peer connection. Returns true if the offer was
// successfully set as remote session description.
+ // Can be called on any thread but never called on signaling thread.
bool OnOfferReceived(SessionDescriptionWrapper offer)
ABSL_LOCKS_EXCLUDED(mutex_);
// Invoked when an answer was received from a remote; this will set the remote
// session description on the peer connection. Returns true if the offer was
// successfully set as remote session description.
+ // Can be called on any thread but never called on signaling thread.
bool OnAnswerReceived(SessionDescriptionWrapper answer)
ABSL_LOCKS_EXCLUDED(mutex_);
// Invoked when an ice candidate was received from a remote; this will add the
// ice candidate to the peer connection if ready or cache it otherwise.
+ // Can be called on any thread but never called on signaling thread.
bool OnRemoteIceCandidatesReceived(
std::vector<std::unique_ptr<webrtc::IceCandidateInterface>>
ice_candidates) ABSL_LOCKS_EXCLUDED(mutex_);
- // Close the peer connection and data channel.
- bool Close() ABSL_LOCKS_EXCLUDED(mutex_);
-
- // Invoked when the peer connection indicates that signaling is stable.
- void OnSignalingStable() ABSL_LOCKS_EXCLUDED(mutex_);
- webrtc::DataChannelObserver* CreateDataChannelObserver(
- rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel);
-
- // Invoked upon changes in the state of peer connection, e.g. react to
- // disconnect.
- void ProcessOnPeerConnectionChange(
- webrtc::PeerConnectionInterface::PeerConnectionState new_state)
- ABSL_LOCKS_EXCLUDED(mutex_);
+ // Close the peer connection and data channel if not connected.
+ // Can be called on any thread but never called on signaling thread.
+ bool CloseIfNotConnected() ABSL_LOCKS_EXCLUDED(mutex_);
+
+ // webrtc::PeerConnectionObserver:
+ // All methods called only on signaling thread.
+ void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override;
+ void OnSignalingChange(
+ webrtc::PeerConnectionInterface::SignalingState new_state) override;
+ void OnDataChannel(
+ rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel) override;
+ void OnIceGatheringChange(
+ webrtc::PeerConnectionInterface::IceGatheringState new_state) override;
+ void OnConnectionChange(
+ webrtc::PeerConnectionInterface::PeerConnectionState new_state) override;
+ void OnRenegotiationNeeded() override;
+
+ // Public because it's used in tests too.
+ rtc::scoped_refptr<webrtc::PeerConnectionInterface> GetPeerConnection();
private:
ConnectionFlow(LocalIceCandidateListener local_ice_candidate_listener,
DataChannelListener data_channel_listener);
+ // Resets peer connection reference. Returns old value.
+ rtc::scoped_refptr<webrtc::PeerConnectionInterface>
+ GetAndResetPeerConnection();
+ void CreateOfferOnSignalingThread(
+ Future<SessionDescriptionWrapper> success_future);
+ void CreateAnswerOnSignalingThread(
+ Future<SessionDescriptionWrapper> success_future);
+ void AddIceCandidatesOnSignalingThread(
+ std::vector<std::unique_ptr<webrtc::IceCandidateInterface>>
+ ice_candidates);
+ // Invoked when the peer connection indicates that signaling is stable.
+ void OnSignalingStable() ABSL_LOCKS_EXCLUDED(mutex_);
+
+ void CreateSocketFromDataChannel(
+ rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel);
+
// TODO(bfranz): Consider whether this needs to be configurable per platform
static constexpr absl::Duration kTimeout = absl::Milliseconds(250);
+ static constexpr absl::Duration kPeerConnectionTimeout =
+ absl::Milliseconds(2500);
bool InitPeerConnection(WebRtcMedium& webrtc_medium);
- bool TransitionState(State current_state, State new_state)
- ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
+ bool TransitionState(State current_state, State new_state);
- bool SetRemoteSessionDescription(SessionDescriptionWrapper sdp);
+ bool SetRemoteSessionDescription(SessionDescriptionWrapper sdp,
+ State expected_entry_state,
+ State exit_state);
- void ProcessDataChannelConnected(
- rtc::scoped_refptr<webrtc::DataChannelInterface>)
- ABSL_LOCKS_EXCLUDED(mutex_);
-
- void CloseAndNotifyLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
- bool CloseLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
+ bool CloseOnSignalingThread() ABSL_LOCKS_EXCLUDED(mutex_);
- void OffloadFromSignalingThread(Runnable runnable);
+ bool RunOnSignalingThread(Runnable&& runnable);
+ bool IsRunningOnSignalingThread();
Mutex mutex_;
+ // Used to prevent the destructor from returning while the signaling thread is
+ // still running CloseOnSignalingThread()
+ CountDownLatch shutdown_latch_{1};
- State state_ ABSL_GUARDED_BY(mutex_) = State::kInitialized;
+ // State is used on signaling thread only.
+ State state_ = State::kInitialized;
+ // Used to communicate data channel events back to the caller of Create()
DataChannelListener data_channel_listener_;
- std::unique_ptr<DataChannelObserverImpl> data_channel_observer_;
-
- PeerConnectionObserverImpl peer_connection_observer_;
- rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
+ LocalIceCandidateListener local_ice_candidate_listener_;
+ // Peer connection can be used only on signaling thread. The only exception
+ // is accessing the signaling thread handle. Tasks posted on the
+ // signaling thread may outlive both |peer_connection_| and |this| objects.
+ // A mutex is required to access peer connection reference because peer
+ // connection object and the reference can be initialized on different
+ // threads - the reference could be initialized before peer connection's
+ // constructor has finished.
+ // |peer_connection_| is actually implemented by PeerConnectionProxy, which
+ // runs the real PeerConnection's methods on the correct thread (signaling or
+ // worker). If a proxy method is called on the correct thread, then the real
+ // method is called directly. Otherwise, a task is posted on the correct
+ // thread and the current thread is blocked until that task finishes. We
+ // choose to explicitly use |peer_connection_| on the signaling thread,
+ // because it allows us to do state management on the signaling thread too,
+ // simplifies locking, and we don't have to block the current thread for every
+ // peer connection call.
+ rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_
+ ABSL_GUARDED_BY(mutex_);
+
+ // Used to hold a reference to the WebRtcSocket while the data channel is
+ // connecting.
+ WebRtcSocketWrapper socket_wrapper_;
std::vector<std::unique_ptr<webrtc::IceCandidateInterface>>
- cached_remote_ice_candidates_ ABSL_GUARDED_BY(mutex_);
-
- SingleThreadExecutor single_threaded_signaling_offloader_;
+ cached_remote_ice_candidates_;
+ // This pointer is only for DCHECK() assertions.
+ // It allows us to check if we are running on signaling thread even
+ // after destroying |peer_connection_|.
+ const void* signaling_thread_for_dcheck_only_ = nullptr;
+ // This shared_ptr is reset on the signaling thread when ConnectionFlow is
+ // closed. This prevents us from running tasks on the signaling thread when
+ // peer connection is closed. The value stored in |can_run_tasks_| is not
+ // used. We are using std::shared_ptr instead of rtc::WeakPtrFactory because
+ // the former is thread-safe.
+ std::shared_ptr<void> can_run_tasks_ = std::make_shared<int>();
+
+ friend class CreateSessionDescriptionObserverImpl;
};
} // namespace mediums
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/connection_flow_test.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/connection_flow_test.cc
index c29d7577b95..04bf9f1fbdb 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/connection_flow_test.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/connection_flow_test.cc
@@ -18,8 +18,10 @@
#include <vector>
#include "core/internal/mediums/webrtc/session_description_wrapper.h"
+#include "core/internal/mediums/webrtc/webrtc_socket_wrapper.h"
#include "platform/base/byte_array.h"
#include "platform/base/medium_environment.h"
+#include "platform/public/count_down_latch.h"
#include "platform/public/webrtc.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@@ -57,10 +59,7 @@ TEST_F(ConnectionFlowTest, SuccessfulOfferAnswerFlow) {
Future<ByteArray> message_received_future;
- Future<rtc::scoped_refptr<webrtc::DataChannelInterface>>
- offerer_data_channel_future;
- Future<rtc::scoped_refptr<webrtc::DataChannelInterface>>
- answerer_data_channel_future;
+ Future<WebRtcSocketWrapper> offerer_socket_future, answerer_socket_future;
std::unique_ptr<ConnectionFlow> offerer, answerer;
@@ -75,10 +74,9 @@ TEST_F(ConnectionFlowTest, SuccessfulOfferAnswerFlow) {
if (answerer)
answerer->OnRemoteIceCandidatesReceived(std::move(vec));
}},
- {.data_channel_created_cb =
- [&offerer_data_channel_future](
- rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel) {
- offerer_data_channel_future.Set(std::move(data_channel));
+ {.data_channel_open_cb =
+ [&offerer_socket_future](WebRtcSocketWrapper socket) {
+ offerer_socket_future.Set(std::move(socket));
}},
webrtc_medium_offerer);
ASSERT_NE(offerer, nullptr);
@@ -92,14 +90,9 @@ TEST_F(ConnectionFlowTest, SuccessfulOfferAnswerFlow) {
if (offerer)
offerer->OnRemoteIceCandidatesReceived(std::move(vec));
}},
- {.data_channel_created_cb =
- [&answerer_data_channel_future](
- rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel) {
- answerer_data_channel_future.Set(std::move(data_channel));
- },
- .data_channel_message_received_cb =
- [&message_received_future](ByteArray bytes) {
- message_received_future.Set(std::move(bytes));
+ {.data_channel_open_cb =
+ [&answerer_socket_future](WebRtcSocketWrapper socket) {
+ answerer_socket_future.Set(std::move(socket));
}},
webrtc_medium_answerer);
ASSERT_NE(answerer, nullptr);
@@ -117,18 +110,19 @@ TEST_F(ConnectionFlowTest, SuccessfulOfferAnswerFlow) {
EXPECT_TRUE(answerer->SetLocalSessionDescription(std::move(answer)));
// Retrieve Data Channels
- ExceptionOr<rtc::scoped_refptr<webrtc::DataChannelInterface>>
- offerer_channel = offerer_data_channel_future.Get(absl::Seconds(1));
- EXPECT_TRUE(offerer_channel.ok());
- ExceptionOr<rtc::scoped_refptr<webrtc::DataChannelInterface>>
- answerer_channel = answerer_data_channel_future.Get(absl::Seconds(1));
- EXPECT_TRUE(answerer_channel.ok());
+ ExceptionOr<WebRtcSocketWrapper> offerer_socket =
+ offerer_socket_future.Get(absl::Seconds(1));
+ EXPECT_TRUE(offerer_socket.ok());
+ ExceptionOr<WebRtcSocketWrapper> answerer_socket =
+ answerer_socket_future.Get(absl::Seconds(1));
+ EXPECT_TRUE(answerer_socket.ok());
// Send message on data channel
const char message[] = "Test";
- offerer_channel.result()->Send(webrtc::DataBuffer(message));
+ offerer_socket.result().GetImpl().GetOutputStream().Write(
+ ByteArray(message, 4));
ExceptionOr<ByteArray> received_message =
- message_received_future.Get(absl::Seconds(1));
+ answerer_socket.result().GetImpl().GetInputStream().Read(4);
EXPECT_TRUE(received_message.ok());
EXPECT_EQ(received_message.result(), ByteArray{message});
}
@@ -173,7 +167,7 @@ TEST_F(ConnectionFlowTest, CannotCreateOfferAfterClose) {
LocalIceCandidateListener(), DataChannelListener(), webrtc_medium);
ASSERT_NE(offerer, nullptr);
- EXPECT_TRUE(offerer->Close());
+ EXPECT_TRUE(offerer->CloseIfNotConnected());
EXPECT_FALSE(offerer->CreateOffer().IsValid());
}
@@ -188,7 +182,7 @@ TEST_F(ConnectionFlowTest, CannotSetSessionDescriptionAfterClose) {
SessionDescriptionWrapper offer = offerer->CreateOffer();
EXPECT_EQ(offer.GetType(), webrtc::SdpType::kOffer);
- EXPECT_TRUE(offerer->Close());
+ EXPECT_TRUE(offerer->CloseIfNotConnected());
EXPECT_FALSE(offerer->SetLocalSessionDescription(offer));
}
@@ -205,7 +199,7 @@ TEST_F(ConnectionFlowTest, CannotReceiveOfferAfterClose) {
webrtc_medium_answerer);
ASSERT_NE(answerer, nullptr);
- EXPECT_TRUE(answerer->Close());
+ EXPECT_TRUE(answerer->CloseIfNotConnected());
SessionDescriptionWrapper offer = offerer->CreateOffer();
EXPECT_EQ(offer.GetType(), webrtc::SdpType::kOffer);
@@ -223,6 +217,179 @@ TEST_F(ConnectionFlowTest, NullPeerConnection) {
EXPECT_EQ(answerer, nullptr);
}
+TEST_F(ConnectionFlowTest, PeerConnectionTimeout) {
+ MediumEnvironment::Instance().SetUseValidPeerConnection(
+ /*use_valid_peer_connection=*/true);
+ WebRtcMedium medium1;
+ std::unique_ptr<ConnectionFlow> flow1 = ConnectionFlow::Create(
+ LocalIceCandidateListener(), DataChannelListener(), medium1);
+ EXPECT_NE(flow1, nullptr);
+
+ // Attempt to trigger the 2.5s peer connection timeout.
+ MediumEnvironment::Instance().SetPeerConnectionLatency(absl::Seconds(5));
+ WebRtcMedium medium2;
+ std::unique_ptr<ConnectionFlow> flow2 = ConnectionFlow::Create(
+ LocalIceCandidateListener(), DataChannelListener(), medium2);
+ EXPECT_EQ(flow2, nullptr);
+}
+
+TEST_F(ConnectionFlowTest, TerminateAnswerer) {
+ WebRtcMedium webrtc_medium_offerer, webrtc_medium_answerer;
+
+ Future<ByteArray> message_received_future;
+
+ Future<WebRtcSocketWrapper> offerer_socket_future, answerer_socket_future;
+
+ std::unique_ptr<ConnectionFlow> offerer, answerer;
+
+ // Send Ice Candidates immediately when you retrieve them
+ offerer = ConnectionFlow::Create(
+ {.local_ice_candidate_found_cb =
+ [&answerer](const webrtc::IceCandidateInterface* candidate) {
+ std::vector<std::unique_ptr<webrtc::IceCandidateInterface>> vec;
+ vec.push_back(CopyCandidate(candidate));
+ // The callback might be alive while the objects in test are
+ // destroyed.
+ if (answerer)
+ answerer->OnRemoteIceCandidatesReceived(std::move(vec));
+ }},
+ {.data_channel_open_cb =
+ [&offerer_socket_future](WebRtcSocketWrapper socket) {
+ offerer_socket_future.Set(std::move(socket));
+ }},
+ webrtc_medium_offerer);
+ ASSERT_NE(offerer, nullptr);
+ answerer = ConnectionFlow::Create(
+ {.local_ice_candidate_found_cb =
+ [&offerer](const webrtc::IceCandidateInterface* candidate) {
+ std::vector<std::unique_ptr<webrtc::IceCandidateInterface>> vec;
+ vec.push_back(CopyCandidate(candidate));
+ // The callback might be alive while the objects in test are
+ // destroyed.
+ if (offerer)
+ offerer->OnRemoteIceCandidatesReceived(std::move(vec));
+ }},
+ {.data_channel_open_cb =
+ [&answerer_socket_future](WebRtcSocketWrapper wrapper) {
+ answerer_socket_future.Set(std::move(wrapper));
+ }},
+ webrtc_medium_answerer);
+ ASSERT_NE(answerer, nullptr);
+
+ // Create and send offer
+ SessionDescriptionWrapper offer = offerer->CreateOffer();
+ EXPECT_EQ(offer.GetType(), webrtc::SdpType::kOffer);
+ EXPECT_TRUE(answerer->OnOfferReceived(offer));
+ EXPECT_TRUE(offerer->SetLocalSessionDescription(std::move(offer)));
+
+ // Create and send answer
+ SessionDescriptionWrapper answer = answerer->CreateAnswer();
+ EXPECT_EQ(answer.GetType(), webrtc::SdpType::kAnswer);
+ EXPECT_TRUE(offerer->OnAnswerReceived(answer));
+ EXPECT_TRUE(answerer->SetLocalSessionDescription(std::move(answer)));
+
+ // Retrieve Data Channels
+ ExceptionOr<WebRtcSocketWrapper> offerer_socket =
+ offerer_socket_future.Get(absl::Seconds(1));
+ EXPECT_TRUE(offerer_socket.ok());
+ ExceptionOr<WebRtcSocketWrapper> answerer_socket =
+ answerer_socket_future.Get(absl::Seconds(1));
+ EXPECT_TRUE(offerer_socket.ok());
+
+ CountDownLatch latch(1);
+ auto pc = answerer->GetPeerConnection();
+ pc->signaling_thread()->PostTask(RTC_FROM_HERE, [pc, latch]() mutable {
+ pc->Close();
+ latch.CountDown();
+ });
+ latch.Await();
+
+ // Send message on data channel
+ std::string message = "Test";
+ offerer_socket.result().GetOutputStream().Write(ByteArray{message});
+ ExceptionOr<ByteArray> received_message =
+ answerer_socket.result().GetInputStream().Read(4);
+ EXPECT_FALSE(received_message.ok());
+}
+
+TEST_F(ConnectionFlowTest, TerminateOfferer) {
+ WebRtcMedium webrtc_medium_offerer, webrtc_medium_answerer;
+
+ Future<ByteArray> message_received_future;
+
+ Future<WebRtcSocketWrapper> offerer_socket_future, answerer_socket_future;
+
+ std::unique_ptr<ConnectionFlow> offerer, answerer;
+
+ // Send Ice Candidates immediately when you retrieve them
+ offerer = ConnectionFlow::Create(
+ {.local_ice_candidate_found_cb =
+ [&answerer](const webrtc::IceCandidateInterface* candidate) {
+ std::vector<std::unique_ptr<webrtc::IceCandidateInterface>> vec;
+ vec.push_back(CopyCandidate(candidate));
+ // The callback might be alive while the objects in test are
+ // destroyed.
+ if (answerer)
+ answerer->OnRemoteIceCandidatesReceived(std::move(vec));
+ }},
+ {.data_channel_open_cb =
+ [&offerer_socket_future](WebRtcSocketWrapper socket) {
+ offerer_socket_future.Set(std::move(socket));
+ }},
+ webrtc_medium_offerer);
+ ASSERT_NE(offerer, nullptr);
+ answerer = ConnectionFlow::Create(
+ {.local_ice_candidate_found_cb =
+ [&offerer](const webrtc::IceCandidateInterface* candidate) {
+ std::vector<std::unique_ptr<webrtc::IceCandidateInterface>> vec;
+ vec.push_back(CopyCandidate(candidate));
+ // The callback might be alive while the objects in test are
+ // destroyed.
+ if (offerer)
+ offerer->OnRemoteIceCandidatesReceived(std::move(vec));
+ }},
+ {.data_channel_open_cb =
+ [&answerer_socket_future](WebRtcSocketWrapper wrapper) {
+ answerer_socket_future.Set(std::move(wrapper));
+ }},
+ webrtc_medium_answerer);
+ ASSERT_NE(answerer, nullptr);
+
+ // Create and send offer
+ SessionDescriptionWrapper offer = offerer->CreateOffer();
+ EXPECT_EQ(offer.GetType(), webrtc::SdpType::kOffer);
+ EXPECT_TRUE(answerer->OnOfferReceived(offer));
+ EXPECT_TRUE(offerer->SetLocalSessionDescription(std::move(offer)));
+
+ // Create and send answer
+ SessionDescriptionWrapper answer = answerer->CreateAnswer();
+ EXPECT_EQ(answer.GetType(), webrtc::SdpType::kAnswer);
+ EXPECT_TRUE(offerer->OnAnswerReceived(answer));
+ EXPECT_TRUE(answerer->SetLocalSessionDescription(std::move(answer)));
+
+ // Retrieve Data Channels
+ ExceptionOr<WebRtcSocketWrapper> offerer_socket =
+ offerer_socket_future.Get(absl::Seconds(1));
+ EXPECT_TRUE(offerer_socket.ok());
+ ExceptionOr<WebRtcSocketWrapper> answerer_socket =
+ answerer_socket_future.Get(absl::Seconds(1));
+ EXPECT_TRUE(offerer_socket.ok());
+
+ CountDownLatch latch(1);
+ auto pc = offerer->GetPeerConnection();
+ pc->signaling_thread()->PostTask(RTC_FROM_HERE, [pc, latch]() mutable {
+ pc->Close();
+ latch.CountDown();
+ });
+ latch.Await();
+
+ // Send message on data channel
+ std::string message = "Test";
+ offerer_socket.result().GetOutputStream().Write(ByteArray{message});
+ ExceptionOr<ByteArray> received_message =
+ answerer_socket.result().GetInputStream().Read(4);
+ EXPECT_FALSE(received_message.ok());
+}
} // namespace
} // namespace mediums
} // namespace connections
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/data_channel_listener.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/data_channel_listener.h
index ee4587521a9..9e2c71a9231 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/data_channel_listener.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/data_channel_listener.h
@@ -15,6 +15,7 @@
#ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_DATA_CHANNEL_LISTENER_H_
#define CORE_INTERNAL_MEDIUMS_WEBRTC_DATA_CHANNEL_LISTENER_H_
+#include "core/internal/mediums/webrtc/webrtc_socket_wrapper.h"
#include "core/listeners.h"
#include "platform/base/byte_array.h"
@@ -25,19 +26,10 @@ namespace mediums {
// Callbacks from the data channel.
struct DataChannelListener {
- // Called when the data channel is created.
- std::function<void(rtc::scoped_refptr<webrtc::DataChannelInterface>)>
- data_channel_created_cb =
- DefaultCallback<rtc::scoped_refptr<webrtc::DataChannelInterface>>();
-
- // Called when a new message was received on the data channel.
- std::function<void(const ByteArray&)> data_channel_message_received_cb =
- DefaultCallback<const ByteArray&>();
-
- // Called when the data channel indicates that the buffered amount has
- // changed.
- std::function<void()> data_channel_buffered_amount_changed_cb =
- DefaultCallback<>();
+ // Called when the data channel is open and the socket wraper is ready to
+ // read and write.
+ std::function<void(WebRtcSocketWrapper)> data_channel_open_cb =
+ DefaultCallback<WebRtcSocketWrapper>();
// Called when the data channel is closed.
std::function<void()> data_channel_closed_cb = DefaultCallback<>();
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/data_channel_observer_impl.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/data_channel_observer_impl.cc
deleted file mode 100644
index cba998d679a..00000000000
--- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/data_channel_observer_impl.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2020 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "core/internal/mediums/webrtc/data_channel_observer_impl.h"
-
-namespace location {
-namespace nearby {
-namespace connections {
-namespace mediums {
-
-DataChannelObserverImpl::DataChannelObserverImpl(
- DataChannelListener* data_channel_listener,
- DataChannelStateChangeCallback callback)
- : data_channel_listener_(data_channel_listener),
- state_change_callback_(std::move(callback)) {}
-
-void DataChannelObserverImpl::OnStateChange() { state_change_callback_(); }
-
-void DataChannelObserverImpl::OnMessage(const webrtc::DataBuffer& buffer) {
- data_channel_listener_->data_channel_message_received_cb(
- ByteArray(buffer.data.data<char>(), buffer.size()));
-}
-
-void DataChannelObserverImpl::OnBufferedAmountChange(uint64_t sent_data_size) {
- data_channel_listener_->data_channel_buffered_amount_changed_cb();
-}
-
-} // namespace mediums
-} // namespace connections
-} // namespace nearby
-} // namespace location
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/data_channel_observer_impl.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/data_channel_observer_impl.h
deleted file mode 100644
index 4de3f346b92..00000000000
--- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/data_channel_observer_impl.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2020 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_DATA_CHANNEL_OBSERVER_IMPL_H_
-#define CORE_INTERNAL_MEDIUMS_WEBRTC_DATA_CHANNEL_OBSERVER_IMPL_H_
-
-#include "core/internal/mediums/webrtc/data_channel_listener.h"
-#include "webrtc/api/data_channel_interface.h"
-
-namespace location {
-namespace nearby {
-namespace connections {
-namespace mediums {
-
-class DataChannelObserverImpl : public webrtc::DataChannelObserver {
- public:
- using DataChannelStateChangeCallback = std::function<void()>;
-
- ~DataChannelObserverImpl() override = default;
- DataChannelObserverImpl(DataChannelListener* data_channel_listener,
- DataChannelStateChangeCallback callback);
-
- // webrtc::DataChannelObserver:
- void OnStateChange() override;
- void OnMessage(const webrtc::DataBuffer& buffer) override;
- void OnBufferedAmountChange(uint64_t sent_data_size) override;
-
- private:
- DataChannelListener* data_channel_listener_;
- DataChannelStateChangeCallback state_change_callback_;
-};
-
-} // namespace mediums
-} // namespace connections
-} // namespace nearby
-} // namespace location
-
-#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_DATA_CHANNEL_OBSERVER_IMPL_H_
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/peer_connection_observer_impl.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/peer_connection_observer_impl.cc
deleted file mode 100644
index 950b2dcbf46..00000000000
--- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/peer_connection_observer_impl.cc
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2020 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "core/internal/mediums/webrtc/peer_connection_observer_impl.h"
-
-#include "core/internal/mediums/webrtc/connection_flow.h"
-#include "platform/public/logging.h"
-
-namespace location {
-namespace nearby {
-namespace connections {
-namespace mediums {
-
-PeerConnectionObserverImpl::PeerConnectionObserverImpl(
- ConnectionFlow* connection_flow,
- LocalIceCandidateListener local_ice_candidate_listener)
- : connection_flow_(connection_flow),
- local_ice_candidate_listener_(std::move(local_ice_candidate_listener)) {}
-
-PeerConnectionObserverImpl::~PeerConnectionObserverImpl() {
- MutexLock lock(&mutex_);
- connection_flow_ = nullptr;
-}
-
-void PeerConnectionObserverImpl::OnIceCandidate(
- const webrtc::IceCandidateInterface* candidate) {
- local_ice_candidate_listener_.local_ice_candidate_found_cb(candidate);
-}
-
-void PeerConnectionObserverImpl::OnSignalingChange(
- webrtc::PeerConnectionInterface::SignalingState new_state) {
- NEARBY_LOG(INFO, "OnSignalingChange: %d", new_state);
-
- OffloadFromSignalingThread([this, new_state]() {
- MutexLock lock(&mutex_);
- if (new_state == webrtc::PeerConnectionInterface::SignalingState::kStable &&
- connection_flow_) {
- connection_flow_->OnSignalingStable();
- }
- });
-}
-
-void PeerConnectionObserverImpl::OnDataChannel(
- rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel) {
- NEARBY_LOG(INFO, "OnDataChannel");
-
- webrtc::DataChannelObserver* data_channel_observer = nullptr;
- {
- MutexLock lock(&mutex_);
- if (!connection_flow_) {
- return;
- }
-
- data_channel_observer =
- connection_flow_->CreateDataChannelObserver(data_channel);
- }
- data_channel->RegisterObserver(data_channel_observer);
-}
-
-void PeerConnectionObserverImpl::OnIceGatheringChange(
- webrtc::PeerConnectionInterface::IceGatheringState new_state) {
- NEARBY_LOG(INFO, "OnIceGatheringChange: %d", new_state);
-}
-
-void PeerConnectionObserverImpl::OnConnectionChange(
- webrtc::PeerConnectionInterface::PeerConnectionState new_state) {
- NEARBY_LOG(INFO, "OnConnectionChange: %d", new_state);
-
- OffloadFromSignalingThread([this, new_state]() {
- MutexLock lock(&mutex_);
- if (connection_flow_) {
- connection_flow_->ProcessOnPeerConnectionChange(new_state);
- }
- });
-}
-
-void PeerConnectionObserverImpl ::OnRenegotiationNeeded() {
- NEARBY_LOG(INFO, "OnRenegotiationNeeded");
-}
-
-void PeerConnectionObserverImpl::DisconnectConnectionFlow() {
- MutexLock lock(&mutex_);
- connection_flow_ = nullptr;
-}
-
-void PeerConnectionObserverImpl::OffloadFromSignalingThread(Runnable runnable) {
- single_threaded_signaling_offloader_.Execute(std::move(runnable));
-}
-
-} // namespace mediums
-} // namespace connections
-} // namespace nearby
-} // namespace location
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/peer_connection_observer_impl.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/peer_connection_observer_impl.h
deleted file mode 100644
index 7bcd86b1812..00000000000
--- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/peer_connection_observer_impl.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2020 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_PEER_CONNECTION_OBSERVER_IMPL_H_
-#define CORE_INTERNAL_MEDIUMS_WEBRTC_PEER_CONNECTION_OBSERVER_IMPL_H_
-
-#include "core/internal/mediums/webrtc/local_ice_candidate_listener.h"
-#include "platform/public/single_thread_executor.h"
-#include "webrtc/api/peer_connection_interface.h"
-
-namespace location {
-namespace nearby {
-namespace connections {
-namespace mediums {
-
-class ConnectionFlow;
-
-class PeerConnectionObserverImpl : public webrtc::PeerConnectionObserver {
- public:
- PeerConnectionObserverImpl(
- ConnectionFlow* connection_flow,
- LocalIceCandidateListener local_ice_candidate_listener);
- ~PeerConnectionObserverImpl() override;
-
- // webrtc::PeerConnectionObserver:
- void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override;
- void OnSignalingChange(
- webrtc::PeerConnectionInterface::SignalingState new_state) override
- ABSL_LOCKS_EXCLUDED(mutex_);
- void OnDataChannel(
- rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel) override
- ABSL_LOCKS_EXCLUDED(mutex_);
- void OnIceGatheringChange(
- webrtc::PeerConnectionInterface::IceGatheringState new_state) override;
- void OnConnectionChange(
- webrtc::PeerConnectionInterface::PeerConnectionState new_state) override
- ABSL_LOCKS_EXCLUDED(mutex_);
- void OnRenegotiationNeeded() override;
-
- void DisconnectConnectionFlow() ABSL_LOCKS_EXCLUDED(mutex_);
-
- private:
- void OffloadFromSignalingThread(Runnable runnable);
-
- // NOTE: This must be a recursive mutex due to the call interactions.
- RecursiveMutex mutex_; // protects access to connection_flow_
- ConnectionFlow* connection_flow_ ABSL_GUARDED_BY(mutex_);
- LocalIceCandidateListener local_ice_candidate_listener_;
- SingleThreadExecutor single_threaded_signaling_offloader_;
-};
-
-} // namespace mediums
-} // namespace connections
-} // namespace nearby
-} // namespace location
-
-#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_PEER_CONNECTION_OBSERVER_IMPL_H_
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/signaling_frames_test.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/signaling_frames_test.cc
index aabd386680d..6fe8384ac09 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/signaling_frames_test.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/signaling_frames_test.cc
@@ -86,11 +86,11 @@ TEST(SignalingFramesTest, SignalingPoke) {
location::nearby::mediums::WebRtcSignalingFrame frame;
frame.ParseFromString(std::string(encoded_poke.data(), encoded_poke.size()));
- EXPECT_THAT(frame, testing::EqualsProto(R"(
+ EXPECT_THAT(frame, testing::EqualsProto(R"pb(
sender_id { id: "abc" }
type: READY_FOR_SIGNALING_POKE_TYPE
ready_for_signaling_poke {}
- )"));
+ )pb"));
}
TEST(SignalingFramesTest, EncodeValidOffer) {
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket.cc
index 1d030929838..71d80ce7fa9 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket.cc
@@ -37,6 +37,7 @@ Exception WebRtcSocket::OutputStreamImpl::Write(const ByteArray& data) {
}
if (!socket_->SendMessage(data)) {
+ NEARBY_LOG(INFO, "Unable to write data to socket.");
return {Exception::kIo};
}
return {Exception::kSuccess};
@@ -56,32 +57,89 @@ Exception WebRtcSocket::OutputStreamImpl::Close() {
WebRtcSocket::WebRtcSocket(
const std::string& name,
rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel)
- : name_(name), data_channel_(std::move(data_channel)) {}
+ : name_(name), data_channel_(std::move(data_channel)) {
+ NEARBY_LOGS(INFO) << "WebRtcSocket::WebRtcSocket(" << name_
+ << ") this: " << this;
+ data_channel_->RegisterObserver(this);
+}
+
+WebRtcSocket::~WebRtcSocket() {
+ NEARBY_LOGS(INFO) << "WebRtcSocket::~WebRtcSocket(" << name_
+ << ") this: " << this;
+ Close();
+ NEARBY_LOGS(INFO) << "WebRtcSocket::~WebRtcSocket(" << name_
+ << ") this: " << this << " done";
+}
InputStream& WebRtcSocket::GetInputStream() { return pipe_.GetInputStream(); }
OutputStream& WebRtcSocket::GetOutputStream() { return output_stream_; }
void WebRtcSocket::Close() {
+ NEARBY_LOGS(INFO) << "WebRtcSocket::Close(" << name_ << ") this: " << this;
if (closed_.Set(true)) return;
- pipe_.GetInputStream().Close();
- pipe_.GetOutputStream().Close();
+ ClosePipe();
+ // NOTE: This call blocks and triggers a state change on the siginaling thread
+ // to 'closing' but does not block until 'closed' is sent so the data channel
+ // is not fully closed when this call is done.
data_channel_->Close();
- WakeUpWriter();
- socket_closed_listener_.socket_closed_cb();
+ NEARBY_LOGS(INFO) << "WebRtcSocket::Close(" << name_ << ") this: " << this
+ << " done";
}
-void WebRtcSocket::NotifyDataChannelMsgReceived(const ByteArray& message) {
- if (!pipe_.GetOutputStream().Write(message).Ok()) {
- Close();
- return;
+void WebRtcSocket::OnStateChange() {
+ // Running on the signaling thread right now.
+ NEARBY_LOGS(ERROR)
+ << "WebRtcSocket::OnStateChange() webrtc data channel state: "
+ << webrtc::DataChannelInterface::DataStateString(data_channel_->state());
+ switch (data_channel_->state()) {
+ case webrtc::DataChannelInterface::DataState::kConnecting:
+ break;
+ case webrtc::DataChannelInterface::DataState::kOpen:
+ // We implicitly depend on the |socket_listener_| to offload from
+ // the signaling thread so it does not get blocked.
+ socket_listener_.socket_ready_cb(this);
+ break;
+ case webrtc::DataChannelInterface::DataState::kClosing:
+ break;
+ case webrtc::DataChannelInterface::DataState::kClosed:
+ NEARBY_LOG(
+ ERROR,
+ "WebRtcSocket::OnStateChange() unregistering data channel observer.");
+ data_channel_->UnregisterObserver();
+ // This will trigger a destruction of the owning connection flow
+ // We implicitly depend on the |socket_listener_| to offload from
+ // the signaling thread so it does not get blocked.
+ socket_listener_.socket_closed_cb(this);
+
+ if (!closed_.Set(true)) {
+ ClosePipe();
+ }
+ break;
}
-
- if (!pipe_.GetOutputStream().Flush().Ok()) Close();
+}
+void WebRtcSocket::OnMessage(const webrtc::DataBuffer& buffer) {
+ // This is a data channel callback on the signaling thread, lets off load so
+ // we don't block signaling.
+ OffloadFromSignalingThread(
+ [this, buffer = ByteArray(buffer.data.data<char>(), buffer.size())] {
+ if (!pipe_.GetOutputStream().Write(buffer).Ok()) {
+ Close();
+ return;
+ }
+
+ if (!pipe_.GetOutputStream().Flush().Ok()) {
+ Close();
+ }
+ });
}
-void WebRtcSocket::NotifyDataChannelBufferedAmountChanged() { WakeUpWriter(); }
+void WebRtcSocket::OnBufferedAmountChange(uint64_t sent_data_size) {
+ // This is a data channel callback on the signaling thread, lets off load so
+ // we don't block signaling.
+ OffloadFromSignalingThread([this] { WakeUpWriter(); });
+}
bool WebRtcSocket::SendMessage(const ByteArray& data) {
return data_channel_->Send(
@@ -90,13 +148,26 @@ bool WebRtcSocket::SendMessage(const ByteArray& data) {
bool WebRtcSocket::IsClosed() { return closed_.Get(); }
+void WebRtcSocket::ClosePipe() {
+ NEARBY_LOGS(INFO) << "WebRtcSocket::ClosePipe(" << name_
+ << ") this: " << this;
+ // This is thread-safe to close these sockets even if a read or write is in
+ // process on another thread, Close will wait for the exclusive mutex before
+ // setting state.
+ pipe_.GetInputStream().Close();
+ pipe_.GetOutputStream().Close();
+ WakeUpWriter();
+ NEARBY_LOGS(INFO) << "WebRtcSocket::ClosePipe(" << name_
+ << ") this: " << this << " done";
+}
+
void WebRtcSocket::WakeUpWriter() {
MutexLock lock(&backpressure_mutex_);
buffer_variable_.Notify();
}
-void WebRtcSocket::SetOnSocketClosedListener(SocketClosedListener&& listener) {
- socket_closed_listener_ = std::move(listener);
+void WebRtcSocket::SetSocketListener(SocketListener&& listener) {
+ socket_listener_ = std::move(listener);
}
void WebRtcSocket::BlockUntilSufficientSpaceInBuffer(int length) {
@@ -108,6 +179,10 @@ void WebRtcSocket::BlockUntilSufficientSpaceInBuffer(int length) {
}
}
+void WebRtcSocket::OffloadFromSignalingThread(Runnable runnable) {
+ single_thread_executor_.Execute(std::move(runnable));
+}
+
} // namespace mediums
} // namespace connections
} // namespace nearby
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket.h
index 37bf0480f0b..a65f2d5d9ed 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket.h
@@ -25,7 +25,9 @@
#include "platform/public/condition_variable.h"
#include "platform/public/mutex.h"
#include "platform/public/pipe.h"
+#include "platform/public/single_thread_executor.h"
#include "webrtc/api/data_channel_interface.h"
+
namespace location {
namespace nearby {
namespace connections {
@@ -39,11 +41,11 @@ constexpr int kMaxDataSize = 1 * 1024 * 1024;
//
// Messages are buffered here to prevent the data channel from overflowing,
// which could lead to data loss.
-class WebRtcSocket : public Socket {
+class WebRtcSocket : public Socket, public webrtc::DataChannelObserver {
public:
WebRtcSocket(const std::string& name,
rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel);
- ~WebRtcSocket() override = default;
+ ~WebRtcSocket() override;
WebRtcSocket(const WebRtcSocket& other) = delete;
WebRtcSocket& operator=(const WebRtcSocket& other) = delete;
@@ -53,20 +55,20 @@ class WebRtcSocket : public Socket {
OutputStream& GetOutputStream() override;
void Close() override;
- // Callback from WebRTC data channel when new message has been received from
- // the remote.
- void NotifyDataChannelMsgReceived(const ByteArray& message);
-
- // Callback from WebRTC data channel that the buffered data amount has
- // changed.
- void NotifyDataChannelBufferedAmountChanged();
-
- // Listener class the gets called when the socket is closed.
- struct SocketClosedListener {
- std::function<void()> socket_closed_cb = DefaultCallback<>();
+ // webrtc::DataChannelObserver:
+ void OnStateChange() override;
+ void OnMessage(const webrtc::DataBuffer& buffer) override;
+ void OnBufferedAmountChange(uint64_t sent_data_size) override;
+
+ // Listener class the gets called when the socket is ready or closed
+ struct SocketListener {
+ std::function<void(WebRtcSocket*)> socket_ready_cb =
+ DefaultCallback<WebRtcSocket*>();
+ std::function<void(WebRtcSocket*)> socket_closed_cb =
+ DefaultCallback<WebRtcSocket*>();
};
- void SetOnSocketClosedListener(SocketClosedListener&& listener);
+ void SetSocketListener(SocketListener&& listener);
private:
class OutputStreamImpl : public OutputStream {
@@ -89,8 +91,10 @@ class WebRtcSocket : public Socket {
void WakeUpWriter();
bool IsClosed();
+ void ClosePipe();
bool SendMessage(const ByteArray& data);
void BlockUntilSufficientSpaceInBuffer(int length);
+ void OffloadFromSignalingThread(Runnable runnable);
std::string name_;
rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel_;
@@ -101,10 +105,14 @@ class WebRtcSocket : public Socket {
AtomicBoolean closed_{false};
- SocketClosedListener socket_closed_listener_;
+ SocketListener socket_listener_;
mutable Mutex backpressure_mutex_;
ConditionVariable buffer_variable_{&backpressure_mutex_};
+
+ // This should be destroyed first to ensure any remaining tasks flushed on
+ // shutdown get run while the other members are still alive.
+ SingleThreadExecutor single_thread_executor_;
};
} // namespace mediums
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket_test.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket_test.cc
index 72c4e346790..7ff3886163a 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket_test.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket_test.cc
@@ -58,23 +58,23 @@ class MockDataChannel
} // namespace
TEST(WebRtcSocketTest, ReadFromSocket) {
- const ByteArray kMessage{"Message"};
+ const char* message = "message";
rtc::scoped_refptr<MockDataChannel> mock_data_channel = new MockDataChannel();
WebRtcSocket webrtc_socket(kSocketName, mock_data_channel);
- webrtc_socket.NotifyDataChannelMsgReceived(kMessage);
+ webrtc_socket.OnMessage(webrtc::DataBuffer{message});
ExceptionOr<ByteArray> result = webrtc_socket.GetInputStream().Read(7);
EXPECT_TRUE(result.ok());
- EXPECT_EQ(result.result(), kMessage);
+ EXPECT_EQ(result.result(), ByteArray{message});
}
TEST(WebRtcSocketTest, ReadMultipleMessages) {
rtc::scoped_refptr<MockDataChannel> mock_data_channel = new MockDataChannel();
WebRtcSocket webrtc_socket(kSocketName, mock_data_channel);
- webrtc_socket.NotifyDataChannelMsgReceived(ByteArray{"Me"});
- webrtc_socket.NotifyDataChannelMsgReceived(ByteArray{"ssa"});
- webrtc_socket.NotifyDataChannelMsgReceived(ByteArray{"ge"});
+ webrtc_socket.OnMessage(webrtc::DataBuffer{"Me"});
+ webrtc_socket.OnMessage(webrtc::DataBuffer{"ssa"});
+ webrtc_socket.OnMessage(webrtc::DataBuffer{"ge"});
ExceptionOr<ByteArray> result;
@@ -131,10 +131,19 @@ TEST(WebRtcSocketTest, Close) {
int socket_closed_cb_called = 0;
- webrtc_socket.SetOnSocketClosedListener(
- {.socket_closed_cb = [&]() { socket_closed_cb_called++; }});
+ webrtc_socket.SetSocketListener(
+ {.socket_closed_cb = [&](WebRtcSocket* socket) {
+ socket_closed_cb_called++;
+ }});
webrtc_socket.Close();
+ // We have to fake the close event to get the callback to run.
+ ON_CALL(*mock_data_channel, state())
+ .WillByDefault(
+ testing::Return(webrtc::DataChannelInterface::DataState::kClosed));
+
+ webrtc_socket.OnStateChange();
+
EXPECT_EQ(socket_closed_cb_called, 1);
}
@@ -162,6 +171,63 @@ TEST(WebRtcSocketTest, ReadFromClosedChannel) {
EXPECT_EQ(webrtc_socket.GetInputStream().Read(7).exception(), Exception::kIo);
}
+TEST(WebRtcSocketTest, DataChannelCloseEventCleansUp) {
+ rtc::scoped_refptr<MockDataChannel> mock_data_channel = new MockDataChannel();
+ WebRtcSocket webrtc_socket(kSocketName, mock_data_channel);
+
+ ON_CALL(*mock_data_channel, state())
+ .WillByDefault(
+ testing::Return(webrtc::DataChannelInterface::DataState::kClosed));
+
+ webrtc_socket.OnStateChange();
+
+ EXPECT_EQ(webrtc_socket.GetInputStream().Read(7).exception(), Exception::kIo);
+
+ // Calling Close again should be safe even if the channel is already shut
+ // down.
+ webrtc_socket.Close();
+}
+
+TEST(WebRtcSocketTest, OpenStateTriggersCallback) {
+ rtc::scoped_refptr<MockDataChannel> mock_data_channel = new MockDataChannel();
+ WebRtcSocket webrtc_socket(kSocketName, mock_data_channel);
+
+ int socket_ready_cb_called = 0;
+
+ webrtc_socket.SetSocketListener(
+ {.socket_ready_cb = [&](WebRtcSocket* socket) {
+ socket_ready_cb_called++;
+ }});
+
+ ON_CALL(*mock_data_channel, state())
+ .WillByDefault(
+ testing::Return(webrtc::DataChannelInterface::DataState::kOpen));
+
+ webrtc_socket.OnStateChange();
+
+ EXPECT_EQ(socket_ready_cb_called, 1);
+}
+
+TEST(WebRtcSocketTest, CloseStateTriggersCallback) {
+ rtc::scoped_refptr<MockDataChannel> mock_data_channel = new MockDataChannel();
+ WebRtcSocket webrtc_socket(kSocketName, mock_data_channel);
+
+ int socket_closed_cb_called = 0;
+
+ webrtc_socket.SetSocketListener(
+ {.socket_closed_cb = [&](WebRtcSocket* socket) {
+ socket_closed_cb_called++;
+ }});
+
+ ON_CALL(*mock_data_channel, state())
+ .WillByDefault(
+ testing::Return(webrtc::DataChannelInterface::DataState::kClosed));
+
+ webrtc_socket.OnStateChange();
+
+ EXPECT_EQ(socket_closed_cb_called, 1);
+}
+
} // namespace mediums
} // namespace connections
} // namespace nearby
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket_wrapper.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket_wrapper.h
index 67c8e2b5604..4da6151deb3 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket_wrapper.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket_wrapper.h
@@ -37,14 +37,6 @@ class WebRtcSocketWrapper final {
OutputStream& GetOutputStream() { return impl_->GetOutputStream(); }
- void NotifyDataChannelMsgReceived(const ByteArray& message) {
- impl_->NotifyDataChannelMsgReceived(message);
- }
-
- void NotifyDataChannelBufferedAmountChanged() {
- impl_->NotifyDataChannelBufferedAmountChanged();
- }
-
void Close() { return impl_->Close(); }
bool IsValid() const { return impl_ != nullptr; }
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc_test.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc_test.cc
index f37dc5a4263..1a0e9a0f283 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc_test.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc_test.cc
@@ -384,12 +384,12 @@ TEST_F(WebRtcTest, ContinueAcceptingConnectionsOnComplete) {
// Simulate a failure in receiving messages stream, WebRtc should restart
// accepting connections.
env_.SendWebRtcSignalingComplete(self_id.GetId(),
- /*success=*/false);
+ /*success=*/false);
EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id));
// And a "success" message should not cause accepting connections to stop.
env_.SendWebRtcSignalingComplete(self_id.GetId(),
- /*success=*/true);
+ /*success=*/true);
EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id));
webrtc.StopAcceptingConnections(service_id);
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/wifi_lan.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/wifi_lan.cc
index 782807f4983..cf0e5427b56 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/wifi_lan.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/mediums/wifi_lan.cc
@@ -222,7 +222,6 @@ bool WifiLan::IsAcceptingConnectionsLocked(const std::string& service_id) {
return accepting_connections_info_.Existed(service_id);
}
-// TODO(b/169303284): Handles Cancellation and registration.
WifiLanSocket WifiLan::Connect(WifiLanService& wifi_lan_service,
const std::string& service_id,
CancellationFlag* cancellation_flag) {
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/offline_frames.cc b/chromium/third_party/nearby/src/cpp/core/internal/offline_frames.cc
index af83a034f11..5ac4c920525 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/offline_frames.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/offline_frames.cc
@@ -20,7 +20,6 @@
#include "core/internal/message_lite.h"
#include "core/internal/offline_frames_validator.h"
#include "core/status.h"
-#include "proto/connections/offline_wire_formats.pb.h"
#include "platform/base/byte_array.h"
namespace location {
@@ -65,9 +64,12 @@ V1Frame::FrameType GetFrameType(const OfflineFrame& frame) {
ByteArray ForConnectionRequest(const std::string& endpoint_id,
const ByteArray& endpoint_info,
- std::int32_t nonce, bool supports_5_ghz,
+ std::int32_t nonce,
+ bool supports_5_ghz,
const std::string& bssid,
- const std::vector<Medium>& mediums) {
+ const std::vector<Medium>& mediums,
+ std::int32_t keep_alive_interval_millis,
+ std::int32_t keep_alive_timeout_millis) {
OfflineFrame frame;
frame.set_version(OfflineFrame::V1);
@@ -90,6 +92,14 @@ ByteArray ForConnectionRequest(const std::string& endpoint_id,
connection_request->add_mediums(MediumToConnectionRequestMedium(medium));
}
}
+ if (keep_alive_interval_millis > 0) {
+ connection_request->set_keep_alive_interval_millis(
+ keep_alive_interval_millis);
+ }
+ if (keep_alive_timeout_millis > 0) {
+ connection_request->set_keep_alive_timeout_millis(
+ keep_alive_timeout_millis);
+ }
return ToBytes(std::move(frame));
}
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/offline_frames.h b/chromium/third_party/nearby/src/cpp/core/internal/offline_frames.h
index b8694d74125..b50886de723 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/offline_frames.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/offline_frames.h
@@ -22,7 +22,6 @@
#include "proto/connections/offline_wire_formats.pb.h"
#include "platform/base/byte_array.h"
#include "platform/base/exception.h"
-#include "proto/connections_enums.pb.h"
namespace location {
namespace nearby {
@@ -45,9 +44,12 @@ V1Frame::FrameType GetFrameType(const OfflineFrame& offline_frame);
// Builds Connection Request / Response messages.
ByteArray ForConnectionRequest(const std::string& endpoint_id,
const ByteArray& endpoint_info,
- std::int32_t nonce, bool supports_5_ghz,
+ std::int32_t nonce,
+ bool supports_5_ghz,
const std::string& bssid,
- const std::vector<Medium>& mediums);
+ const std::vector<Medium>& mediums,
+ std::int32_t keep_alive_interval_millis,
+ std::int32_t keep_alive_timeout_millis);
ByteArray ForConnectionResponse(std::int32_t status);
// Builds Payload transfer messages.
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/offline_frames_test.cc b/chromium/third_party/nearby/src/cpp/core/internal/offline_frames_test.cc
index a64355d196f..cfe8b78762a 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/offline_frames_test.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/offline_frames_test.cc
@@ -43,6 +43,8 @@ constexpr std::array<Medium, 9> kMediums = {
Medium::BLE, Medium::WIFI_LAN, Medium::WIFI_AWARE,
Medium::NFC, Medium::WIFI_DIRECT, Medium::WEB_RTC,
};
+constexpr int kKeepAliveIntervalMillis = 1000;
+constexpr int kKeepAliveTimeoutMillis = 5000;
TEST(OfflineFramesTest, CanParseMessageFromBytes) {
OfflineFrame tx_message;
@@ -57,6 +59,8 @@ TEST(OfflineFramesTest, CanParseMessageFromBytes) {
sub_frame->set_endpoint_name(kEndpointName);
sub_frame->set_endpoint_info(kEndpointName);
sub_frame->set_nonce(kNonce);
+ sub_frame->set_keep_alive_interval_millis(kKeepAliveIntervalMillis);
+ sub_frame->set_keep_alive_timeout_millis(kKeepAliveTimeoutMillis);
auto* medium_metadata = sub_frame->mutable_medium_metadata();
medium_metadata->set_supports_5_ghz(kSupports5ghz);
@@ -101,12 +105,15 @@ TEST(OfflineFramesTest, CanGenerateConnectionRequest) {
mediums: NFC
mediums: WIFI_DIRECT
mediums: WEB_RTC
+ keep_alive_interval_millis: 1000
+ keep_alive_timeout_millis : 5000
>
>)pb";
ByteArray bytes = ForConnectionRequest(
std::string(kEndpointId), ByteArray{std::string(kEndpointName)}, kNonce,
kSupports5ghz, std::string(kBssid),
- std::vector(kMediums.begin(), kMediums.end()));
+ std::vector(kMediums.begin(), kMediums.end()), kKeepAliveIntervalMillis,
+ kKeepAliveTimeoutMillis);
auto response = FromBytes(bytes);
ASSERT_TRUE(response.ok());
OfflineFrame message = FromBytes(bytes).result();
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/offline_frames_validator.cc b/chromium/third_party/nearby/src/cpp/core/internal/offline_frames_validator.cc
index 209d206b9dd..614c65f8e63 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/offline_frames_validator.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/offline_frames_validator.cc
@@ -78,7 +78,7 @@ Exception EnsureValidConnectionResponseFrame(
}
Exception EnsureValidPayloadTransferDataFrame(const PayloadChunk& payload_chunk,
- int totalSize) {
+ std::int64_t totalSize) {
if (!payload_chunk.has_flags()) return {Exception::kInvalidProtocolBuffer};
// Special case. The body can be null iff the chunk is flagged as the last
@@ -100,7 +100,7 @@ Exception EnsureValidPayloadTransferDataFrame(const PayloadChunk& payload_chunk,
}
Exception EnsureValidPayloadTransferControlFrame(
- const ControlMessage& control_message, int totalSize) {
+ const ControlMessage& control_message, std::int64_t totalSize) {
if (!control_message.has_offset() || control_message.offset() < 0)
return {Exception::kInvalidProtocolBuffer};
if (totalSize != InternalPayload::kIndeterminateSize &&
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/offline_frames_validator_test.cc b/chromium/third_party/nearby/src/cpp/core/internal/offline_frames_validator_test.cc
index 09fecac483d..e659e86f09d 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/offline_frames_validator_test.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/offline_frames_validator_test.cc
@@ -45,6 +45,8 @@ constexpr std::array<Medium, 9> kMediums = {
Medium::BLE, Medium::WIFI_LAN, Medium::WIFI_AWARE,
Medium::NFC, Medium::WIFI_DIRECT, Medium::WEB_RTC,
};
+constexpr int kKeepAliveIntervalMillis = 1000;
+constexpr int kKeepAliveTimeoutMillis = 5000;
TEST(OfflineFramesValidatorTest, ValidatesAsOkWithValidConnectionRequestFrame) {
OfflineFrame offline_frame;
@@ -52,7 +54,8 @@ TEST(OfflineFramesValidatorTest, ValidatesAsOkWithValidConnectionRequestFrame) {
ByteArray bytes = ForConnectionRequest(
std::string(kEndpointId), ByteArray{std::string(kEndpointName)}, kNonce,
kSupports5ghz, std::string(kBssid),
- std::vector(kMediums.begin(), kMediums.end()));
+ std::vector(kMediums.begin(), kMediums.end()), kKeepAliveIntervalMillis,
+ kKeepAliveTimeoutMillis);
offline_frame.ParseFromString(std::string(bytes));
auto ret_value = EnsureValidOfflineFrame(offline_frame);
@@ -67,7 +70,8 @@ TEST(OfflineFramesValidatorTest,
ByteArray bytes = ForConnectionRequest(
std::string(kEndpointId), ByteArray{std::string(kEndpointName)}, kNonce,
kSupports5ghz, std::string(kBssid),
- std::vector(kMediums.begin(), kMediums.end()));
+ std::vector(kMediums.begin(), kMediums.end()), kKeepAliveIntervalMillis,
+ kKeepAliveTimeoutMillis);
offline_frame.ParseFromString(std::string(bytes));
auto* v1_frame = offline_frame.mutable_v1();
@@ -86,7 +90,8 @@ TEST(OfflineFramesValidatorTest,
ByteArray bytes = ForConnectionRequest(
empty_enpoint_id, ByteArray{std::string(kEndpointName)}, kNonce,
kSupports5ghz, std::string(kBssid),
- std::vector(kMediums.begin(), kMediums.end()));
+ std::vector(kMediums.begin(), kMediums.end()), kKeepAliveIntervalMillis,
+ kKeepAliveTimeoutMillis);
offline_frame.ParseFromString(std::string(bytes));
auto ret_value = EnsureValidOfflineFrame(offline_frame);
@@ -101,7 +106,8 @@ TEST(OfflineFramesValidatorTest,
ByteArray empty_endpoint_info;
ByteArray bytes = ForConnectionRequest(
std::string(kEndpointId), empty_endpoint_info, kNonce, kSupports5ghz,
- std::string(kBssid), std::vector(kMediums.begin(), kMediums.end()));
+ std::string(kBssid), std::vector(kMediums.begin(), kMediums.end()),
+ kKeepAliveIntervalMillis, kKeepAliveTimeoutMillis);
offline_frame.ParseFromString(std::string(bytes));
auto ret_value = EnsureValidOfflineFrame(offline_frame);
@@ -116,8 +122,8 @@ TEST(OfflineFramesValidatorTest,
std::string empty_bssid;
ByteArray bytes = ForConnectionRequest(
std::string(kEndpointId), ByteArray{std::string(kEndpointName)}, kNonce,
- kSupports5ghz, empty_bssid,
- std::vector(kMediums.begin(), kMediums.end()));
+ kSupports5ghz, empty_bssid, std::vector(kMediums.begin(), kMediums.end()),
+ kKeepAliveIntervalMillis, kKeepAliveTimeoutMillis);
offline_frame.ParseFromString(std::string(bytes));
auto ret_value = EnsureValidOfflineFrame(offline_frame);
@@ -132,7 +138,8 @@ TEST(OfflineFramesValidatorTest,
std::vector<Medium> empty_mediums;
ByteArray bytes = ForConnectionRequest(
std::string(kEndpointId), ByteArray{std::string(kEndpointName)}, kNonce,
- kSupports5ghz, std::string(kBssid), empty_mediums);
+ kSupports5ghz, std::string(kBssid), empty_mediums,
+ kKeepAliveIntervalMillis, kKeepAliveTimeoutMillis);
offline_frame.ParseFromString(std::string(bytes));
auto ret_value = EnsureValidOfflineFrame(offline_frame);
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/offline_simulation_user.h b/chromium/third_party/nearby/src/cpp/core/internal/offline_simulation_user.h
index d4299d02398..bbd9eb6e143 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/offline_simulation_user.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/offline_simulation_user.h
@@ -50,7 +50,15 @@ class OfflineSimulationUser {
explicit OfflineSimulationUser(
absl::string_view device_name,
BooleanMediumSelector allowed = BooleanMediumSelector())
- : info_{ByteArray{std::string(device_name)}},
+ : connection_options_{
+ .keep_alive_interval_millis = FeatureFlags::GetInstance()
+ .GetFlags()
+ .keep_alive_interval_millis,
+ .keep_alive_timeout_millis = FeatureFlags::GetInstance()
+ .GetFlags()
+ .keep_alive_timeout_millis,
+ },
+ info_{ByteArray{std::string(device_name)}},
options_{
.strategy = Strategy::kP2pCluster,
.allowed = allowed,
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/p2p_cluster_pcp_handler.cc b/chromium/third_party/nearby/src/cpp/core/internal/p2p_cluster_pcp_handler.cc
index f8cef073a1f..de793744635 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/p2p_cluster_pcp_handler.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/p2p_cluster_pcp_handler.cc
@@ -206,155 +206,168 @@ bool P2pClusterPcpHandler::IsRecognizedBluetoothEndpoint(
void P2pClusterPcpHandler::BluetoothDeviceDiscoveredHandler(
ClientProxy* client, const std::string& service_id,
BluetoothDevice device) {
- RunOnPcpHandlerThread([this, client, service_id,
- device]() RUN_ON_PCP_HANDLER_THREAD() {
- // Make sure we are still discovering before proceeding.
- if (!client->IsDiscovering()) {
- NEARBY_LOG(INFO,
- "BT discovery handler (FOUND) [client=%p, service=%s]: not "
- "in discovery mode",
- client, service_id.c_str());
- return;
- }
+ RunOnPcpHandlerThread(
+ "p2p-bt-device-discovered",
+ [this, client, service_id, device]()
+ RUN_ON_PCP_HANDLER_THREAD() {
+ // Make sure we are still discovering before proceeding.
+ if (!client->IsDiscovering()) {
+ NEARBY_LOG(
+ INFO,
+ "BT discovery handler (FOUND) [client=%p, service=%s]: not "
+ "in discovery mode",
+ client, service_id.c_str());
+ return;
+ }
- // Parse the Bluetooth device name.
- const std::string device_name_string = device.GetName();
- BluetoothDeviceName device_name(device_name_string);
+ // Parse the Bluetooth device name.
+ const std::string device_name_string = device.GetName();
+ BluetoothDeviceName device_name(device_name_string);
- // Make sure the Bluetooth device name points to a valid
- // endpoint we're discovering.
- if (!IsRecognizedBluetoothEndpoint(device_name_string, service_id,
- device_name))
- return;
+ // Make sure the Bluetooth device name points to a valid
+ // endpoint we're discovering.
+ if (!IsRecognizedBluetoothEndpoint(device_name_string, service_id,
+ device_name))
+ return;
- // Report the discovered endpoint to the client.
- NEARBY_LOGS(INFO)
- << "Invoking BasePcpHandler::OnEndpointFound() for BT service="
- << service_id << "; id=" << device_name.GetEndpointId() << "; name="
- << absl::BytesToHexString(device_name.GetEndpointInfo().data());
- OnEndpointFound(
- client, std::make_shared<BluetoothEndpoint>(BluetoothEndpoint{
+ // Report the discovered endpoint to the client.
+ NEARBY_LOGS(INFO)
+ << "Invoking BasePcpHandler::OnEndpointFound() for BT service="
+ << service_id << "; id=" << device_name.GetEndpointId()
+ << "; name="
+ << absl::BytesToHexString(device_name.GetEndpointInfo().data());
+ OnEndpointFound(
+ client,
+ std::make_shared<BluetoothEndpoint>(BluetoothEndpoint{
{device_name.GetEndpointId(), device_name.GetEndpointInfo(),
service_id, proto::connections::Medium::BLUETOOTH,
device_name.GetWebRtcState()},
device,
}));
- });
+ });
}
void P2pClusterPcpHandler::BluetoothNameChangedHandler(
ClientProxy* client, const std::string& service_id,
BluetoothDevice device) {
- RunOnPcpHandlerThread([this, client, service_id,
- device]() RUN_ON_PCP_HANDLER_THREAD() {
- // Make sure we are still discovering before proceeding.
- if (!client->IsDiscovering()) {
- NEARBY_LOG(INFO,
- "BT discovery handler (CHANGED) [client=%p, service=%s]: not "
- "in discovery mode",
- client, service_id.c_str());
- return;
- }
-
- // Parse the Bluetooth device name.
- const std::string device_name_string = device.GetName();
- BluetoothDeviceName device_name(device_name_string);
- NEARBY_LOG(INFO,
- "BT discovery handler (CHANGED) [client=%p, service=%s]: "
- "processing new name %s",
- client, service_id.c_str(), device_name_string.c_str());
-
- // By this point, the BluetoothDevice passed to us has a different name than
- // what we may have discovered before. We need to iterate over the found
- // BluetoothEndpoints and compare their addresses to see the devices are the
- // same. We are not guaranteed to discover a match, since the old name may
- // not have been formatted for Nearby Connections.
- for (auto endpoint :
- GetDiscoveredEndpoints(proto::connections::Medium::BLUETOOTH)) {
- BluetoothEndpoint* bluetoothEndpoint =
- static_cast<BluetoothEndpoint*>(endpoint);
- NEARBY_LOG(INFO,
- "BT discovery handler (CHANGED) [client=%p, service=%s]: "
- "comparing MAC addresses with existing endpoint %s. They have "
- "MAC address %s and the new endpoint has MAC address %s.",
- client, service_id.c_str(),
- bluetoothEndpoint->bluetooth_device.GetName().c_str(),
- bluetoothEndpoint->bluetooth_device.GetMacAddress().c_str(),
- device.GetMacAddress().c_str());
- if (bluetoothEndpoint->bluetooth_device.GetMacAddress() ==
- device.GetMacAddress()) {
- // Report the BluetoothEndpoint as lost to the client.
- NEARBY_LOG(
- INFO,
- "BT discovery handler (LOST) [client=%p, service=%s]: report "
- "to client",
- client, service_id.c_str());
- OnEndpointLost(client, *endpoint);
- break;
- }
- }
-
- // Make sure the Bluetooth device name points to a valid
- // endpoint we're discovering.
- if (!IsRecognizedBluetoothEndpoint(device_name_string, service_id,
- device_name)) {
- NEARBY_LOG(INFO,
- "BT discovery handler (CHANGED) [client=%p, service=%s]: The "
- "new name is not recognized. Ignoring.",
- client, service_id.c_str());
- return;
- }
-
- // Report the discovered endpoint to the client.
- NEARBY_LOGS(INFO)
- << "Invoking BasePcpHandler::OnEndpointFound() for BT service="
- << service_id << "; id=" << device_name.GetEndpointId() << "; name="
- << absl::BytesToHexString(device_name.GetEndpointInfo().data());
- OnEndpointFound(
- client, std::make_shared<BluetoothEndpoint>(BluetoothEndpoint{
- {device_name.GetEndpointId(), device_name.GetEndpointInfo(),
- service_id, proto::connections::Medium::BLUETOOTH,
- device_name.GetWebRtcState()},
- device,
- }));
- });
+ RunOnPcpHandlerThread(
+ "p2p-bt-name-changed",
+ [this, client, service_id, device]() RUN_ON_PCP_HANDLER_THREAD() {
+ // Make sure we are still discovering before proceeding.
+ if (!client->IsDiscovering()) {
+ NEARBY_LOG(
+ INFO,
+ "BT discovery handler (CHANGED) [client=%p, service=%s]: not "
+ "in discovery mode",
+ client, service_id.c_str());
+ return;
+ }
+
+ // Parse the Bluetooth device name.
+ const std::string device_name_string = device.GetName();
+ BluetoothDeviceName device_name(device_name_string);
+ NEARBY_LOG(INFO,
+ "BT discovery handler (CHANGED) [client=%p, service=%s]: "
+ "processing new name %s",
+ client, service_id.c_str(), device_name_string.c_str());
+
+ // By this point, the BluetoothDevice passed to us has a different name
+ // than what we may have discovered before. We need to iterate over the
+ // found BluetoothEndpoints and compare their addresses to see the
+ // devices are the same. We are not guaranteed to discover a match,
+ // since the old name may not have been formatted for Nearby
+ // Connections.
+ for (auto endpoint :
+ GetDiscoveredEndpoints(proto::connections::Medium::BLUETOOTH)) {
+ BluetoothEndpoint* bluetoothEndpoint =
+ static_cast<BluetoothEndpoint*>(endpoint);
+ NEARBY_LOG(
+ INFO,
+ "BT discovery handler (CHANGED) [client=%p, service=%s]: "
+ "comparing MAC addresses with existing endpoint %s. They have "
+ "MAC address %s and the new endpoint has MAC address %s.",
+ client, service_id.c_str(),
+ bluetoothEndpoint->bluetooth_device.GetName().c_str(),
+ bluetoothEndpoint->bluetooth_device.GetMacAddress().c_str(),
+ device.GetMacAddress().c_str());
+ if (bluetoothEndpoint->bluetooth_device.GetMacAddress() ==
+ device.GetMacAddress()) {
+ // Report the BluetoothEndpoint as lost to the client.
+ NEARBY_LOG(
+ INFO,
+ "BT discovery handler (LOST) [client=%p, service=%s]: report "
+ "to client",
+ client, service_id.c_str());
+ OnEndpointLost(client, *endpoint);
+ break;
+ }
+ }
+
+ // Make sure the Bluetooth device name points to a valid
+ // endpoint we're discovering.
+ if (!IsRecognizedBluetoothEndpoint(device_name_string, service_id,
+ device_name)) {
+ NEARBY_LOG(
+ INFO,
+ "BT discovery handler (CHANGED) [client=%p, service=%s]: The "
+ "new name is not recognized. Ignoring.",
+ client, service_id.c_str());
+ return;
+ }
+
+ // Report the discovered endpoint to the client.
+ NEARBY_LOGS(INFO)
+ << "Invoking BasePcpHandler::OnEndpointFound() for BT service="
+ << service_id << "; id=" << device_name.GetEndpointId() << "; name="
+ << absl::BytesToHexString(device_name.GetEndpointInfo().data());
+ OnEndpointFound(
+ client,
+ std::make_shared<BluetoothEndpoint>(BluetoothEndpoint{
+ {device_name.GetEndpointId(), device_name.GetEndpointInfo(),
+ service_id, proto::connections::Medium::BLUETOOTH,
+ device_name.GetWebRtcState()},
+ device,
+ }));
+ });
}
void P2pClusterPcpHandler::BluetoothDeviceLostHandler(
ClientProxy* client, const std::string& service_id,
BluetoothDevice& device) {
const std::string& device_name_string = device.GetName();
- RunOnPcpHandlerThread([this, client, service_id,
- device_name_string]() RUN_ON_PCP_HANDLER_THREAD() {
- // Make sure we are still discovering before proceeding.
- if (!client->IsDiscovering()) {
- NEARBY_LOG(INFO,
- "BT discovery handler (LOST) [client=%p, service=%s]: not "
- "in discovery mode",
- client, service_id.c_str());
- return;
- }
+ RunOnPcpHandlerThread(
+ "p2p-bt-device-lost", [this, client, service_id,
+ device_name_string]() RUN_ON_PCP_HANDLER_THREAD() {
+ // Make sure we are still discovering before proceeding.
+ if (!client->IsDiscovering()) {
+ NEARBY_LOG(INFO,
+ "BT discovery handler (LOST) [client=%p, service=%s]: not "
+ "in discovery mode",
+ client, service_id.c_str());
+ return;
+ }
+
+ // Parse the Bluetooth device name.
+ BluetoothDeviceName device_name(device_name_string);
+
+ // Make sure the Bluetooth device name points to a valid
+ // endpoint we're discovering.
+ if (!IsRecognizedBluetoothEndpoint(device_name_string, service_id,
+ device_name))
+ return;
- // Parse the Bluetooth device name.
- BluetoothDeviceName device_name(device_name_string);
-
- // Make sure the Bluetooth device name points to a valid
- // endpoint we're discovering.
- if (!IsRecognizedBluetoothEndpoint(device_name_string, service_id,
- device_name))
- return;
-
- // Report the BluetoothEndpoint as lost to the client.
- NEARBY_LOG(INFO,
- "BT discovery handler (LOST) [client=%p, service=%s]: report "
- "to client",
- client, service_id.c_str());
- OnEndpointLost(client,
- DiscoveredEndpoint{device_name.GetEndpointId(),
- device_name.GetEndpointInfo(), service_id,
- proto::connections::Medium::BLUETOOTH,
- WebRtcState::kUndefined});
- });
+ // Report the BluetoothEndpoint as lost to the client.
+ NEARBY_LOG(
+ INFO,
+ "BT discovery handler (LOST) [client=%p, service=%s]: report "
+ "to client",
+ client, service_id.c_str());
+ OnEndpointLost(client, DiscoveredEndpoint{
+ device_name.GetEndpointId(),
+ device_name.GetEndpointInfo(), service_id,
+ proto::connections::Medium::BLUETOOTH,
+ WebRtcState::kUndefined});
+ });
}
bool P2pClusterPcpHandler::IsRecognizedBleEndpoint(
@@ -408,76 +421,81 @@ void P2pClusterPcpHandler::BlePeripheralDiscoveredHandler(
ClientProxy* client, BlePeripheral& peripheral,
const std::string& service_id, const ByteArray& advertisement_bytes,
bool fast_advertisement) {
- RunOnPcpHandlerThread([this, client, &peripheral, service_id,
- advertisement_bytes,
- fast_advertisement]() RUN_ON_PCP_HANDLER_THREAD() {
- // Make sure we are still discovering before proceeding.
- if (!client->IsDiscovering()) {
- NEARBY_LOG(INFO,
- "Ble scanning handler (FOUND) [client=%p, service_id=%s]: not "
- "in discovery mode",
- client, service_id.c_str());
- return;
- }
-
- // Parse the BLE advertisement bytes.
- BleAdvertisement advertisement(fast_advertisement, advertisement_bytes);
-
- // Make sure the BLE advertisement points to a valid
- // endpoint we're discovering.
- if (!IsRecognizedBleEndpoint(service_id, advertisement)) return;
-
- // Store all the state we need to be able to re-create a BleEndpoint
- // in BlePeripheralLostHandler, since that isn't privy to
- // the bytes of the ble advertisement itself.
- found_ble_endpoints_.emplace(
- peripheral.GetName(),
- BleEndpointState(advertisement.GetEndpointId(),
- advertisement.GetEndpointInfo()));
-
- // Report the discovered endpoint to the client.
- NEARBY_LOGS(INFO)
- << "Invoking BasePcpHandler::OnEndpointFound() for Ble service="
- << service_id << "; id=" << advertisement.GetEndpointId() << "; name="
- << absl::BytesToHexString(advertisement.GetEndpointInfo().data());
- OnEndpointFound(client, std::make_shared<BleEndpoint>(BleEndpoint{
- {advertisement.GetEndpointId(),
- advertisement.GetEndpointInfo(), service_id,
- proto::connections::Medium::BLE,
- advertisement.GetWebRtcState()},
- peripheral,
- }));
-
- // Make sure we can connect to this device via Classic Bluetooth.
- std::string remote_bluetooth_mac_address =
- advertisement.GetBluetoothMacAddress();
- if (remote_bluetooth_mac_address.empty()) {
- NEARBY_LOGS(INFO)
- << "No Bluetooth Classic MAC address found in advertisement";
- return;
- }
-
- BluetoothDevice remote_bluetooth_device =
- bluetooth_medium_.GetRemoteDevice(remote_bluetooth_mac_address);
- if (!remote_bluetooth_device.IsValid()) {
- NEARBY_LOGS(INFO) << "A valid Bluetooth device could not be derived from "
- "the MAC address "
- << remote_bluetooth_mac_address;
- return;
- }
-
- OnEndpointFound(client,
- std::make_shared<BluetoothEndpoint>(BluetoothEndpoint{
- {
- advertisement.GetEndpointId(),
- advertisement.GetEndpointInfo(),
- service_id,
- proto::connections::Medium::BLUETOOTH,
- advertisement.GetWebRtcState(),
- },
- remote_bluetooth_device,
- }));
- });
+ RunOnPcpHandlerThread(
+ "p2p-ble-device-discovered",
+ [this, client, &peripheral, service_id, advertisement_bytes,
+ fast_advertisement]() RUN_ON_PCP_HANDLER_THREAD() {
+ // Make sure we are still discovering before proceeding.
+ if (!client->IsDiscovering()) {
+ NEARBY_LOG(
+ INFO,
+ "Ble scanning handler (FOUND) [client=%p, service_id=%s]: not "
+ "in discovery mode",
+ client, service_id.c_str());
+ return;
+ }
+
+ // Parse the BLE advertisement bytes.
+ BleAdvertisement advertisement(fast_advertisement, advertisement_bytes);
+
+ // Make sure the BLE advertisement points to a valid
+ // endpoint we're discovering.
+ if (!IsRecognizedBleEndpoint(service_id, advertisement)) return;
+
+ // Store all the state we need to be able to re-create a BleEndpoint
+ // in BlePeripheralLostHandler, since that isn't privy to
+ // the bytes of the ble advertisement itself.
+ found_ble_endpoints_.emplace(
+ peripheral.GetName(),
+ BleEndpointState(advertisement.GetEndpointId(),
+ advertisement.GetEndpointInfo()));
+
+ // Report the discovered endpoint to the client.
+ NEARBY_LOGS(INFO)
+ << "Invoking BasePcpHandler::OnEndpointFound() for Ble service="
+ << service_id << "; id=" << advertisement.GetEndpointId()
+ << "; name="
+ << absl::BytesToHexString(advertisement.GetEndpointInfo().data());
+ OnEndpointFound(
+ client,
+ std::make_shared<BleEndpoint>(BleEndpoint{
+ {advertisement.GetEndpointId(), advertisement.GetEndpointInfo(),
+ service_id, proto::connections::Medium::BLE,
+ advertisement.GetWebRtcState()},
+ peripheral,
+ }));
+
+ // Make sure we can connect to this device via Classic Bluetooth.
+ std::string remote_bluetooth_mac_address =
+ advertisement.GetBluetoothMacAddress();
+ if (remote_bluetooth_mac_address.empty()) {
+ NEARBY_LOGS(INFO)
+ << "No Bluetooth Classic MAC address found in advertisement";
+ return;
+ }
+
+ BluetoothDevice remote_bluetooth_device =
+ bluetooth_medium_.GetRemoteDevice(remote_bluetooth_mac_address);
+ if (!remote_bluetooth_device.IsValid()) {
+ NEARBY_LOGS(INFO)
+ << "A valid Bluetooth device could not be derived from "
+ "the MAC address "
+ << remote_bluetooth_mac_address;
+ return;
+ }
+
+ OnEndpointFound(client,
+ std::make_shared<BluetoothEndpoint>(BluetoothEndpoint{
+ {
+ advertisement.GetEndpointId(),
+ advertisement.GetEndpointInfo(),
+ service_id,
+ proto::connections::Medium::BLUETOOTH,
+ advertisement.GetWebRtcState(),
+ },
+ remote_bluetooth_device,
+ }));
+ });
}
void P2pClusterPcpHandler::BlePeripheralLostHandler(
@@ -486,38 +504,40 @@ void P2pClusterPcpHandler::BlePeripheralLostHandler(
std::string peripheral_name = peripheral.GetName();
NEARBY_LOG(INFO, "Ble: [LOST, SCHED] peripheral_name=%s",
peripheral_name.c_str());
- RunOnPcpHandlerThread([this, client, service_id,
- &peripheral]() RUN_ON_PCP_HANDLER_THREAD() {
- // Make sure we are still discovering before proceeding.
- if (!client->IsDiscovering()) {
- NEARBY_LOG(INFO,
- "Ble scanning handler (LOST) [client=%p, service_id=%s]: not "
- "in scanning mode",
- client, service_id.c_str());
- return;
- }
-
- // Remove this BlePeripheral from found_ble_endpoints_, and
- // report the endpoint as lost to the client.
- auto item = found_ble_endpoints_.find(peripheral.GetName());
- if (item != found_ble_endpoints_.end()) {
- BleEndpointState ble_endpoint_state(item->second);
- found_ble_endpoints_.erase(item);
-
- // Report the discovered endpoint to the client.
- NEARBY_LOG(INFO,
- "Ble scanning handler (LOST) [client=%p, "
- "service_id=%s]: report to client",
- client, service_id.c_str());
- OnEndpointLost(client, DiscoveredEndpoint{
- ble_endpoint_state.endpoint_id,
- ble_endpoint_state.endpoint_info,
- service_id,
- proto::connections::Medium::BLE,
- WebRtcState::kUndefined,
- });
- }
- });
+ RunOnPcpHandlerThread(
+ "p2p-ble-device-lost",
+ [this, client, service_id, &peripheral]() RUN_ON_PCP_HANDLER_THREAD() {
+ // Make sure we are still discovering before proceeding.
+ if (!client->IsDiscovering()) {
+ NEARBY_LOG(
+ INFO,
+ "Ble scanning handler (LOST) [client=%p, service_id=%s]: not "
+ "in scanning mode",
+ client, service_id.c_str());
+ return;
+ }
+
+ // Remove this BlePeripheral from found_ble_endpoints_, and
+ // report the endpoint as lost to the client.
+ auto item = found_ble_endpoints_.find(peripheral.GetName());
+ if (item != found_ble_endpoints_.end()) {
+ BleEndpointState ble_endpoint_state(item->second);
+ found_ble_endpoints_.erase(item);
+
+ // Report the discovered endpoint to the client.
+ NEARBY_LOG(INFO,
+ "Ble scanning handler (LOST) [client=%p, "
+ "service_id=%s]: report to client",
+ client, service_id.c_str());
+ OnEndpointLost(client, DiscoveredEndpoint{
+ ble_endpoint_state.endpoint_id,
+ ble_endpoint_state.endpoint_info,
+ service_id,
+ proto::connections::Medium::BLE,
+ WebRtcState::kUndefined,
+ });
+ }
+ });
}
bool P2pClusterPcpHandler::IsRecognizedWifiLanEndpoint(
@@ -557,43 +577,46 @@ bool P2pClusterPcpHandler::IsRecognizedWifiLanEndpoint(
void P2pClusterPcpHandler::WifiLanServiceDiscoveredHandler(
ClientProxy* client, WifiLanService& wifi_lan_service,
const std::string& service_id) {
- RunOnPcpHandlerThread([this, client, service_id,
- &wifi_lan_service]() RUN_ON_PCP_HANDLER_THREAD() {
- // Make sure we are still discovering before proceeding.
- if (!client->IsDiscovering()) {
- NEARBY_LOG(
- INFO,
- "WifiLan discovery handler (FOUND) [client=%p, service=%s]: not "
- "in discovery mode",
- client, service_id.c_str());
- return;
- }
-
- // Parse the WifiLanServiceInfo.
- WifiLanServiceInfo service_info(wifi_lan_service.GetServiceInfo());
-
- // Make sure the WifiLan service name points to a valid
- // endpoint we're discovering.
- if (!IsRecognizedWifiLanEndpoint(service_id, service_info)) return;
-
- // Report the discovered endpoint to the client.
- NEARBY_LOG(
- INFO,
- "Invoking BasePcpHandler::OnEndpointFound() for WifiLan "
- "service_id=%s; endpoint_id=%s; endpoint_info=%s",
- service_id.c_str(), service_info.GetEndpointId().c_str(),
- absl::BytesToHexString(service_info.GetEndpointInfo().data()).c_str());
- OnEndpointFound(client, std::make_shared<WifiLanEndpoint>(WifiLanEndpoint{
- {
- service_info.GetEndpointId(),
- service_info.GetEndpointInfo(),
- service_id,
- proto::connections::Medium::WIFI_LAN,
- service_info.GetWebRtcState(),
- },
- wifi_lan_service,
- }));
- });
+ RunOnPcpHandlerThread(
+ "p2p-wifi-service-discovered",
+ [this, client, service_id,
+ &wifi_lan_service]() RUN_ON_PCP_HANDLER_THREAD() {
+ // Make sure we are still discovering before proceeding.
+ if (!client->IsDiscovering()) {
+ NEARBY_LOG(
+ INFO,
+ "WifiLan discovery handler (FOUND) [client=%p, service=%s]: not "
+ "in discovery mode",
+ client, service_id.c_str());
+ return;
+ }
+
+ // Parse the WifiLanServiceInfo.
+ WifiLanServiceInfo service_info(wifi_lan_service.GetServiceInfo());
+
+ // Make sure the WifiLan service name points to a valid
+ // endpoint we're discovering.
+ if (!IsRecognizedWifiLanEndpoint(service_id, service_info)) return;
+
+ // Report the discovered endpoint to the client.
+ NEARBY_LOG(INFO,
+ "Invoking BasePcpHandler::OnEndpointFound() for WifiLan "
+ "service_id=%s; endpoint_id=%s; endpoint_info=%s",
+ service_id.c_str(), service_info.GetEndpointId().c_str(),
+ absl::BytesToHexString(service_info.GetEndpointInfo().data())
+ .c_str());
+ OnEndpointFound(client,
+ std::make_shared<WifiLanEndpoint>(WifiLanEndpoint{
+ {
+ service_info.GetEndpointId(),
+ service_info.GetEndpointInfo(),
+ service_id,
+ proto::connections::Medium::WIFI_LAN,
+ service_info.GetWebRtcState(),
+ },
+ wifi_lan_service,
+ }));
+ });
}
void P2pClusterPcpHandler::WifiLanServiceLostHandler(
@@ -603,39 +626,41 @@ void P2pClusterPcpHandler::WifiLanServiceLostHandler(
NEARBY_LOG(INFO,
"WifiLan: [LOST, SCHED] wifi_lan_service=%p, service_info_name=%s",
&wifi_lan_service, nsd_service_info.GetServiceInfoName().c_str());
- RunOnPcpHandlerThread([this, client, service_id,
- nsd_service_info]() RUN_ON_PCP_HANDLER_THREAD() {
- // Make sure we are still discovering before proceeding.
- if (!client->IsDiscovering()) {
- NEARBY_LOG(
- INFO,
- "WifiLan discovery handler (LOST) [client=%p, service=%s]: not "
- "in discovery mode",
- client, service_id.c_str());
- return;
- }
-
- // Parse the WifiLanServiceInfo.
- WifiLanServiceInfo service_info(nsd_service_info);
-
- // Make sure the WifiLan service name points to a valid
- // endpoint we're discovering.
- if (!IsRecognizedWifiLanEndpoint(service_id, service_info)) return;
-
- // Report the discovered endpoint to the client.
- NEARBY_LOG(
- INFO,
- "WifiLan discovery handler (LOST) [client=%p, service_id=%s]: report "
- "to client",
- client, service_id.c_str());
- OnEndpointLost(client, DiscoveredEndpoint{
- service_info.GetEndpointId(),
- service_info.GetEndpointInfo(),
- service_id,
- proto::connections::Medium::WIFI_LAN,
- WebRtcState::kUndefined,
- });
- });
+ RunOnPcpHandlerThread(
+ "p2p-wifi-service-lost",
+ [this, client, service_id,
+ nsd_service_info]() RUN_ON_PCP_HANDLER_THREAD() {
+ // Make sure we are still discovering before proceeding.
+ if (!client->IsDiscovering()) {
+ NEARBY_LOG(
+ INFO,
+ "WifiLan discovery handler (LOST) [client=%p, service=%s]: not "
+ "in discovery mode",
+ client, service_id.c_str());
+ return;
+ }
+
+ // Parse the WifiLanServiceInfo.
+ WifiLanServiceInfo service_info(nsd_service_info);
+
+ // Make sure the WifiLan service name points to a valid
+ // endpoint we're discovering.
+ if (!IsRecognizedWifiLanEndpoint(service_id, service_info)) return;
+
+ // Report the discovered endpoint to the client.
+ NEARBY_LOG(INFO,
+ "WifiLan discovery handler (LOST) [client=%p, "
+ "service_id=%s]: report "
+ "to client",
+ client, service_id.c_str());
+ OnEndpointLost(client, DiscoveredEndpoint{
+ service_info.GetEndpointId(),
+ service_info.GetEndpointInfo(),
+ service_id,
+ proto::connections::Medium::WIFI_LAN,
+ WebRtcState::kUndefined,
+ });
+ });
}
BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartDiscoveryImpl(
@@ -830,6 +855,7 @@ proto::connections::Medium P2pClusterPcpHandler::StartBluetoothAdvertising(
return;
}
RunOnPcpHandlerThread(
+ "p2p-bt-on-incoming-connection",
[this, client, local_endpoint_info,
socket =
std::move(socket)]() RUN_ON_PCP_HANDLER_THREAD() mutable {
@@ -959,6 +985,7 @@ proto::connections::Medium P2pClusterPcpHandler::StartBleAdvertising(
return;
}
RunOnPcpHandlerThread(
+ "p2p-ble-on-incoming-connection",
[this, client, local_endpoint_info, service_id,
socket = std::move(socket)]()
RUN_ON_PCP_HANDLER_THREAD() mutable {
@@ -999,6 +1026,7 @@ proto::connections::Medium P2pClusterPcpHandler::StartBleAdvertising(
return;
}
RunOnPcpHandlerThread(
+ "p2p-bt-on-incoming-connection",
[this, client, local_endpoint_info,
socket = std::move(socket)]()
RUN_ON_PCP_HANDLER_THREAD() mutable {
@@ -1143,6 +1171,7 @@ proto::connections::Medium P2pClusterPcpHandler::StartWifiLanAdvertising(
return;
}
RunOnPcpHandlerThread(
+ "p2p-wifi-on-incoming-connection",
[this, client, local_endpoint_info,
socket = std::move(socket)]()
RUN_ON_PCP_HANDLER_THREAD() mutable {
@@ -1272,6 +1301,7 @@ P2pClusterPcpHandler::StartListeningForWebRtcConnections(
}
RunOnPcpHandlerThread(
+ "p2p-rtc-on-incoming-connection",
[this, client,
socket = std::move(socket)]() RUN_ON_PCP_HANDLER_THREAD() {
std::string remote_device_name = "WebRtcSocket";
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/p2p_cluster_pcp_handler.h b/chromium/third_party/nearby/src/cpp/core/internal/p2p_cluster_pcp_handler.h
index 43b84f3e5c3..fda43215348 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/p2p_cluster_pcp_handler.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/p2p_cluster_pcp_handler.h
@@ -37,7 +37,6 @@
#include "platform/base/byte_array.h"
#include "platform/public/bluetooth_classic.h"
#include "platform/public/wifi_lan.h"
-#include "proto/connections_enums.pb.h"
namespace location {
namespace nearby {
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/payload_manager.cc b/chromium/third_party/nearby/src/cpp/core/internal/payload_manager.cc
index d9a0ba6cbfa..965aba47a63 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/payload_manager.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/payload_manager.cc
@@ -264,6 +264,7 @@ PayloadManager::~PayloadManager() {
CountDownLatch stop_latch(1);
// Clear our tracked pending payloads.
RunOnStatusUpdateThread(
+ "~payload-manager",
[this, &stop_latch]() RUN_ON_PAYLOAD_STATUS_UPDATE_THREAD() {
NEARBY_LOG(INFO, "PayloadManager: stop tracking payloads; self=%p",
this);
@@ -317,7 +318,7 @@ void PayloadManager::SendPayload(ClientProxy* client,
Payload::Type payload_type = payload.GetType();
Payload::Id payload_id =
CreateOutgoingPayload(std::move(payload), endpoint_ids);
- executor->Execute([this, client, endpoint_ids, payload_id]() {
+ executor->Execute("send-payload", [this, client, endpoint_ids, payload_id]() {
if (shutdown_.Get()) return;
PendingPayload* pending_payload = GetPayload(payload_id);
if (!pending_payload) return;
@@ -331,7 +332,8 @@ void PayloadManager::SendPayload(ClientProxy* client,
should_continue = SendPayloadLoop(client, *pending_payload,
payload_header, next_chunk_offset);
}
- RunOnStatusUpdateThread([this, payload_id]()
+ RunOnStatusUpdateThread("destroy-payload",
+ [this, payload_id]()
RUN_ON_PAYLOAD_STATUS_UPDATE_THREAD() {
DestroyPendingPayload(payload_id);
});
@@ -399,6 +401,7 @@ void PayloadManager::OnEndpointDisconnect(ClientProxy* client,
return;
}
RunOnStatusUpdateThread(
+ "payload-manager-on-disconnect",
[this, client, endpoint_id, barrier]()
RUN_ON_PAYLOAD_STATUS_UPDATE_THREAD() mutable {
// Iterate through all our payloads and look for payloads associated
@@ -551,38 +554,40 @@ void PayloadManager::SendClientCallbacksForFinishedOutgoingPayload(
const PayloadTransferFrame::PayloadHeader& payload_header,
std::int64_t num_bytes_successfully_transferred,
proto::connections::PayloadStatus status) {
- RunOnStatusUpdateThread([this, client, finished_endpoint_ids, payload_header,
- num_bytes_successfully_transferred,
- status]() RUN_ON_PAYLOAD_STATUS_UPDATE_THREAD() {
- // Make sure we're still tracking this payload.
- PendingPayload* pending_payload = GetPayload(payload_header.id());
- if (!pending_payload) {
- return;
- }
+ RunOnStatusUpdateThread(
+ "outgoing-payload-callbacks",
+ [this, client, finished_endpoint_ids, payload_header,
+ num_bytes_successfully_transferred,
+ status]() RUN_ON_PAYLOAD_STATUS_UPDATE_THREAD() {
+ // Make sure we're still tracking this payload.
+ PendingPayload* pending_payload = GetPayload(payload_header.id());
+ if (!pending_payload) {
+ return;
+ }
- PayloadProgressInfo update{
- payload_header.id(),
- PayloadManager::PayloadStatusToTransferUpdateStatus(status),
- payload_header.total_size(), num_bytes_successfully_transferred};
- for (const auto& endpoint_id : finished_endpoint_ids) {
- // Skip sending notifications if we have stopped tracking this
- // endpoint.
- if (!pending_payload->GetEndpoint(endpoint_id)) {
- continue;
- }
+ PayloadProgressInfo update{
+ payload_header.id(),
+ PayloadManager::PayloadStatusToTransferUpdateStatus(status),
+ payload_header.total_size(), num_bytes_successfully_transferred};
+ for (const auto& endpoint_id : finished_endpoint_ids) {
+ // Skip sending notifications if we have stopped tracking this
+ // endpoint.
+ if (!pending_payload->GetEndpoint(endpoint_id)) {
+ continue;
+ }
- // Notify the client.
- client->OnPayloadProgress(endpoint_id, update);
- }
+ // Notify the client.
+ client->OnPayloadProgress(endpoint_id, update);
+ }
- // Remove these endpoints from our tracking list for this payload.
- pending_payload->RemoveEndpoints(finished_endpoint_ids);
+ // Remove these endpoints from our tracking list for this payload.
+ pending_payload->RemoveEndpoints(finished_endpoint_ids);
- // Close the payload if no endpoints remain.
- if (pending_payload->GetEndpoints().empty()) {
- pending_payload->Close();
- }
- });
+ // Close the payload if no endpoints remain.
+ if (pending_payload->GetEndpoints().empty()) {
+ pending_payload->Close();
+ }
+ });
}
void PayloadManager::SendClientCallbacksForFinishedIncomingPayload(
@@ -590,6 +595,7 @@ void PayloadManager::SendClientCallbacksForFinishedIncomingPayload(
const PayloadTransferFrame::PayloadHeader& payload_header,
std::int64_t offset_bytes, proto::connections::PayloadStatus status) {
RunOnStatusUpdateThread(
+ "incoming-payload-callbacks",
[this, client, endpoint_id, payload_header, offset_bytes,
status]() RUN_ON_PAYLOAD_STATUS_UPDATE_THREAD() {
// Make sure we're still tracking this payload.
@@ -693,6 +699,7 @@ void PayloadManager::HandleSuccessfulOutgoingChunk(
std::int32_t payload_chunk_flags, std::int64_t payload_chunk_offset,
std::int64_t payload_chunk_body_size) {
RunOnStatusUpdateThread(
+ "outgoing-chunk-success",
[this, client, endpoint_id, payload_header, payload_chunk_flags,
payload_chunk_offset,
payload_chunk_body_size]() RUN_ON_PAYLOAD_STATUS_UPDATE_THREAD() {
@@ -757,6 +764,7 @@ void PayloadManager::HandleSuccessfulIncomingChunk(
std::int32_t payload_chunk_flags, std::int64_t payload_chunk_offset,
std::int64_t payload_chunk_body_size) {
RunOnStatusUpdateThread(
+ "incoming-chunk-success",
[this, client, endpoint_id, payload_header, payload_chunk_flags,
payload_chunk_offset,
payload_chunk_body_size]() RUN_ON_PAYLOAD_STATUS_UPDATE_THREAD() {
@@ -805,6 +813,7 @@ void PayloadManager::ProcessDataPacket(
// Also, let the client know of this new incoming payload.
RunOnStatusUpdateThread(
+ "process-data-packet",
[to_client, from_endpoint_id, pending_payload]()
RUN_ON_PAYLOAD_STATUS_UPDATE_THREAD() {
NEARBY_LOG(INFO,
@@ -1046,8 +1055,9 @@ bool PayloadManager::PendingPayload::IsClosed() {
return close_event_.Await(absl::ZeroDuration()).result();
}
-void PayloadManager::RunOnStatusUpdateThread(std::function<void()> runnable) {
- payload_status_update_executor_.Execute(std::move(runnable));
+void PayloadManager::RunOnStatusUpdateThread(const std::string& name,
+ std::function<void()> runnable) {
+ payload_status_update_executor_.Execute(name, std::move(runnable));
}
/////////////////////////////// PendingPayloads ///////////////////////////////
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/payload_manager.h b/chromium/third_party/nearby/src/cpp/core/internal/payload_manager.h
index 9c18756502e..c62ff3c055b 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/payload_manager.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/payload_manager.h
@@ -26,13 +26,11 @@
#include "core/listeners.h"
#include "core/payload.h"
#include "core/status.h"
-#include "proto/connections/offline_wire_formats.pb.h"
#include "platform/base/byte_array.h"
#include "platform/public/atomic_boolean.h"
#include "platform/public/atomic_reference.h"
#include "platform/public/count_down_latch.h"
#include "platform/public/mutex.h"
-#include "proto/connections_enums.pb.h"
#include "absl/container/flat_hash_map.h"
namespace location {
@@ -277,7 +275,8 @@ class PayloadManager : public EndpointManager::FrameProcessor {
SingleThreadExecutor* GetOutgoingPayloadExecutor(Payload::Type payload_type);
- void RunOnStatusUpdateThread(std::function<void()> runnable);
+ void RunOnStatusUpdateThread(const std::string& name,
+ std::function<void()> runnable);
bool NotifyShutdown() ABSL_LOCKS_EXCLUDED(mutex_);
void DestroyPendingPayload(Payload::Id payload_id)
ABSL_LOCKS_EXCLUDED(mutex_);
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/pcp_handler.h b/chromium/third_party/nearby/src/cpp/core/internal/pcp_handler.h
index eaf8aabf4fb..b7ad50c0295 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/pcp_handler.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/pcp_handler.h
@@ -24,7 +24,6 @@
#include "core/params.h"
#include "core/status.h"
#include "core/strategy.h"
-#include "proto/connections_enums.pb.h"
namespace location {
namespace nearby {
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/service_controller_router.cc b/chromium/third_party/nearby/src/cpp/core/internal/service_controller_router.cc
index 0e1932ae5cc..653f9003db7 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/service_controller_router.cc
+++ b/chromium/third_party/nearby/src/cpp/core/internal/service_controller_router.cc
@@ -61,28 +61,31 @@ void ServiceControllerRouter::StartAdvertising(
ClientProxy* client, absl::string_view service_id,
const ConnectionOptions& options, const ConnectionRequestInfo& info,
const ResultCallback& callback) {
- RouteToServiceController([this, client, service_id = std::string(service_id),
- options, info, callback]() {
- Status status = AcquireServiceControllerForClient(client, options.strategy);
- if (!status.Ok()) {
- callback.result_cb(status);
- return;
- }
+ RouteToServiceController(
+ "scr-start-advertising",
+ [this, client, service_id = std::string(service_id), options, info,
+ callback]() {
+ Status status =
+ AcquireServiceControllerForClient(client, options.strategy);
+ if (!status.Ok()) {
+ callback.result_cb(status);
+ return;
+ }
- if (client->IsAdvertising()) {
- callback.result_cb({Status::kAlreadyAdvertising});
- return;
- }
+ if (client->IsAdvertising()) {
+ callback.result_cb({Status::kAlreadyAdvertising});
+ return;
+ }
- status = service_controller_->StartAdvertising(client, service_id, options,
- info);
- callback.result_cb(status);
- });
+ status = service_controller_->StartAdvertising(client, service_id,
+ options, info);
+ callback.result_cb(status);
+ });
}
void ServiceControllerRouter::StopAdvertising(ClientProxy* client,
const ResultCallback& callback) {
- RouteToServiceController([this, client, callback]() {
+ RouteToServiceController("scr-stop-advertising", [this, client, callback]() {
if (ClientHasAcquiredServiceController(client) && client->IsAdvertising()) {
service_controller_->StopAdvertising(client);
}
@@ -95,8 +98,11 @@ void ServiceControllerRouter::StartDiscovery(ClientProxy* client,
const ConnectionOptions& options,
const DiscoveryListener& listener,
const ResultCallback& callback) {
- RouteToServiceController([this, client, service_id = std::string(service_id),
- options, listener, callback]() {
+ RouteToServiceController("scr-start-discovery", [this, client,
+ service_id =
+ std::string(service_id),
+ options, listener,
+ callback]() {
Status status = AcquireServiceControllerForClient(client, options.strategy);
if (!status.Ok()) {
callback.result_cb(status);
@@ -116,7 +122,7 @@ void ServiceControllerRouter::StartDiscovery(ClientProxy* client,
void ServiceControllerRouter::StopDiscovery(ClientProxy* client,
const ResultCallback& callback) {
- RouteToServiceController([this, client, callback]() {
+ RouteToServiceController("scr-stop-discovery", [this, client, callback]() {
if (ClientHasAcquiredServiceController(client) && client->IsDiscovering()) {
service_controller_->StopDiscovery(client);
}
@@ -128,8 +134,10 @@ void ServiceControllerRouter::InjectEndpoint(
ClientProxy* client, absl::string_view service_id,
const OutOfBandConnectionMetadata& metadata,
const ResultCallback& callback) {
- RouteToServiceController([this, client, service_id = std::string(service_id),
- metadata, callback]() {
+ RouteToServiceController("scr-inject-endpoint", [this, client,
+ service_id =
+ std::string(service_id),
+ metadata, callback]() {
// Currently, Bluetooth is the only supported medium for endpoint injection.
if (metadata.medium != Medium::BLUETOOTH ||
metadata.remote_bluetooth_mac_address.size() != kMacAddressLength) {
@@ -167,36 +175,38 @@ void ServiceControllerRouter::RequestConnection(
// CancellationListener as soon as possible.
client->AddCancellationFlag(std::string(endpoint_id));
- RouteToServiceController([this, client,
- endpoint_id = std::string(endpoint_id), info,
- options, callback]() {
- if (!ClientHasAcquiredServiceController(client)) {
- callback.result_cb({Status::kOutOfOrderApiCall});
- return;
- }
+ RouteToServiceController(
+ "scr-request-connection",
+ [this, client, endpoint_id = std::string(endpoint_id), info, options,
+ callback]() {
+ if (!ClientHasAcquiredServiceController(client)) {
+ callback.result_cb({Status::kOutOfOrderApiCall});
+ return;
+ }
- if (client->HasPendingConnectionToEndpoint(endpoint_id) ||
- client->IsConnectedToEndpoint(endpoint_id)) {
- callback.result_cb({Status::kAlreadyConnectedToEndpoint});
- return;
- }
+ if (client->HasPendingConnectionToEndpoint(endpoint_id) ||
+ client->IsConnectedToEndpoint(endpoint_id)) {
+ callback.result_cb({Status::kAlreadyConnectedToEndpoint});
+ return;
+ }
- Status status = service_controller_->RequestConnection(client, endpoint_id,
- info, options);
- if (!status.Ok()) {
- client->CancelEndpoint(endpoint_id);
- }
- callback.result_cb(status);
- });
+ Status status = service_controller_->RequestConnection(
+ client, endpoint_id, info, options);
+ if (!status.Ok()) {
+ client->CancelEndpoint(endpoint_id);
+ }
+ callback.result_cb(status);
+ });
}
void ServiceControllerRouter::AcceptConnection(ClientProxy* client,
absl::string_view endpoint_id,
const PayloadListener& listener,
const ResultCallback& callback) {
- RouteToServiceController([this, client,
- endpoint_id = std::string(endpoint_id), listener,
- callback]() {
+ RouteToServiceController("scr-accept-connection", [this, client,
+ endpoint_id = std::string(
+ endpoint_id),
+ listener, callback]() {
if (!ClientHasAcquiredServiceController(client)) {
callback.result_cb({Status::kOutOfOrderApiCall});
return;
@@ -227,6 +237,7 @@ void ServiceControllerRouter::RejectConnection(ClientProxy* client,
client->CancelEndpoint(std::string(endpoint_id));
RouteToServiceController(
+ "scr-reject-connection",
[this, client, endpoint_id = std::string(endpoint_id), callback]() {
if (!ClientHasAcquiredServiceController(client)) {
callback.result_cb({Status::kOutOfOrderApiCall});
@@ -256,6 +267,7 @@ void ServiceControllerRouter::InitiateBandwidthUpgrade(
ClientProxy* client, absl::string_view endpoint_id,
const ResultCallback& callback) {
RouteToServiceController(
+ "scr-init-bwu",
[this, client, endpoint_id = std::string(endpoint_id), callback]() {
if (!ClientHasAcquiredServiceController(client) ||
!client->IsConnectedToEndpoint(endpoint_id)) {
@@ -285,6 +297,7 @@ void ServiceControllerRouter::SendPayload(
std::vector<std::string>(endpoint_ids.begin(), endpoint_ids.end());
RouteToServiceController(
+ "scr-send-payload",
[this, client, shared_payload, endpoints, callback]() {
if (!ClientHasAcquiredServiceController(client)) {
callback.result_cb({Status::kOutOfOrderApiCall});
@@ -310,7 +323,8 @@ void ServiceControllerRouter::SendPayload(
void ServiceControllerRouter::CancelPayload(ClientProxy* client,
std::uint64_t payload_id,
const ResultCallback& callback) {
- RouteToServiceController([this, client, payload_id, callback]() {
+ RouteToServiceController("scr-cancel-payload", [this, client, payload_id,
+ callback]() {
if (!ClientHasAcquiredServiceController(client)) {
callback.result_cb({Status::kOutOfOrderApiCall});
return;
@@ -328,6 +342,7 @@ void ServiceControllerRouter::DisconnectFromEndpoint(
client->CancelEndpoint(std::string(endpoint_id));
RouteToServiceController(
+ "scr-disconnect-endpoint",
[this, client, endpoint_id = std::string(endpoint_id), callback]() {
if (ClientHasAcquiredServiceController(client)) {
if (!client->IsConnectedToEndpoint(endpoint_id) &&
@@ -347,7 +362,11 @@ void ServiceControllerRouter::StopAllEndpoints(ClientProxy* client,
// without further posting it.
client->CancelAllEndpoints();
- RouteToServiceController([this, client, callback]() {
+ RouteToServiceController("scr-stop-all-endpoints", [this, client,
+ callback]() {
+ NEARBY_LOGS(INFO) << "Client " << client->GetClientId()
+ << " has requested us to stop all endpoints. We will now "
+ "reset the client.";
if (ClientHasAcquiredServiceController(client)) {
DoneWithStrategySessionForClient(client);
}
@@ -361,7 +380,8 @@ void ServiceControllerRouter::ClientDisconnecting(
// without further posting it.
client->CancelAllEndpoints();
- RouteToServiceController([this, client, callback]() {
+ RouteToServiceController("scr-client-disconnecting", [this, client,
+ callback]() {
if (ClientHasAcquiredServiceController(client)) {
DoneWithStrategySessionForClient(client);
NEARBY_LOG(INFO,
@@ -459,8 +479,9 @@ void ServiceControllerRouter::DoneWithStrategySessionForClient(
ReleaseServiceControllerForClient(client);
}
-void ServiceControllerRouter::RouteToServiceController(Runnable runnable) {
- serializer_.Execute(std::move(runnable));
+void ServiceControllerRouter::RouteToServiceController(const std::string& name,
+ Runnable runnable) {
+ serializer_.Execute(name, std::move(runnable));
}
bool ServiceControllerRouter::ClientHasConnectionToAtLeastOneEndpoint(
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/service_controller_router.h b/chromium/third_party/nearby/src/cpp/core/internal/service_controller_router.h
index 8c9e7039094..fa209e63585 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/service_controller_router.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/service_controller_router.h
@@ -104,11 +104,10 @@ class ServiceControllerRouter {
void ClientDisconnecting(ClientProxy* client, const ResultCallback& callback);
private:
- friend class ServiceControllerRouterTest;
static bool ClientHasConnectionToAtLeastOneEndpoint(
ClientProxy* client, const std::vector<std::string>& remote_endpoint_ids);
- void RouteToServiceController(Runnable runnable);
+ void RouteToServiceController(const std::string& name, Runnable runnable);
Status AcquireServiceControllerForClient(ClientProxy* client,
Strategy strategy);
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/simulation_user.h b/chromium/third_party/nearby/src/cpp/core/internal/simulation_user.h
index 14152bf0f01..98522921df6 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/simulation_user.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/simulation_user.h
@@ -54,7 +54,15 @@ class SimulationUser {
explicit SimulationUser(
const std::string& device_name,
BooleanMediumSelector allowed = BooleanMediumSelector())
- : info_{ByteArray{device_name}},
+ : connection_options_{
+ .keep_alive_interval_millis = FeatureFlags::GetInstance()
+ .GetFlags()
+ .keep_alive_interval_millis,
+ .keep_alive_timeout_millis = FeatureFlags::GetInstance()
+ .GetFlags()
+ .keep_alive_timeout_millis,
+ },
+ info_{ByteArray{device_name}},
options_{
.strategy = Strategy::kP2pCluster,
.allowed = allowed,
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/webrtc_endpoint_channel.h b/chromium/third_party/nearby/src/cpp/core/internal/webrtc_endpoint_channel.h
index e15cc0c7124..48d8d37f7dc 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/webrtc_endpoint_channel.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/webrtc_endpoint_channel.h
@@ -17,7 +17,6 @@
#include "core/internal/base_endpoint_channel.h"
#include "core/internal/mediums/webrtc/webrtc_socket_wrapper.h"
-#include "proto/connections_enums.pb.h"
namespace location {
namespace nearby {
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/wifi_lan_endpoint_channel.h b/chromium/third_party/nearby/src/cpp/core/internal/wifi_lan_endpoint_channel.h
index 87eb359e9a5..38459c810a0 100644
--- a/chromium/third_party/nearby/src/cpp/core/internal/wifi_lan_endpoint_channel.h
+++ b/chromium/third_party/nearby/src/cpp/core/internal/wifi_lan_endpoint_channel.h
@@ -17,7 +17,6 @@
#include "core/internal/base_endpoint_channel.h"
#include "platform/public/wifi_lan.h"
-#include "proto/connections_enums.pb.h"
namespace location {
namespace nearby {
diff --git a/chromium/third_party/nearby/src/cpp/core/options.h b/chromium/third_party/nearby/src/cpp/core/options.h
index 100e80e3760..09c1c98d75a 100644
--- a/chromium/third_party/nearby/src/cpp/core/options.h
+++ b/chromium/third_party/nearby/src/cpp/core/options.h
@@ -18,7 +18,6 @@
#include "core/strategy.h"
#include "platform/base/byte_array.h"
#include "proto/connections_enums.pb.h"
-#include "proto/connections_enums.pb.h"
namespace location {
namespace nearby {
@@ -95,10 +94,13 @@ struct ConnectionOptions {
bool enforce_topology_constraints;
bool low_power;
bool enable_bluetooth_listening;
+ bool enable_webrtc_listening;
// Whether this is intended to be used in conjunction with InjectEndpoint().
bool is_out_of_band_connection = false;
ByteArray remote_bluetooth_mac_address;
std::string fast_advertisement_service_uuid;
+ int keep_alive_interval_millis = 0;
+ int keep_alive_timeout_millis = 0;
// Verify if ConnectionOptions is in a not-initialized (Empty) state.
bool Empty() const { return strategy.IsNone(); }
// Bring ConnectionOptions to a not-initialized (Empty) state.
diff --git a/chromium/third_party/nearby/src/cpp/platform/api/BUILD b/chromium/third_party/nearby/src/cpp/platform/api/BUILD
index e31a848af6e..cad9831364b 100644
--- a/chromium/third_party/nearby/src/cpp/platform/api/BUILD
+++ b/chromium/third_party/nearby/src/cpp/platform/api/BUILD
@@ -34,6 +34,7 @@ cc_library(
"system_clock.h",
],
visibility = [
+ "//googlemac/iPhone/Shared/Nearby/Connections_v2:__subpackages__",
"//platform/base:__pkg__",
"//platform/impl:__subpackages__",
"//platform/public:__pkg__",
diff --git a/chromium/third_party/nearby/src/cpp/platform/api/log_message.h b/chromium/third_party/nearby/src/cpp/platform/api/log_message.h
index 11374ed13d0..3f43c0bc352 100644
--- a/chromium/third_party/nearby/src/cpp/platform/api/log_message.h
+++ b/chromium/third_party/nearby/src/cpp/platform/api/log_message.h
@@ -23,9 +23,13 @@ namespace api {
// A log message that prints to appropraite destination when ~LogMessage() is
// called.
+//
+// note: the Severity enum should map (best effort) to the corresponding level
+// id that the platform logging implementation has.
class LogMessage {
public:
enum class Severity {
+ kVerbose = -1,
kInfo = 0,
kWarning = 1,
kError = 2,
diff --git a/chromium/third_party/nearby/src/cpp/platform/api/webrtc.h b/chromium/third_party/nearby/src/cpp/platform/api/webrtc.h
index 16fc30e5f26..9d01f20ef99 100644
--- a/chromium/third_party/nearby/src/cpp/platform/api/webrtc.h
+++ b/chromium/third_party/nearby/src/cpp/platform/api/webrtc.h
@@ -18,7 +18,6 @@
#include <memory>
#include "proto/connections/offline_wire_formats.pb.h"
-#include "proto/connections/offline_wire_formats.pb.h"
#include "platform/base/byte_array.h"
#include "absl/strings/string_view.h"
#include "webrtc/api/peer_connection_interface.h"
diff --git a/chromium/third_party/nearby/src/cpp/platform/base/BUILD b/chromium/third_party/nearby/src/cpp/platform/base/BUILD
index 3f010ebb920..b61a8e8603f 100644
--- a/chromium/third_party/nearby/src/cpp/platform/base/BUILD
+++ b/chromium/third_party/nearby/src/cpp/platform/base/BUILD
@@ -102,6 +102,7 @@ cc_library(
],
hdrs = [
"cancellation_flag.h",
+ "cancellation_flag_listener.h",
],
visibility = [
"//core/internal:__subpackages__",
diff --git a/chromium/third_party/nearby/src/cpp/platform/base/cancellation_flag.cc b/chromium/third_party/nearby/src/cpp/platform/base/cancellation_flag.cc
index 7aaf4d2d965..1d6b792af79 100644
--- a/chromium/third_party/nearby/src/cpp/platform/base/cancellation_flag.cc
+++ b/chromium/third_party/nearby/src/cpp/platform/base/cancellation_flag.cc
@@ -28,25 +28,37 @@ CancellationFlag::CancellationFlag(bool cancelled) {
cancelled_ = cancelled;
}
-void CancellationFlag::Cancel() {
- absl::MutexLock lock(mutex_.get());
+CancellationFlag::~CancellationFlag() {
+ listeners_.clear();
+}
+void CancellationFlag::Cancel() {
// Return immediately as no-op if feature flag is not enabled.
if (!FeatureFlags::GetInstance().GetFlags().enable_cancellation_flag) {
return;
}
- if (cancelled_) {
- // Someone already cancelled. Return immediately.
- return;
+ absl::flat_hash_set<CancelListener *> listeners;
+ {
+ absl::MutexLock lock(mutex_.get());
+ if (cancelled_) {
+ // Someone already cancelled. Return immediately.
+ return;
+ }
+ cancelled_ = true;
+
+ listeners = listeners_;
+ }
+
+ for (const auto *listener : listeners) {
+ (*listener)();
}
- cancelled_ = true;
}
bool CancellationFlag::Cancelled() const {
absl::MutexLock lock(mutex_.get());
- // Return falsea as no-op if feature flag is not enabled.
+ // Return false as no-op if feature flag is not enabled.
if (!FeatureFlags::GetInstance().GetFlags().enable_cancellation_flag) {
return false;
}
@@ -54,5 +66,17 @@ bool CancellationFlag::Cancelled() const {
return cancelled_;
}
+void CancellationFlag::RegisterOnCancelListener(CancelListener *listener) {
+ absl::MutexLock lock(mutex_.get());
+
+ listeners_.emplace(listener);
+}
+
+void CancellationFlag::UnregisterOnCancelListener(CancelListener *listener) {
+ absl::MutexLock lock(mutex_.get());
+
+ listeners_.erase(listener);
+}
+
} // namespace nearby
} // namespace location
diff --git a/chromium/third_party/nearby/src/cpp/platform/base/cancellation_flag.h b/chromium/third_party/nearby/src/cpp/platform/base/cancellation_flag.h
index a9cd9450a1f..e861bfe0ab4 100644
--- a/chromium/third_party/nearby/src/cpp/platform/base/cancellation_flag.h
+++ b/chromium/third_party/nearby/src/cpp/platform/base/cancellation_flag.h
@@ -17,6 +17,7 @@
#include <memory>
+#include "absl/container/flat_hash_set.h"
#include "absl/synchronization/mutex.h"
namespace location {
@@ -26,13 +27,16 @@ namespace nearby {
// cleaned up as soon as possible.
class CancellationFlag {
public:
+ // The listener for cancellation.
+ using CancelListener = std::function<void()>;
+
CancellationFlag();
explicit CancellationFlag(bool cancelled);
CancellationFlag(const CancellationFlag &) = delete;
CancellationFlag &operator=(const CancellationFlag &) = delete;
CancellationFlag(CancellationFlag &&) = default;
CancellationFlag &operator=(CancellationFlag &&) = default;
- virtual ~CancellationFlag() = default;
+ virtual ~CancellationFlag();
// Set the flag as cancelled.
void Cancel() ABSL_LOCKS_EXCLUDED(mutex_);
@@ -41,8 +45,33 @@ class CancellationFlag {
bool Cancelled() const ABSL_LOCKS_EXCLUDED(mutex_);
private:
+ friend class CancellationFlagListener;
+ friend class CancellationFlagPeer;
+
+ // The registration inserts the pointer of caller's listener callback into
+ // `listeners_`, a flat hash set which support the pointer type for hashing
+ // function. It conducts that 2 different pointers might point to the same
+ // callback function which is unusal and should avoid. Hence we make it as
+ // private and use `CancellationFlagListener` as a RAII to wrap the function.
+ // The caller should register listener as lambda or std::function
+ // via `CancellationFlagListener`.
+ void RegisterOnCancelListener(CancelListener *listener)
+ ABSL_LOCKS_EXCLUDED(mutex_);
+
+ // The un-registration erases the pointer of caller's listener callback from
+ // `listeners_`. This is paired to RegisterOnCancelListener which is
+ // guaranteed to be called under `CancellationFlagListener`.
+ void UnregisterOnCancelListener(CancelListener *listener)
+ ABSL_LOCKS_EXCLUDED(mutex_);
+
+ int CancelListenersSize() const ABSL_LOCKS_EXCLUDED(mutex_) {
+ absl::MutexLock lock(mutex_.get());
+ return listeners_.size();
+ }
+
std::unique_ptr<absl::Mutex> mutex_;
bool cancelled_ ABSL_GUARDED_BY(mutex_) = false;
+ absl::flat_hash_set<CancelListener *> ABSL_GUARDED_BY(mutex_) listeners_;
};
} // namespace nearby
diff --git a/chromium/third_party/nearby/src/cpp/platform/base/cancellation_flag_listener.h b/chromium/third_party/nearby/src/cpp/platform/base/cancellation_flag_listener.h
new file mode 100644
index 00000000000..8a5d9d37794
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/base/cancellation_flag_listener.h
@@ -0,0 +1,43 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_BASE_CANCELLATION_FLAG_LISTENER_H_
+#define PLATFORM_BASE_CANCELLATION_FLAG_LISTENER_H_
+
+#include "platform/base/cancellation_flag.h"
+
+namespace location {
+namespace nearby {
+
+// An RAII mechanism to register CancelListener over a life cycle of medium
+// class.
+class CancellationFlagListener {
+ public:
+ CancellationFlagListener(CancellationFlag* flag,
+ std::function<void()> listener)
+ : flag_(flag), listener_(std::move(listener)) {
+ flag_->RegisterOnCancelListener(&listener_);
+ }
+
+ ~CancellationFlagListener() { flag_->UnregisterOnCancelListener(&listener_); }
+
+ private:
+ CancellationFlag* flag_;
+ std::function<void()> listener_;
+};
+
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_BASE_CANCELLATION_FLAG_LISTENER_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/base/cancellation_flag_test.cc b/chromium/third_party/nearby/src/cpp/platform/base/cancellation_flag_test.cc
index e5f05af9c97..f5a55316123 100644
--- a/chromium/third_party/nearby/src/cpp/platform/base/cancellation_flag_test.cc
+++ b/chromium/third_party/nearby/src/cpp/platform/base/cancellation_flag_test.cc
@@ -14,15 +14,40 @@
#include "platform/base/cancellation_flag.h"
+#include <memory>
+
+#include "platform/base/cancellation_flag_listener.h"
#include "platform/base/feature_flags.h"
#include "platform/base/medium_environment.h"
+#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace location {
namespace nearby {
+
+class CancellationFlagPeer {
+ public:
+ explicit CancellationFlagPeer(CancellationFlag* cancellation_flag)
+ : cancellation_flag_(cancellation_flag) {}
+ void RegisterOnCancelListener(CancellationFlag::CancelListener* listener) {
+ cancellation_flag_->RegisterOnCancelListener(listener);
+ }
+ void UnregisterOnCancelListener(CancellationFlag::CancelListener* listener) {
+ cancellation_flag_->UnregisterOnCancelListener(listener);
+ }
+ int CancelListenersSize() const {
+ return cancellation_flag_->CancelListenersSize();
+ }
+
+ private:
+ CancellationFlag* cancellation_flag_; // Not owned by CancellationFlagPeer.
+};
+
namespace {
using FeatureFlags = FeatureFlags::Flags;
+using ::testing::MockFunction;
+using ::testing::StrictMock;
constexpr FeatureFlags kTestCases[] = {
FeatureFlags{
@@ -64,7 +89,36 @@ TEST_P(CancellationFlagTest, InitialValueAsTrue) {
}
TEST_P(CancellationFlagTest, CanCancel) {
+ StrictMock<MockFunction<void()>> mock_cancel_callback;
+ CancellationFlag::CancelListener cancel_callback =
+ mock_cancel_callback.AsStdFunction();
+ EXPECT_CALL(mock_cancel_callback, Call)
+ .Times(feature_flags_.enable_cancellation_flag ? 1 : 0);
+ CancellationFlag flag;
+ CancellationFlagListener cancellation_flag_listener(&flag, cancel_callback);
+ flag.Cancel();
+
+ // If FeatureFlag is disabled, return as no-op immediately and
+ // Cancelled is always false.
+ if (!feature_flags_.enable_cancellation_flag) {
+ EXPECT_FALSE(flag.Cancelled());
+ return;
+ }
+
+ EXPECT_TRUE(flag.Cancelled());
+}
+
+TEST_P(CancellationFlagTest, ShouldOnlyCancelOnce) {
+ StrictMock<MockFunction<void()>> mock_cancel_callback;
+ CancellationFlag::CancelListener cancel_callback =
+ mock_cancel_callback.AsStdFunction();
+ EXPECT_CALL(mock_cancel_callback, Call)
+ .Times(feature_flags_.enable_cancellation_flag ? 1 : 0);
+
CancellationFlag flag;
+ CancellationFlagListener cancellation_flag_listener(&flag, cancel_callback);
+ flag.Cancel();
+ flag.Cancel();
flag.Cancel();
// If FeatureFlag is disabled, return as no-op immediately and
@@ -77,9 +131,82 @@ TEST_P(CancellationFlagTest, CanCancel) {
EXPECT_TRUE(flag.Cancelled());
}
+TEST_P(CancellationFlagTest, CannotCancelAfterUnregister) {
+ StrictMock<MockFunction<void()>> mock_cancel_callback;
+ CancellationFlag::CancelListener cancel_callback =
+ mock_cancel_callback.AsStdFunction();
+ EXPECT_CALL(mock_cancel_callback, Call).Times(0);
+
+ CancellationFlag flag;
+ auto cancellation_flag_listener =
+ std::make_unique<CancellationFlagListener>(&flag, cancel_callback);
+ // Release immediately.
+ cancellation_flag_listener.reset();
+ flag.Cancel();
+}
+
INSTANTIATE_TEST_SUITE_P(ParametrisedCancellationFlagTest, CancellationFlagTest,
::testing::ValuesIn(kTestCases));
} // namespace
+
+TEST(CancellationFlagTest,
+ CancelMultiplesIfMultiplePointersToTheSameFunctionRegistered) {
+ location::nearby::FeatureFlags::Flags feature_flags_ =
+ location::nearby::FeatureFlags::Flags{
+ .enable_cancellation_flag = true,
+ };
+ MediumEnvironment::Instance().SetFeatureFlags(feature_flags_);
+
+ StrictMock<MockFunction<void()>> mock_cancel_callback;
+ CancellationFlag::CancelListener cancel_callback =
+ mock_cancel_callback.AsStdFunction();
+
+ CancellationFlag::CancelListener *callback_pointer_1 = &cancel_callback;
+ auto callback_pointer_2 =
+ std::make_unique<CancellationFlag::CancelListener>();
+ *callback_pointer_2 = cancel_callback;
+
+ EXPECT_NE(callback_pointer_1, callback_pointer_2.get());
+ EXPECT_CALL(mock_cancel_callback, Call).Times(2);
+
+ CancellationFlag flag;
+ CancellationFlagPeer flag_peer(&flag);
+ flag_peer.RegisterOnCancelListener(callback_pointer_1);
+ flag_peer.RegisterOnCancelListener(callback_pointer_2.get());
+
+ flag.Cancel();
+
+ flag_peer.UnregisterOnCancelListener(callback_pointer_2.get());
+ EXPECT_EQ(1, flag_peer.CancelListenersSize());
+ flag_peer.UnregisterOnCancelListener(callback_pointer_1);
+ EXPECT_EQ(0, flag_peer.CancelListenersSize());
+}
+
+TEST(CancellationFlagTest, RegisteredMultuipleTimesOnlyCancelOnce) {
+ location::nearby::FeatureFlags::Flags feature_flags_ =
+ location::nearby::FeatureFlags::Flags{
+ .enable_cancellation_flag = true,
+ };
+ MediumEnvironment::Instance().SetFeatureFlags(feature_flags_);
+
+ StrictMock<MockFunction<void()>> mock_cancel_callback;
+ CancellationFlag::CancelListener cancel_callback =
+ mock_cancel_callback.AsStdFunction();
+ EXPECT_CALL(mock_cancel_callback, Call).Times(1);
+
+ CancellationFlag flag;
+ CancellationFlagPeer flag_peer(&flag);
+ flag_peer.RegisterOnCancelListener(&cancel_callback);
+ flag_peer.RegisterOnCancelListener(&cancel_callback);
+ EXPECT_EQ(1, flag_peer.CancelListenersSize());
+
+ flag.Cancel();
+
+ flag_peer.UnregisterOnCancelListener(&cancel_callback);
+ EXPECT_EQ(0, flag_peer.CancelListenersSize());
+ flag_peer.UnregisterOnCancelListener(&cancel_callback);
+}
+
} // namespace nearby
} // namespace location
diff --git a/chromium/third_party/nearby/src/cpp/platform/base/feature_flags.h b/chromium/third_party/nearby/src/cpp/platform/base/feature_flags.h
index ff30b43235d..d62c7a458f3 100644
--- a/chromium/third_party/nearby/src/cpp/platform/base/feature_flags.h
+++ b/chromium/third_party/nearby/src/cpp/platform/base/feature_flags.h
@@ -34,6 +34,9 @@ class FeatureFlags {
// If a scheduled runnable is already running, Cancel() will synchronously
// wait for the task to complete.
bool cancel_waits_for_running_tasks = true;
+ // Keep Alive frame interval and timeout in millis.
+ std::int32_t keep_alive_interval_millis = 5000;
+ std::int32_t keep_alive_timeout_millis = 30000;
};
static const FeatureFlags& GetInstance() {
diff --git a/chromium/third_party/nearby/src/cpp/platform/base/feature_flags_test.cc b/chromium/third_party/nearby/src/cpp/platform/base/feature_flags_test.cc
index 2ad5e44fc28..075a75f4008 100644
--- a/chromium/third_party/nearby/src/cpp/platform/base/feature_flags_test.cc
+++ b/chromium/third_party/nearby/src/cpp/platform/base/feature_flags_test.cc
@@ -21,13 +21,18 @@ namespace location {
namespace nearby {
namespace {
-constexpr FeatureFlags::Flags kTestFeatureFlags{.enable_cancellation_flag =
- true};
+constexpr FeatureFlags::Flags kTestFeatureFlags{
+ .enable_cancellation_flag = true,
+ .keep_alive_interval_millis = 5000,
+ .keep_alive_timeout_millis = 30000};
TEST(FeatureFlagsTest, ToSetFeatureWorks) {
const FeatureFlags& features = FeatureFlags::GetInstance();
EXPECT_FALSE(features.GetFlags().enable_cancellation_flag);
+ EXPECT_EQ(5000, features.GetFlags().keep_alive_interval_millis);
+ EXPECT_EQ(30000, features.GetFlags().keep_alive_timeout_millis);
+
MediumEnvironment& medium_environment = MediumEnvironment::Instance();
medium_environment.SetFeatureFlags(kTestFeatureFlags);
EXPECT_TRUE(features.GetFlags().enable_cancellation_flag);
diff --git a/chromium/third_party/nearby/src/cpp/platform/base/logging.h b/chromium/third_party/nearby/src/cpp/platform/base/logging.h
index c50e57cefef..36a6416ce53 100644
--- a/chromium/third_party/nearby/src/cpp/platform/base/logging.h
+++ b/chromium/third_party/nearby/src/cpp/platform/base/logging.h
@@ -36,7 +36,10 @@ class LogMessageVoidify {
} // namespace location
// Severity enum conversion
-#define NEARBY_SEVERITY_INFO location::nearby::api::LogMessage::Severity::kInfo
+#define NEARBY_SEVERITY_VERBOSE \
+ location::nearby::api::LogMessage::Severity::kVerbose
+#define NEARBY_SEVERITY_INFO \
+ location::nearby::api::LogMessage::Severity::kInfo
#define NEARBY_SEVERITY_WARNING \
location::nearby::api::LogMessage::Severity::kWarning
#define NEARBY_SEVERITY_ERROR \
diff --git a/chromium/third_party/nearby/src/cpp/platform/base/medium_environment.cc b/chromium/third_party/nearby/src/cpp/platform/base/medium_environment.cc
index 42733cd865b..870eeffe40c 100644
--- a/chromium/third_party/nearby/src/cpp/platform/base/medium_environment.cc
+++ b/chromium/third_party/nearby/src/cpp/platform/base/medium_environment.cc
@@ -62,6 +62,8 @@ void MediumEnvironment::Reset() {
webrtc_signaling_message_callback_.clear();
webrtc_signaling_complete_callback_.clear();
wifi_lan_mediums_.clear();
+ use_valid_peer_connection_ = true;
+ peer_connection_latency_ = absl::ZeroDuration();
});
Sync();
}
@@ -511,6 +513,15 @@ bool MediumEnvironment::GetUseValidPeerConnection() {
return use_valid_peer_connection_;
}
+void MediumEnvironment::SetPeerConnectionLatency(
+ absl::Duration peer_connection_latency) {
+ peer_connection_latency_ = peer_connection_latency;
+}
+
+absl::Duration MediumEnvironment::GetPeerConnectionLatency() {
+ return peer_connection_latency_;
+}
+
void MediumEnvironment::RegisterWifiLanMedium(api::WifiLanMedium& medium) {
if (!enabled_) return;
RunOnMediumEnvironmentThread([this, &medium]() {
diff --git a/chromium/third_party/nearby/src/cpp/platform/base/medium_environment.h b/chromium/third_party/nearby/src/cpp/platform/base/medium_environment.h
index bd7126dc795..15eb0becb48 100644
--- a/chromium/third_party/nearby/src/cpp/platform/base/medium_environment.h
+++ b/chromium/third_party/nearby/src/cpp/platform/base/medium_environment.h
@@ -153,6 +153,11 @@ class MediumEnvironment {
bool GetUseValidPeerConnection();
+ // Used to set latency when creating the peer connection in tests.
+ void SetPeerConnectionLatency(absl::Duration peer_connection_latency);
+
+ absl::Duration GetPeerConnectionLatency();
+
// Adds medium-related info to allow for scanning/advertising to work.
// This provides acccess to this medium from other mediums, when protocol
// expects they should communicate.
@@ -319,6 +324,7 @@ class MediumEnvironment {
wifi_lan_mediums_;
bool use_valid_peer_connection_ = true;
+ absl::Duration peer_connection_latency_ = absl::ZeroDuration();
};
} // namespace nearby
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/g3/ble.cc b/chromium/third_party/nearby/src/cpp/platform/impl/g3/ble.cc
index 0595c80aaa2..ecd9ac03190 100644
--- a/chromium/third_party/nearby/src/cpp/platform/impl/g3/ble.cc
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/g3/ble.cc
@@ -19,6 +19,7 @@
#include <string>
#include "platform/api/ble.h"
+#include "platform/base/cancellation_flag_listener.h"
#include "platform/base/logging.h"
#include "platform/base/medium_environment.h"
#include "absl/synchronization/mutex.h"
@@ -44,9 +45,7 @@ InputStream& BleSocket::GetInputStream() {
return remote_socket->GetLocalInputStream();
}
-OutputStream& BleSocket::GetOutputStream() {
- return GetLocalOutputStream();
-}
+OutputStream& BleSocket::GetOutputStream() { return GetLocalOutputStream(); }
BleSocket* BleSocket::GetRemoteSocket() {
absl::MutexLock lock(&mutex_);
@@ -354,6 +353,11 @@ std::unique_ptr<api::BleSocket> BleMedium::Connect(
return {};
}
+ CancellationFlagListener listener(cancellation_flag, [this]() {
+ NEARBY_LOGS(INFO) << "G3 BLE Cancel Connect.";
+ if (server_socket_ != nullptr) server_socket_->Close();
+ });
+
BlePeripheral peripheral = static_cast<BlePeripheral&>(remote_peripheral);
auto socket = std::make_unique<BleSocket>(&peripheral);
// Finally, Request to connect to this socket.
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/g3/bluetooth_classic.cc b/chromium/third_party/nearby/src/cpp/platform/impl/g3/bluetooth_classic.cc
index 7af8b6c477d..995b93a999d 100644
--- a/chromium/third_party/nearby/src/cpp/platform/impl/g3/bluetooth_classic.cc
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/g3/bluetooth_classic.cc
@@ -18,6 +18,7 @@
#include <string>
#include "platform/api/bluetooth_classic.h"
+#include "platform/base/cancellation_flag_listener.h"
#include "platform/base/logging.h"
#include "platform/base/medium_environment.h"
#include "platform/impl/g3/bluetooth_adapter.h"
@@ -234,6 +235,11 @@ std::unique_ptr<api::BluetoothSocket> BluetoothClassicMedium::ConnectToService(
return {};
}
+ CancellationFlagListener listener(cancellation_flag, [&server_socket]() {
+ NEARBY_LOGS(INFO) << "G3 Bluetooth Cancel Connect.";
+ if (server_socket != nullptr) server_socket->Close();
+ });
+
auto socket = std::make_unique<BluetoothSocket>(&GetAdapter());
// Finally, Request to connect to this socket.
if (!server_socket->Connect(*socket)) {
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/g3/log_message.cc b/chromium/third_party/nearby/src/cpp/platform/impl/g3/log_message.cc
index b227392a668..dd63c332d43 100644
--- a/chromium/third_party/nearby/src/cpp/platform/impl/g3/log_message.cc
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/g3/log_message.cc
@@ -26,6 +26,10 @@ api::LogMessage::Severity g_min_log_severity = api::LogMessage::Severity::kInfo;
inline absl::LogSeverity ConvertSeverity(api::LogMessage::Severity severity) {
switch (severity) {
+ // api::LogMessage::Severity kVerbose and kInfo is mapped to
+ // absl::LogSeverity kInfo since absl::LogSeverity doesn't have kVerbose
+ // level.
+ case api::LogMessage::Severity::kVerbose:
case api::LogMessage::Severity::kInfo:
return absl::LogSeverity::kInfo;
case api::LogMessage::Severity::kWarning:
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/g3/webrtc.cc b/chromium/third_party/nearby/src/cpp/platform/impl/g3/webrtc.cc
index cd5f467ce84..c02cde71adc 100644
--- a/chromium/third_party/nearby/src/cpp/platform/impl/g3/webrtc.cc
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/g3/webrtc.cc
@@ -48,6 +48,8 @@ void WebRtcSignalingMessenger::StopReceivingMessages() {
env.UnregisterWebRtcSignalingMessenger(self_id_);
}
+WebRtcMedium::~WebRtcMedium() { single_thread_executor_.Shutdown(); }
+
const std::string WebRtcMedium::GetDefaultCountryCode() {
return "US";
}
@@ -72,9 +74,17 @@ void WebRtcMedium::CreatePeerConnection(
webrtc::CreateDefaultTaskQueueFactory();
factory_dependencies.signaling_thread = signaling_thread.release();
- callback(webrtc::CreateModularPeerConnectionFactory(
- std::move(factory_dependencies))
- ->CreatePeerConnection(rtc_config, std::move(dependencies)));
+ rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection =
+ webrtc::CreateModularPeerConnectionFactory(
+ std::move(factory_dependencies))
+ ->CreatePeerConnection(rtc_config, std::move(dependencies));
+
+ single_thread_executor_.Execute(
+ [&env, callback = std::move(callback),
+ peer_connection = std::move(peer_connection)]() {
+ absl::SleepFor(env.GetPeerConnectionLatency());
+ callback(peer_connection);
+ });
}
std::unique_ptr<api::WebRtcSignalingMessenger>
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/g3/webrtc.h b/chromium/third_party/nearby/src/cpp/platform/impl/g3/webrtc.h
index 235fb6495f1..14930f5923d 100644
--- a/chromium/third_party/nearby/src/cpp/platform/impl/g3/webrtc.h
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/g3/webrtc.h
@@ -18,6 +18,7 @@
#include <memory>
#include "platform/api/webrtc.h"
+#include "platform/impl/g3/single_thread_executor.h"
#include "absl/strings/string_view.h"
#include "webrtc/api/peer_connection_interface.h"
@@ -54,7 +55,7 @@ class WebRtcMedium : public api::WebRtcMedium {
using PeerConnectionCallback = api::WebRtcMedium::PeerConnectionCallback;
WebRtcMedium() = default;
- ~WebRtcMedium() override = default;
+ ~WebRtcMedium() override;
const std::string GetDefaultCountryCode() override;
@@ -69,6 +70,8 @@ class WebRtcMedium : public api::WebRtcMedium {
const connections::LocationHint& location_hint) override;
private:
+ // Executor for handling calls to create a peer connection.
+ SingleThreadExecutor single_thread_executor_;
};
} // namespace g3
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/g3/wifi_lan.cc b/chromium/third_party/nearby/src/cpp/platform/impl/g3/wifi_lan.cc
index 2ae2b9feaea..31b2732f763 100644
--- a/chromium/third_party/nearby/src/cpp/platform/impl/g3/wifi_lan.cc
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/g3/wifi_lan.cc
@@ -19,6 +19,7 @@
#include <string>
#include "platform/api/wifi_lan.h"
+#include "platform/base/cancellation_flag_listener.h"
#include "platform/base/logging.h"
#include "platform/base/medium_environment.h"
#include "platform/base/nsd_service_info.h"
@@ -361,6 +362,11 @@ std::unique_ptr<api::WifiLanSocket> WifiLanMedium::Connect(
return {};
}
+ CancellationFlagListener listener(cancellation_flag, [this]() {
+ NEARBY_LOGS(INFO) << "G3 WifiLan Cancel Connect.";
+ if (server_socket_ != nullptr) server_socket_->Close();
+ });
+
WifiLanService wifi_lan_service =
static_cast<WifiLanService&>(remote_wifi_lan_service);
auto socket = std::make_unique<WifiLanSocket>(&wifi_lan_service);
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/shared/BUILD b/chromium/third_party/nearby/src/cpp/platform/impl/shared/BUILD
index b2c31460e2d..64f96218639 100644
--- a/chromium/third_party/nearby/src/cpp/platform/impl/shared/BUILD
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/shared/BUILD
@@ -21,7 +21,7 @@ cc_library(
"posix_mutex.h",
],
visibility = [
- "//googlemac/iPhone/Shared/Nearby/Connections:__subpackages__",
+ "//googlemac/iPhone/Shared/Nearby/Connections_v2:__subpackages__",
"//platform/impl:__subpackages__",
],
deps = ["//platform/api:types"],
@@ -36,7 +36,7 @@ cc_library(
"posix_condition_variable.h",
],
visibility = [
- "//googlemac/iPhone/Shared/Nearby/Connections:__subpackages__",
+ "//googlemac/iPhone/Shared/Nearby/Connections_v2:__subpackages__",
],
deps = [
":posix_mutex",
@@ -49,7 +49,7 @@ cc_library(
srcs = ["file.cc"],
hdrs = ["file.h"],
visibility = [
- "//googlemac/iPhone/Shared/Nearby/Connections:__subpackages__",
+ "//googlemac/iPhone/Shared/Nearby/Connections_v2:__subpackages__",
"//platform/impl:__subpackages__",
],
deps = [
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/BUILD b/chromium/third_party/nearby/src/cpp/platform/impl/windows/BUILD
new file mode 100644
index 00000000000..25c2086e04c
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/BUILD
@@ -0,0 +1,104 @@
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+cc_library(
+ name = "types",
+ srcs = [
+ "log_message.cc",
+ "system_clock.cc",
+ ],
+ hdrs = [
+ "atomic_boolean.h",
+ "atomic_reference.h",
+ "cancelable.h",
+ "condition_variable.h",
+ "count_down_latch.h",
+ "executor.h",
+ "future.h",
+ "input_file.h",
+ "listenable_future.h",
+ "log_message.h",
+ "mutex.h",
+ "output_file.h",
+ "scheduled_executor.h",
+ "settable_future.h",
+ "submittable_executor.h",
+ ],
+ deps = [
+ "//platform/api:types",
+ "//platform/base",
+ ],
+)
+
+cc_library(
+ name = "comm",
+ hdrs = [
+ "ble.h",
+ "bluetooth_adapter.h",
+ "bluetooth_classic.h",
+ "server_sync.h",
+ "webrtc.h",
+ "wifi.h",
+ "wifi_lan.h",
+ ],
+ visibility = ["//visibility:private"],
+ deps = [
+ "//platform/api:comm",
+ "//platform/base",
+ ],
+)
+
+cc_library(
+ name = "crypto",
+ srcs = [
+ "crypto.cc",
+ ],
+ visibility = ["//visibility:private"],
+ deps = [
+ "//platform/api:types",
+ "//platform/base",
+ "//absl/strings",
+ "//openssl:crypto",
+ ],
+)
+
+cc_library(
+ name = "windows",
+ srcs = [
+ "platform.cc",
+ ],
+ deps = [
+ ":comm",
+ ":crypto", # build_cleaner: keep
+ ":types",
+ "//platform/api:comm",
+ "//platform/api:platform",
+ "//platform/api:types",
+ ],
+)
+
+cc_test(
+ name = "impl_test",
+ size = "small",
+ srcs = [
+ "crypto_test.cc",
+ ],
+ deps = [
+ ":comm",
+ ":crypto",
+ ":types",
+ "//platform/api:types",
+ "//testing/base/public:gunit_main",
+ ],
+)
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/atomic_boolean.h b/chromium/third_party/nearby/src/cpp/platform/impl/windows/atomic_boolean.h
new file mode 100644
index 00000000000..74239da4d56
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/atomic_boolean.h
@@ -0,0 +1,47 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_IMPL_WINDOWS_ATOMIC_BOOLEAN_H_
+#define PLATFORM_IMPL_WINDOWS_ATOMIC_BOOLEAN_H_
+
+#include "platform/api/atomic_boolean.h"
+
+namespace location {
+namespace nearby {
+namespace windows {
+
+// A boolean value that may be updated atomically.
+class AtomicBoolean : public api::AtomicBoolean {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~AtomicBoolean() override = default;
+
+ // Atomically read and return current value.
+ bool Get() const override {
+ // TODO(b/184975123): replace with real implementation.
+ return false;
+ };
+
+ // Atomically exchange original value with a new one. Return previous value.
+ bool Set(bool value) override {
+ // TODO(b/184975123): replace with real implementation.
+ return false;
+ };
+};
+
+} // namespace windows
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_IMPL_WINDOWS_ATOMIC_BOOLEAN_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/atomic_reference.h b/chromium/third_party/nearby/src/cpp/platform/impl/windows/atomic_reference.h
new file mode 100644
index 00000000000..0653f4a2fa0
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/atomic_reference.h
@@ -0,0 +1,43 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_IMPL_WINDOWS_ATOMIC_REFERENCE_H_
+#define PLATFORM_IMPL_WINDOWS_ATOMIC_REFERENCE_H_
+
+#include "platform/api/atomic_reference.h"
+
+namespace location {
+namespace nearby {
+namespace windows {
+
+// Type that allows 32-bit atomic reads and writes.
+class AtomicUint32 : public api::AtomicUint32 {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~AtomicUint32() override = default;
+
+ // Atomically reads and returns stored value.
+ // TODO(b/184975123): replace with real implementation.
+ std::uint32_t Get() const override { return 0; };
+
+ // Atomically stores value.
+ // TODO(b/184975123): replace with real implementation.
+ void Set(std::uint32_t value) override {}
+};
+
+} // namespace windows
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_IMPL_WINDOWS_ATOMIC_REFERENCE_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/ble.h b/chromium/third_party/nearby/src/cpp/platform/impl/windows/ble.h
new file mode 100644
index 00000000000..4141f732623
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/ble.h
@@ -0,0 +1,155 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_IMPL_WINDOWS_BLE_H_
+#define PLATFORM_IMPL_WINDOWS_BLE_H_
+
+#include "platform/api/ble.h"
+#include "platform/base/exception.h"
+#include "platform/base/input_stream.h"
+#include "platform/base/output_stream.h"
+
+namespace location {
+namespace nearby {
+namespace windows {
+
+// Opaque wrapper over a BLE peripheral. Must contain enough data about a
+// particular BLE device to connect to its GATT server.
+class BlePeripheral : public api::BlePeripheral {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~BlePeripheral() override = default;
+
+ // TODO(b/184975123): replace with real implementation.
+ std::string GetName() const override { return std::string{""}; }
+ // TODO(b/184975123): replace with real implementation.
+ ByteArray GetAdvertisementBytes(
+ const std::string& service_id) const override {
+ return ByteArray{};
+ }
+};
+
+class BleSocket : public api::BleSocket {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~BleSocket() override;
+
+ // Returns the InputStream of the BleSocket.
+ // On error, returned stream will report Exception::kIo on any operation.
+ //
+ // The returned object is not owned by the caller, and can be invalidated once
+ // the BleSocket object is destroyed.
+ // TODO(b/184975123): replace with real implementation.
+ InputStream& GetInputStream() override { return fake_input_stream_; }
+
+ // Returns the OutputStream of the BleSocket.
+ // On error, returned stream will report Exception::kIo on any operation.
+ //
+ // The returned object is not owned by the caller, and can be invalidated once
+ // the BleSocket object is destroyed.
+ // TODO(b/184975123): replace with real implementation.
+ OutputStream& GetOutputStream() override { return fake_output_stream_; }
+
+ // Conforms to the same contract as
+ // https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html#close().
+ //
+ // Returns Exception::kIo on error, Exception::kSuccess otherwise.
+ // TODO(b/184975123): replace with real implementation.
+ Exception Close() override { return Exception{}; }
+
+ // Returns valid BlePeripheral pointer if there is a connection, and
+ // nullptr otherwise.
+ // TODO(b/184975123): replace with real implementation.
+ BlePeripheral* GetRemotePeripheral() override { return nullptr; }
+
+ // Unhooked InputStream & OutputStream for empty implementation.
+ // TODO(b/184975123): replace with real implementation.
+ private:
+ class FakeInputStream : public InputStream {
+ ~FakeInputStream() override = default;
+ ExceptionOr<ByteArray> Read(std::int64_t size) override {
+ return ExceptionOr<ByteArray>(Exception::kFailed);
+ }
+ Exception Close() override { return {.value = Exception::kFailed}; }
+ };
+ class FakeOutputStream : public OutputStream {
+ ~FakeOutputStream() override = default;
+
+ Exception Write(const ByteArray& data) override {
+ return {.value = Exception::kFailed};
+ }
+ Exception Flush() override { return {.value = Exception::kFailed}; }
+ Exception Close() override { return {.value = Exception::kFailed}; }
+ };
+ FakeInputStream fake_input_stream_;
+ FakeOutputStream fake_output_stream_;
+};
+
+// Container of operations that can be performed over the BLE medium.
+class BleMedium : public api::BleMedium {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~BleMedium() override = default;
+
+ // TODO(b/184975123): replace with real implementation.
+ bool StartAdvertising(
+ const std::string& service_id, const ByteArray& advertisement_bytes,
+ const std::string& fast_advertisement_service_uuid) override {
+ return false;
+ }
+ // TODO(b/184975123): replace with real implementation.
+ bool StopAdvertising(const std::string& service_id) override { return false; }
+
+ // Returns true once the BLE scan has been initiated.
+ // TODO(b/184975123): replace with real implementation.
+ bool StartScanning(const std::string& service_id,
+ const std::string& fast_advertisement_service_uuid,
+ DiscoveredPeripheralCallback callback) override {
+ return false;
+ }
+
+ // Returns true once BLE scanning for service_id is well and truly stopped;
+ // after this returns, there must be no more invocations of the
+ // DiscoveredPeripheralCallback passed in to StartScanning() for service_id.
+ // TODO(b/184975123): replace with real implementation.
+ bool StopScanning(const std::string& service_id) override { return false; }
+
+ // Returns true once BLE socket connection requests to service_id can be
+ // accepted.
+ // TODO(b/184975123): replace with real implementation.
+ bool StartAcceptingConnections(const std::string& service_id,
+ AcceptedConnectionCallback callback) override {
+ return false;
+ }
+ // TODO(b/184975123): replace with real implementation.
+ bool StopAcceptingConnections(const std::string& service_id) override {
+ return false;
+ }
+
+ // Connects to a BLE peripheral.
+ // On success, returns a new BleSocket.
+ // On error, returns nullptr.
+ // TODO(b/184975123): replace with real implementation.
+ std::unique_ptr<api::BleSocket> Connect(
+ api::BlePeripheral& peripheral, const std::string& service_id,
+ CancellationFlag* cancellation_flag) override {
+ return nullptr;
+ }
+};
+
+} // namespace windows
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_IMPL_WINDOWS_BLE_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/bluetooth_adapter.h b/chromium/third_party/nearby/src/cpp/platform/impl/windows/bluetooth_adapter.h
new file mode 100644
index 00000000000..60a7e8ebe67
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/bluetooth_adapter.h
@@ -0,0 +1,68 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_IMPL_WINDOWS_BLUETOOTH_ADAPTER_H_
+#define PLATFORM_IMPL_WINDOWS_BLUETOOTH_ADAPTER_H_
+
+#include <string>
+
+#include "platform/api/bluetooth_adapter.h"
+
+namespace location {
+namespace nearby {
+namespace windows {
+
+// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html
+class BluetoothAdapter : public api::BluetoothAdapter {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~BluetoothAdapter() override = default;
+
+ // Synchronously sets the status of the BluetoothAdapter to 'status', and
+ // returns true if the operation was a success.
+ // TODO(b/184975123): replace with real implementation.
+ bool SetStatus(Status status) override { return false; }
+ // Returns true if the BluetoothAdapter's current status is
+ // Status::Value::kEnabled.
+ // TODO(b/184975123): replace with real implementation.
+ bool IsEnabled() const override { return false; }
+
+ // https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#getScanMode()
+ //
+ // Returns ScanMode::kUnknown on error.
+ // TODO(b/184975123): replace with real implementation.
+ ScanMode GetScanMode() const override { return ScanMode::kUnknown; }
+ // Synchronously sets the scan mode of the adapter, and returns true if the
+ // operation was a success.
+ // TODO(b/184975123): replace with real implementation.
+ bool SetScanMode(ScanMode scan_mode) override { return false; }
+
+ // https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#getName()
+ // Returns an empty string on error
+ // TODO(b/184975123): replace with real implementation.
+ std::string GetName() const override { return "Un-implemented"; }
+ // https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#setName(java.lang.String)
+ // TODO(b/184975123): replace with real implementation.
+ bool SetName(absl::string_view name) override { return false; }
+
+ // Returns BT MAC address assigned to this adapter.
+ // TODO(b/184975123): replace with real implementation.
+ std::string GetMacAddress() const override { return "Un-implemented"; }
+};
+
+} // namespace windows
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_IMPL_WINDOWS_BLUETOOTH_ADAPTER_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/bluetooth_classic.h b/chromium/third_party/nearby/src/cpp/platform/impl/windows/bluetooth_classic.h
new file mode 100644
index 00000000000..7681e7105af
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/bluetooth_classic.h
@@ -0,0 +1,186 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_H_
+#define PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_H_
+
+#include "platform/api/bluetooth_classic.h"
+#include "platform/base/exception.h"
+#include "platform/base/input_stream.h"
+#include "platform/base/output_stream.h"
+namespace location {
+namespace nearby {
+namespace windows {
+
+// https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html.
+class BluetoothDevice : public api::BluetoothDevice {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~BluetoothDevice() override = default;
+
+ // https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#getName()
+ // TODO(b/184975123): replace with real implementation.
+ std::string GetName() const override { return "Un-implemented"; }
+
+ // Returns BT MAC address assigned to this device.
+ // TODO(b/184975123): replace with real implementation.
+ std::string GetMacAddress() const override { return "Un-implemented"; }
+};
+
+// https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html.
+class BluetoothSocket : public api::BluetoothSocket {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~BluetoothSocket() override;
+
+ // NOTE:
+ // It is an undefined behavior if GetInputStream() or GetOutputStream() is
+ // called for a not-connected BluetoothSocket, i.e. any object that is not
+ // returned by BluetoothClassicMedium::ConnectToService() for client side or
+ // BluetoothServerSocket::Accept() for server side of connection.
+
+ // Returns the InputStream of this connected BluetoothSocket.
+ // TODO(b/184975123): replace with real implementation.
+ InputStream& GetInputStream() override { return fake_input_stream_; }
+
+ // Returns the OutputStream of this connected BluetoothSocket.
+ // TODO(b/184975123): replace with real implementation.
+ OutputStream& GetOutputStream() override { return fake_output_stream_; }
+
+ // Closes both input and output streams, marks Socket as closed.
+ // After this call object should be treated as not connected.
+ // Returns Exception::kIo on error, Exception::kSuccess otherwise.
+ // TODO(b/184975123): replace with real implementation.
+ Exception Close() override { return Exception{}; }
+
+ // https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html#getRemoteDevice()
+ // Returns valid BluetoothDevice pointer if there is a connection, and
+ // nullptr otherwise.
+ // TODO(b/184975123): replace with real implementation.
+ BluetoothDevice* GetRemoteDevice() override { return nullptr; }
+
+ private:
+ class FakeInputStream : public InputStream {
+ ~FakeInputStream() override = default;
+ ExceptionOr<ByteArray> Read(std::int64_t size) override {
+ return ExceptionOr<ByteArray>(Exception::kFailed);
+ }
+ Exception Close() override { return {.value = Exception::kFailed}; }
+ };
+ class FakeOutputStream : public OutputStream {
+ ~FakeOutputStream() override = default;
+
+ Exception Write(const ByteArray& data) override {
+ return {.value = Exception::kFailed};
+ }
+ Exception Flush() override { return {.value = Exception::kFailed}; }
+ Exception Close() override { return {.value = Exception::kFailed}; }
+ };
+ FakeInputStream fake_input_stream_;
+ FakeOutputStream fake_output_stream_;
+};
+
+// https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html.
+class BluetoothServerSocket : public api::BluetoothServerSocket {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~BluetoothServerSocket() override = default;
+
+ // https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html#accept()
+ //
+ // Blocks until either:
+ // - at least one incoming connection request is available, or
+ // - ServerSocket is closed.
+ // On success, returns connected socket, ready to exchange data.
+ // Returns nullptr on error.
+ // Once error is reported, it is permanent, and ServerSocket has to be closed.
+ // TODO(b/184975123): replace with real implementation.
+ std::unique_ptr<api::BluetoothSocket> Accept() override { return nullptr; }
+
+ // https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html#close()
+ //
+ // Returns Exception::kIo on error, Exception::kSuccess otherwise.
+ // TODO(b/184975123): replace with real implementation.
+ Exception Close() override { return Exception{}; }
+};
+
+// Container of operations that can be performed over the Bluetooth Classic
+// medium.
+class BluetoothClassicMedium : public api::BluetoothClassicMedium {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~BluetoothClassicMedium() override = default;
+
+ // https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#startDiscovery()
+ //
+ // Returns true once the process of discovery has been initiated.
+ // TODO(b/184975123): replace with real implementation.
+ bool StartDiscovery(DiscoveryCallback discovery_callback) override {
+ return false;
+ }
+ // https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#cancelDiscovery()
+ //
+ // Returns true once discovery is well and truly stopped; after this returns,
+ // there must be no more invocations of the DiscoveryCallback passed in to
+ // StartDiscovery().
+ // TODO(b/184975123): replace with real implementation.
+ bool StopDiscovery() override { return false; }
+
+ // A combination of
+ // https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#createInsecureRfcommSocketToServiceRecord
+ // followed by
+ // https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html#connect().
+ //
+ // service_uuid is the canonical textual representation
+ // (https://en.wikipedia.org/wiki/Universally_unique_identifier#Format) of a
+ // type 3 name-based
+ // (https://en.wikipedia.org/wiki/Universally_unique_identifier#Versions_3_and_5_(namespace_name-based))
+ // UUID.
+ //
+ // On success, returns a new BluetoothSocket.
+ // On error, returns nullptr.
+ // TODO(b/184975123): replace with real implementation.
+ std::unique_ptr<api::BluetoothSocket> ConnectToService(
+ api::BluetoothDevice& remote_device, const std::string& service_uuid,
+ CancellationFlag* cancellation_flag) override {
+ return nullptr;
+ }
+
+ // https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#listenUsingInsecureRfcommWithServiceRecord
+ //
+ // service_uuid is the canonical textual representation
+ // (https://en.wikipedia.org/wiki/Universally_unique_identifier#Format) of a
+ // type 3 name-based
+ // (https://en.wikipedia.org/wiki/Universally_unique_identifier#Versions_3_and_5_(namespace_name-based))
+ // UUID.
+ //
+ // Returns nullptr error.
+ // TODO(b/184975123): replace with real implementation.
+ std::unique_ptr<api::BluetoothServerSocket> ListenForService(
+ const std::string& service_name,
+ const std::string& service_uuid) override {
+ return nullptr;
+ }
+
+ // TODO(b/184975123): replace with real implementation.
+ BluetoothDevice* GetRemoteDevice(const std::string& mac_address) override {
+ return nullptr;
+ }
+};
+
+} // namespace windows
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/cancelable.h b/chromium/third_party/nearby/src/cpp/platform/impl/windows/cancelable.h
new file mode 100644
index 00000000000..b538ea5e2e1
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/cancelable.h
@@ -0,0 +1,39 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_IMPL_WINDOWS_CANCELABLE_H_
+#define PLATFORM_IMPL_WINDOWS_CANCELABLE_H_
+
+#include "platform/api/cancelable.h"
+
+namespace location {
+namespace nearby {
+namespace windows {
+
+// An interface to provide a cancellation mechanism for objects that represent
+// long-running operations.
+class Cancelable : public api::Cancelable {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~Cancelable() override = default;
+
+ // TODO(b/184975123): replace with real implementation.
+ bool Cancel() override { return false; };
+};
+
+} // namespace windows
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_IMPL_WINDOWS_CANCELABLE_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/condition_variable.h b/chromium/third_party/nearby/src/cpp/platform/impl/windows/condition_variable.h
new file mode 100644
index 00000000000..cd8c75d483f
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/condition_variable.h
@@ -0,0 +1,54 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_IMPL_WINDOWS_CONDITION_VARIABLE_H_
+#define PLATFORM_IMPL_WINDOWS_CONDITION_VARIABLE_H_
+
+#include "platform/api/condition_variable.h"
+
+namespace location {
+namespace nearby {
+namespace windows {
+
+// The ConditionVariable class is a synchronization primitive that can be used
+// to block a thread, or multiple threads at the same time, until another thread
+// both modifies a shared variable (the condition), and notifies the
+// ConditionVariable.
+class ConditionVariable : public api::ConditionVariable {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~ConditionVariable() override = default;
+
+ // Notifies all the waiters that condition state has changed.
+ // TODO(b/184975123): replace with real implementation.
+ void Notify() override {}
+
+ // Waits indefinitely for Notify to be called.
+ // May return prematurely in case of interrupt, if supported by platform.
+ // Returns kSuccess, or kInterrupted on interrupt.
+ // TODO(b/184975123): replace with real implementation.
+ Exception Wait() override { return Exception{}; }
+
+ // Waits while timeout has not expired for Notify to be called.
+ // May return prematurely in case of interrupt, if supported by platform.
+ // Returns kSuccess, or kInterrupted on interrupt.
+ // TODO(b/184975123): replace with real implementation.
+ Exception Wait(absl::Duration timeout) override { return Exception{}; }
+};
+
+} // namespace windows
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_IMPL_WINDOWS_CONDITION_VARIABLE_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/count_down_latch.h b/chromium/third_party/nearby/src/cpp/platform/impl/windows/count_down_latch.h
new file mode 100644
index 00000000000..bacac4b7865
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/count_down_latch.h
@@ -0,0 +1,47 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_IMPL_WINDOWS_COUNT_DOWN_LATCH_H_
+#define PLATFORM_IMPL_WINDOWS_COUNT_DOWN_LATCH_H_
+
+#include "platform/api/count_down_latch.h"
+
+namespace location {
+namespace nearby {
+namespace windows {
+
+// A synchronization aid that allows one or more threads to wait until a set of
+// operations being performed in other threads completes.
+//
+// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CountDownLatch.html
+class CountDownLatch : public api::CountDownLatch {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~CountDownLatch() override = default;
+
+ // TODO(b/184975123): replace with real implementation.
+ Exception Await() override { return Exception{}; }
+ // TODO(b/184975123): replace with real implementation.
+ ExceptionOr<bool> Await(absl::Duration timeout) override {
+ return Exception{};
+ }
+ // TODO(b/184975123): replace with real implementation.
+ void CountDown() override{};
+};
+
+} // namespace windows
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_IMPL_WINDOWS_COUNT_DOWN_LATCH_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/crypto.cc b/chromium/third_party/nearby/src/cpp/platform/impl/windows/crypto.cc
new file mode 100644
index 00000000000..263bec273b4
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/crypto.cc
@@ -0,0 +1,54 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "platform/api/crypto.h"
+
+#include <cstdint>
+#include <string>
+
+#include "platform/base/byte_array.h"
+#include "absl/strings/string_view.h"
+#include "openssl/digest.h"
+
+// Function implementations for platform/api/crypto.h.
+namespace location {
+namespace nearby {
+
+// Initialize global crypto state.
+void Crypto::Init() {}
+
+static ByteArray Hash(absl::string_view input, const EVP_MD* algo) {
+ unsigned int md_out_size = EVP_MAX_MD_SIZE;
+ uint8_t digest_buffer[EVP_MAX_MD_SIZE];
+ if (input.empty()) return {};
+
+ if (!EVP_Digest(input.data(), input.size(), digest_buffer, &md_out_size, algo,
+ nullptr))
+ return {};
+
+ return ByteArray{reinterpret_cast<char*>(digest_buffer), md_out_size};
+}
+
+// Return MD5 hash of input.
+ByteArray Crypto::Md5(absl::string_view input) {
+ return Hash(input, EVP_md5());
+}
+
+// Return SHA256 hash of input.
+ByteArray Crypto::Sha256(absl::string_view input) {
+ return Hash(input, EVP_sha256());
+}
+
+} // namespace nearby
+} // namespace location
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/crypto_test.cc b/chromium/third_party/nearby/src/cpp/platform/impl/windows/crypto_test.cc
new file mode 100644
index 00000000000..5276a9e6f05
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/crypto_test.cc
@@ -0,0 +1,50 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "platform/api/crypto.h"
+
+#include "gtest/gtest.h"
+
+namespace location {
+namespace nearby {
+namespace {
+
+TEST(CryptoTest, Md5Hash) {
+ const std::string input{"Hello Nearby Connection"};
+ const ByteArray expected_md5(
+ "\x94\xa3\xbe\xc1\x8d\x30\xe3\x24\x5f\xa1\x4c\xee\xe7\x52\xe9\x36");
+ ByteArray md5_hash = Crypto::Md5(input);
+ EXPECT_EQ(md5_hash, expected_md5);
+}
+
+TEST(CryptoTest, Md5HashOnEmptyInput) {
+ EXPECT_EQ(Crypto::Md5(""), ByteArray{});
+}
+
+TEST(CryptoTest, Sha256Hash) {
+ const std::string input("Hello Nearby Connection");
+ const ByteArray expected_sha256(
+ "\xb4\x24\xd3\xc0\x58\x12\x9a\x42\xcb\x81\xa0\x4b\x6e\x9d\xfe\x45\x45\x9f"
+ "\x15\xf7\xc0\xa9\x32\x2f\xfb\x9\x45\xf0\xf9\xbe\x75\xb");
+ ByteArray sha256_hash = Crypto::Sha256(input);
+ EXPECT_EQ(sha256_hash, expected_sha256);
+}
+
+TEST(CryptoTest, Sha256HashOnEmptyInput) {
+ EXPECT_EQ(Crypto::Sha256(""), ByteArray{});
+}
+
+} // namespace
+} // namespace nearby
+} // namespace location
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/executor.h b/chromium/third_party/nearby/src/cpp/platform/impl/windows/executor.h
new file mode 100644
index 00000000000..4f521368a14
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/executor.h
@@ -0,0 +1,48 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_IMPL_WINDOWS_EXECUTOR_H_
+#define PLATFORM_IMPL_WINDOWS_EXECUTOR_H_
+
+#include "platform/api/executor.h"
+
+namespace location {
+namespace nearby {
+namespace windows {
+
+// This abstract class is the superclass of all classes representing an
+// Executor.
+class Executor : public api::Executor {
+ public:
+ // Before returning from destructor, executor must wait for all pending
+ // jobs to finish.
+ // TODO(b/184975123): replace with real implementation.
+ ~Executor() override = default;
+ // https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html#execute-java.lang.Runnable-
+ // TODO(b/184975123): replace with real implementation.
+ void Execute(Runnable&& runnable) override {}
+
+ // https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#shutdown--
+ // TODO(b/184975123): replace with real implementation.
+ void Shutdown() override {}
+
+ // TODO(b/184975123): replace with real implementation.
+ int GetTid(int index) const override { return 0; }
+};
+
+} // namespace windows
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_IMPL_WINDOWS_EXECUTOR_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/future.h b/chromium/third_party/nearby/src/cpp/platform/impl/windows/future.h
new file mode 100644
index 00000000000..6dee7e37f65
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/future.h
@@ -0,0 +1,50 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_IMPL_WINDOWS_FUTURE_H_
+#define PLATFORM_IMPL_WINDOWS_FUTURE_H_
+
+#include "platform/api/future.h"
+
+namespace location {
+namespace nearby {
+namespace windows {
+
+// A Future represents the result of an asynchronous computation.
+//
+// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Future.html
+template <typename T>
+class Future : public api::Future<T> {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~Future() override = default;
+
+ // throws Exception::kInterrupted, Exception::kExecution
+ // TODO(b/184975123): replace with real implementation.
+ ExceptionOr<T> Get() override { return ExceptionOr<T>{Exception::kFailed}; }
+
+ // throws Exception::kInterrupted, Exception::kExecution
+ // throws Exception::kTimeout if timeout is exceeded while waiting for
+ // result.
+ // TODO(b/184975123): replace with real implementation.
+ ExceptionOr<T> Get(absl::Duration timeout) override {
+ return ExceptionOr<T>{Exception::kFailed};
+ }
+};
+
+} // namespace windows
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_IMPL_WINDOWS_FUTURE_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/input_file.h b/chromium/third_party/nearby/src/cpp/platform/impl/windows/input_file.h
new file mode 100644
index 00000000000..1ed3982141c
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/input_file.h
@@ -0,0 +1,50 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_IMPL_WINDOWS_INPUT_FILE_H_
+#define PLATFORM_IMPL_WINDOWS_INPUT_FILE_H_
+
+#include "platform/api/input_file.h"
+#include "platform/base/byte_array.h"
+#include "platform/base/exception.h"
+
+namespace location {
+namespace nearby {
+namespace windows {
+
+// An InputFile represents a readable file on the system.
+class InputFile : public api::InputFile {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~InputFile() override = default;
+ // TODO(b/184975123): replace with real implementation.
+ std::string GetFilePath() const override { return "Un-implemented"; }
+ // TODO(b/184975123): replace with real implementation.
+ std::int64_t GetTotalSize() const override { return 0; }
+
+ // throws Exception::kIo
+ // TODO(b/184975123): replace with real implementation.
+ ExceptionOr<ByteArray> Read(std::int64_t size) override {
+ return ExceptionOr<ByteArray>(Exception::kFailed);
+ }
+ // throws Exception::kIo
+ // TODO(b/184975123): replace with real implementation.
+ Exception Close() override { return Exception{}; }
+};
+
+} // namespace windows
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_IMPL_WINDOWS_INPUT_FILE_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/listenable_future.h b/chromium/third_party/nearby/src/cpp/platform/impl/windows/listenable_future.h
new file mode 100644
index 00000000000..954fe01badb
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/listenable_future.h
@@ -0,0 +1,41 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_IMPL_WINDOWS_LISTENABLE_FUTURE_H_
+#define PLATFORM_IMPL_WINDOWS_LISTENABLE_FUTURE_H_
+
+#include "platform/api/listenable_future.h"
+
+namespace location {
+namespace nearby {
+namespace windows {
+
+// A Future that accepts completion listeners.
+//
+// https://guava.dev/releases/20.0/api/docs/com/google/common/util/concurrent/ListenableFuture.html
+template <typename T>
+class ListenableFuture : public api::ListenableFuture<T> {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~ListenableFuture() override = default;
+
+ // TODO(b/184975123): replace with real implementation.
+ void AddListener(Runnable runnable, api::Executor* executor) {}
+};
+
+} // namespace windows
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_IMPL_WINDOWS_LISTENABLE_FUTURE_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/log_message.cc b/chromium/third_party/nearby/src/cpp/platform/impl/windows/log_message.cc
new file mode 100644
index 00000000000..f220176f561
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/log_message.cc
@@ -0,0 +1,29 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "platform/impl/windows/log_message.h"
+
+namespace location {
+namespace nearby {
+namespace api {
+
+// TODO(b/184975123): replace with real implementation.
+void LogMessage::SetMinLogSeverity(Severity severity) {}
+
+// TODO(b/184975123): replace with real implementation.
+bool LogMessage::ShouldCreateLogMessage(Severity severity) { return false; }
+
+} // namespace api
+} // namespace nearby
+} // namespace location
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/log_message.h b/chromium/third_party/nearby/src/cpp/platform/impl/windows/log_message.h
new file mode 100644
index 00000000000..2fd5308c06c
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/log_message.h
@@ -0,0 +1,50 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_IMPL_WINDOWS_LOG_MESSAGE_H_
+#define PLATFORM_IMPL_WINDOWS_LOG_MESSAGE_H_
+
+#include "platform/api/log_message.h"
+
+namespace location {
+namespace nearby {
+namespace windows {
+
+// A log message that prints to appropraite destination when ~LogMessage() is
+// called.
+//
+// note: the Severity enum should map (best effort) to the corresponding level
+// id that the platform logging implementation has.
+class LogMessage : public api::LogMessage {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~LogMessage() override = default;
+
+ // Printf like logging.
+ // TODO(b/184975123): replace with real implementation.
+ void Print(const char* format, ...) override {}
+
+ // Returns a stream for std::cout like logging.
+ // TODO(b/184975123): replace with real implementation.
+ std::ostream& Stream() override { return empty_stream_; }
+
+ // TODO(b/184975123): replace with real implementation.
+ std::ostream empty_stream_;
+};
+
+} // namespace windows
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_IMPL_WINDOWS_LOG_MESSAGE_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/mutex.h b/chromium/third_party/nearby/src/cpp/platform/impl/windows/mutex.h
new file mode 100644
index 00000000000..2fee6a2f861
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/mutex.h
@@ -0,0 +1,43 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_IMPL_WINDOWS_MUTEX_H_
+#define PLATFORM_IMPL_WINDOWS_MUTEX_H_
+
+#include "platform/api/mutex.h"
+
+namespace location {
+namespace nearby {
+namespace windows {
+
+// A lock is a tool for controlling access to a shared resource by multiple
+// threads.
+//
+// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/Lock.html
+class Mutex : public api::Mutex {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~Mutex() override = default;
+
+ // TODO(b/184975123): replace with real implementation.
+ void Lock() override {}
+ // TODO(b/184975123): replace with real implementation.
+ void Unlock() override {}
+};
+
+} // namespace windows
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_IMPL_WINDOWS_MUTEX_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/output_file.h b/chromium/third_party/nearby/src/cpp/platform/impl/windows/output_file.h
new file mode 100644
index 00000000000..9ad479b6c1b
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/output_file.h
@@ -0,0 +1,47 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_IMPL_WINDOWS_OUTPUT_FILE_H_
+#define PLATFORM_IMPL_WINDOWS_OUTPUT_FILE_H_
+
+#include "platform/api/output_file.h"
+#include "platform/base/byte_array.h"
+#include "platform/base/exception.h"
+
+namespace location {
+namespace nearby {
+namespace windows {
+
+// An OutputFile represents a writable file on the system.
+class OutputFile : public api::OutputFile {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~OutputFile() override = default;
+
+ // throws Exception::kIo
+ // TODO(b/184975123): replace with real implementation.
+ Exception Write(const ByteArray& data) override { return Exception{}; }
+ // throws Exception::kIo
+ // TODO(b/184975123): replace with real implementation.
+ Exception Flush() override { return Exception{}; }
+ // throws Exception::kIo
+ // TODO(b/184975123): replace with real implementation.
+ Exception Close() override { return Exception{}; }
+};
+
+} // namespace windows
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_IMPL_WINDOWS_OUTPUT_FILE_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/platform.cc b/chromium/third_party/nearby/src/cpp/platform/impl/windows/platform.cc
new file mode 100644
index 00000000000..e8f3372db6e
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/platform.cc
@@ -0,0 +1,158 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "platform/api/platform.h"
+
+#include "platform/impl/windows/atomic_boolean.h"
+#include "platform/impl/windows/atomic_reference.h"
+#include "platform/impl/windows/ble.h"
+#include "platform/impl/windows/bluetooth_adapter.h"
+#include "platform/impl/windows/bluetooth_classic.h"
+#include "platform/impl/windows/cancelable.h"
+#include "platform/impl/windows/condition_variable.h"
+#include "platform/impl/windows/count_down_latch.h"
+#include "platform/impl/windows/executor.h"
+#include "platform/impl/windows/future.h"
+#include "platform/impl/windows/input_file.h"
+#include "platform/impl/windows/listenable_future.h"
+#include "platform/impl/windows/log_message.h"
+#include "platform/impl/windows/mutex.h"
+#include "platform/impl/windows/output_file.h"
+#include "platform/impl/windows/scheduled_executor.h"
+#include "platform/impl/windows/server_sync.h"
+#include "platform/impl/windows/settable_future.h"
+#include "platform/impl/windows/submittable_executor.h"
+#include "platform/impl/windows/webrtc.h"
+#include "platform/impl/windows/wifi.h"
+#include "platform/impl/windows/wifi_lan.h"
+
+namespace location {
+namespace nearby {
+namespace api {
+
+// TODO(b/184975123): replace with real implementation.
+std::unique_ptr<AtomicBoolean> ImplementationPlatform::CreateAtomicBoolean(
+ bool initial_value) {
+ return absl::make_unique<windows::AtomicBoolean>();
+}
+
+// TODO(b/184975123): replace with real implementation.
+std::unique_ptr<AtomicUint32> ImplementationPlatform::CreateAtomicUint32(
+ std::uint32_t value) {
+ return absl::make_unique<windows::AtomicUint32>();
+}
+
+// TODO(b/184975123): replace with real implementation.
+std::unique_ptr<CountDownLatch> ImplementationPlatform::CreateCountDownLatch(
+ std::int32_t count) {
+ return absl::make_unique<windows::CountDownLatch>();
+}
+
+// TODO(b/184975123): replace with real implementation.
+std::unique_ptr<Mutex> ImplementationPlatform::CreateMutex(Mutex::Mode mode) {
+ return absl::make_unique<windows::Mutex>();
+}
+
+// TODO(b/184975123): replace with real implementation.
+std::unique_ptr<ConditionVariable>
+ImplementationPlatform::CreateConditionVariable(Mutex* mutex) {
+ return std::unique_ptr<ConditionVariable>(new windows::ConditionVariable());
+}
+
+// TODO(b/184975123): replace with real implementation.
+std::unique_ptr<InputFile> ImplementationPlatform::CreateInputFile(
+ PayloadId payload_id, std::int64_t total_size) {
+ return absl::make_unique<windows::InputFile>();
+}
+
+// TODO(b/184975123): replace with real implementation.
+std::unique_ptr<OutputFile> ImplementationPlatform::CreateOutputFile(
+ PayloadId payload_id) {
+ return absl::make_unique<windows::OutputFile>();
+}
+
+// TODO(b/184975123): replace with real implementation.
+std::unique_ptr<LogMessage> ImplementationPlatform::CreateLogMessage(
+ const char* file, int line, LogMessage::Severity severity) {
+ return nullptr;
+}
+
+// TODO(b/184975123): replace with real implementation.
+std::unique_ptr<SubmittableExecutor>
+ImplementationPlatform::CreateSingleThreadExecutor() {
+ return absl::make_unique<windows::SubmittableExecutor>();
+}
+
+// TODO(b/184975123): replace with real implementation.
+std::unique_ptr<SubmittableExecutor>
+ImplementationPlatform::CreateMultiThreadExecutor(
+ std::int32_t max_concurrency) {
+ return absl::make_unique<windows::SubmittableExecutor>();
+}
+
+// TODO(b/184975123): replace with real implementation.
+std::unique_ptr<ScheduledExecutor>
+ImplementationPlatform::CreateScheduledExecutor() {
+ return absl::make_unique<windows::ScheduledExecutor>();
+}
+
+// TODO(b/184975123): replace with real implementation.
+std::unique_ptr<BluetoothAdapter>
+ImplementationPlatform::CreateBluetoothAdapter() {
+ return absl::make_unique<windows::BluetoothAdapter>();
+}
+
+// TODO(b/184975123): replace with real implementation.
+std::unique_ptr<BluetoothClassicMedium>
+ImplementationPlatform::CreateBluetoothClassicMedium(
+ BluetoothAdapter& adapter) {
+ return absl::make_unique<windows::BluetoothClassicMedium>();
+}
+
+// TODO(b/184975123): replace with real implementation.
+std::unique_ptr<BleMedium> ImplementationPlatform::CreateBleMedium(
+ BluetoothAdapter& adapter) {
+ return absl::make_unique<windows::BleMedium>();
+}
+
+// TODO(b/184975123): replace with real implementation.
+std::unique_ptr<ble_v2::BleMedium> ImplementationPlatform::CreateBleV2Medium(
+ BluetoothAdapter&) {
+ return nullptr;
+}
+
+// TODO(b/184975123): replace with real implementation.
+std::unique_ptr<ServerSyncMedium>
+ImplementationPlatform::CreateServerSyncMedium() {
+ return std::unique_ptr<windows::ServerSyncMedium>();
+}
+
+// TODO(b/184975123): replace with real implementation.
+std::unique_ptr<WifiMedium> ImplementationPlatform::CreateWifiMedium() {
+ return std::unique_ptr<WifiMedium>();
+}
+
+// TODO(b/184975123): replace with real implementation.
+std::unique_ptr<WifiLanMedium> ImplementationPlatform::CreateWifiLanMedium() {
+ return absl::make_unique<windows::WifiLanMedium>();
+}
+
+// TODO(b/184975123): replace with real implementation.
+std::unique_ptr<WebRtcMedium> ImplementationPlatform::CreateWebRtcMedium() {
+ return absl::make_unique<windows::WebRtcMedium>();
+}
+
+} // namespace api
+} // namespace nearby
+} // namespace location
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/scheduled_executor.h b/chromium/third_party/nearby/src/cpp/platform/impl/windows/scheduled_executor.h
new file mode 100644
index 00000000000..a1e6122780f
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/scheduled_executor.h
@@ -0,0 +1,59 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_IMPL_WINDOWS_SCHEDULED_EXECUTOR_H_
+#define PLATFORM_IMPL_WINDOWS_SCHEDULED_EXECUTOR_H_
+
+#include "platform/api/scheduled_executor.h"
+
+namespace location {
+namespace nearby {
+namespace windows {
+
+// An Executor that can schedule commands to run after a given delay, or to
+// execute periodically.
+//
+// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ScheduledExecutorService.html
+class ScheduledExecutor : public api::ScheduledExecutor {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~ScheduledExecutor() override = default;
+
+ // Cancelable is kept both in the executor context, and in the caller context.
+ // We want Cancelable to live until both caller and executor are done with it.
+ // Exclusive ownership model does not work for this case;
+ // using std:shared_ptr<> instead if std::unique_ptr<>.
+ // TODO(b/184975123): replace with real implementation.
+ std::shared_ptr<api::Cancelable> Schedule(Runnable&& runnable,
+ absl::Duration duration) override {
+ return nullptr;
+ }
+
+ // https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html#execute-java.lang.Runnable-
+ // TODO(b/184975123): replace with real implementation.
+ void Execute(Runnable&& runnable) override {}
+
+ // https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#shutdown--
+ // TODO(b/184975123): replace with real implementation.
+ void Shutdown() override {}
+
+ // TODO(b/184975123): replace with real implementation.
+ int GetTid(int index) const override { return 0; }
+};
+
+} // namespace windows
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_IMPL_WINDOWS_SCHEDULED_EXECUTOR_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/server_sync.h b/chromium/third_party/nearby/src/cpp/platform/impl/windows/server_sync.h
new file mode 100644
index 00000000000..ec59745f365
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/server_sync.h
@@ -0,0 +1,90 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_IMPL_WINDOWS_SERVER_SYNC_H_
+#define PLATFORM_IMPL_WINDOWS_SERVER_SYNC_H_
+
+#include "platform/api/server_sync.h"
+
+namespace location {
+namespace nearby {
+namespace windows {
+
+// Abstraction that represents a Nearby endpoint exchanging data through
+// ServerSync Medium.
+class ServerSyncDevice : public api::ServerSyncDevice {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~ServerSyncDevice() override = default;
+
+ // TODO(b/184975123): replace with real implementation.
+ std::string GetName() const override { return "Un-implemented"; }
+ // TODO(b/184975123): replace with real implementation.
+ std::string GetGuid() const override { return "Un-implemented"; }
+ // TODO(b/184975123): replace with real implementation.
+ std::string GetOwnGuid() const override { return "Un-implemented"; }
+};
+
+// Container of operations that can be performed over the Chrome Sync medium.
+class ServerSyncMedium : public api::ServerSyncMedium {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~ServerSyncMedium() override = default;
+
+ // TODO(b/184975123): replace with real implementation.
+ bool StartAdvertising(absl::string_view service_id,
+ absl::string_view endpoint_id,
+ const ByteArray& endpoint_info) override {
+ return false;
+ }
+ // TODO(b/184975123): replace with real implementation.
+ void StopAdvertising(absl::string_view service_id) override {}
+
+ class DiscoveredDeviceCallback
+ : public api::ServerSyncMedium::DiscoveredDeviceCallback {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~DiscoveredDeviceCallback() override = default;
+
+ // Called on a new ServerSyncDevice discovery.
+ // TODO(b/184975123): replace with real implementation.
+ void OnDeviceDiscovered(api::ServerSyncDevice* device,
+ absl::string_view service_id,
+ absl::string_view endpoint_id,
+ const ByteArray& endpoint_info) override {}
+ // Called when ServerSyncDevice is no longer reachable.
+ // TODO(b/184975123): replace with real implementation.
+ void OnDeviceLost(api::ServerSyncDevice* device,
+ absl::string_view service_id) override {}
+ };
+
+ // Returns true once the Chrome Sync scan has been initiated.
+ // TODO(b/184975123): replace with real implementation.
+ bool StartDiscovery(absl::string_view service_id,
+ const api::ServerSyncMedium::DiscoveredDeviceCallback&
+ discovered_device_callback) override {
+ return false;
+ }
+ // Returns true once Chrome Sync scan for service_id is well and truly
+ // stopped; after this returns, there must be no more invocations of the
+ // DiscoveredDeviceCallback passed in to startScanning() for service_id.
+ // TODO(b/184975123): replace with real implementation.
+ void StopDiscovery(absl::string_view service_id) override {}
+};
+
+} // namespace windows
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_IMPL_WINDOWS_SERVER_SYNC_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/settable_future.h b/chromium/third_party/nearby/src/cpp/platform/impl/windows/settable_future.h
new file mode 100644
index 00000000000..99f9a02c059
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/settable_future.h
@@ -0,0 +1,51 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_IMPL_WINDOWS_SETTABLE_FUTURE_H_
+#define PLATFORM_IMPL_WINDOWS_SETTABLE_FUTURE_H_
+
+#include "platform/api/settable_future.h"
+
+namespace location {
+namespace nearby {
+namespace windows {
+
+// A SettableFuture is a type of Future whose result can be set.
+//
+// https://google.github.io/guava/releases/20.0/api/docs/com/google/common/util/concurrent/SettableFuture.html
+template <typename T>
+class SettableFuture : public api::SettableFuture<T> {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~SettableFuture() override = default;
+
+ // Completes the future successfully. The value is returned to any waiters.
+ // Returns true, if value was set.
+ // Returns false, if Future is already in "done" state.
+ // TODO(b/184975123): replace with real implementation.
+ bool Set(T value) override { return false; }
+
+ // Completes the future unsuccessfully. The exception value is returned to any
+ // waiters.
+ // Returns true, if exception was set.
+ // Returns false, if Future is already in "done" state.
+ // TODO(b/184975123): replace with real implementation.
+ bool SetException(Exception exception) override { return false; }
+};
+
+} // namespace windows
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_IMPL_WINDOWS_SETTABLE_FUTURE_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/submittable_executor.h b/chromium/third_party/nearby/src/cpp/platform/impl/windows/submittable_executor.h
new file mode 100644
index 00000000000..9533a5e906d
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/submittable_executor.h
@@ -0,0 +1,55 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_IMPL_WINDOWS_SUBMITTABLE_EXECUTOR_H_
+#define PLATFORM_IMPL_WINDOWS_SUBMITTABLE_EXECUTOR_H_
+
+#include "platform/api/submittable_executor.h"
+
+namespace location {
+namespace nearby {
+namespace windows {
+
+// Main interface to be used by platform as a base class for
+// - MultiThreadExecutorWrapper
+// - SingleThreadExecutorWrapper
+// Platform must override bool submit(std::function<void()>) method.
+class SubmittableExecutor : public api::SubmittableExecutor {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~SubmittableExecutor() override = default;
+
+ // Submit a callable (with no delay).
+ // Returns true, if callable was submitted, false otherwise.
+ // Callable is not submitted if shutdown is in progress.
+ // TODO(b/184975123): replace with real implementation.
+ bool DoSubmit(Runnable&& wrapped_callable) override { return false; }
+
+ // https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html#execute-java.lang.Runnable-
+ // TODO(b/184975123): replace with real implementation.
+ void Execute(Runnable&& runnable) override {}
+
+ // https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#shutdown--
+ // TODO(b/184975123): replace with real implementation.
+ void Shutdown() override {}
+
+ // TODO(b/184975123): replace with real implementation.
+ int GetTid(int index) const override { return 0; }
+};
+
+} // namespace windows
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_IMPL_WINDOWS_SUBMITTABLE_EXECUTOR_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/system_clock.cc b/chromium/third_party/nearby/src/cpp/platform/impl/windows/system_clock.cc
new file mode 100644
index 00000000000..7da94eb8683
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/system_clock.cc
@@ -0,0 +1,36 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_IMPL_WINDOWS_SYSTEM_CLOCK_H_
+#define PLATFORM_IMPL_WINDOWS_SYSTEM_CLOCK_H_
+
+#include "platform/api/system_clock.h"
+
+namespace location {
+namespace nearby {
+
+// Initialize global system state.
+// TODO(b/184975123): replace with real implementation.
+void SystemClock::Init() {}
+// Returns current absolute time. It is guaranteed to be monotonic.
+// TODO(b/184975123): replace with real implementation.
+absl::Time SystemClock::ElapsedRealtime() { return absl::UnixEpoch(); }
+// Pauses current thread for the specified duration.
+// TODO(b/184975123): replace with real implementation.
+Exception SystemClock::Sleep(absl::Duration duration) { return Exception{}; }
+
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_IMPL_WINDOWS_SYSTEM_CLOCK_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/webrtc.h b/chromium/third_party/nearby/src/cpp/platform/impl/windows/webrtc.h
new file mode 100644
index 00000000000..24aa5a92466
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/webrtc.h
@@ -0,0 +1,78 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_IMPL_WINDOWS_WEBRTC_H_
+#define PLATFORM_IMPL_WINDOWS_WEBRTC_H_
+
+#include "platform/api/webrtc.h"
+
+namespace location {
+namespace nearby {
+namespace windows {
+
+class WebRtcSignalingMessenger : public api::WebRtcSignalingMessenger {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~WebRtcSignalingMessenger() override = default;
+
+ // TODO(b/184975123): replace with real implementation.
+ bool SendMessage(absl::string_view peer_id,
+ const ByteArray& message) override {
+ return false;
+ }
+
+ // TODO(b/184975123): replace with real implementation.
+ bool StartReceivingMessages(
+ api::WebRtcSignalingMessenger::OnSignalingMessageCallback
+ on_message_callback,
+ api::WebRtcSignalingMessenger::OnSignalingCompleteCallback
+ on_complete_callback) override {
+ return false;
+ }
+ // TODO(b/184975123): replace with real implementation.
+ void StopReceivingMessages() override {}
+};
+
+class WebRtcMedium : public api::WebRtcMedium {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~WebRtcMedium() override = default;
+
+ // Gets the default two-letter country code associated with current locale.
+ // For example, en_US locale resolves to "US".
+ // TODO(b/184975123): replace with real implementation.
+ const std::string GetDefaultCountryCode() override {
+ return "Un-implemented";
+ }
+
+ // Creates and returns a new webrtc::PeerConnectionInterface object via
+ // |callback|.
+ // TODO(b/184975123): replace with real implementation.
+ void CreatePeerConnection(webrtc::PeerConnectionObserver* observer,
+ PeerConnectionCallback callback) override {}
+
+ // Returns a signaling messenger for sending WebRTC signaling messages.
+ // TODO(b/184975123): replace with real implementation.
+ std::unique_ptr<api::WebRtcSignalingMessenger> GetSignalingMessenger(
+ absl::string_view self_id,
+ const connections::LocationHint& location_hint) override {
+ return nullptr;
+ }
+};
+
+} // namespace windows
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_IMPL_WINDOWS_WEBRTC_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/wifi.h b/chromium/third_party/nearby/src/cpp/platform/impl/windows/wifi.h
new file mode 100644
index 00000000000..00ca53580d0
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/wifi.h
@@ -0,0 +1,98 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_IMPL_WINDOWS_WIFI_H_
+#define PLATFORM_IMPL_WINDOWS_WIFI_H_
+
+#include "platform/api/wifi.h"
+
+namespace location {
+namespace nearby {
+namespace windows {
+
+// Represents a WiFi network found during a call to WifiMedium#scan().
+class WifiScanResult : public api::WifiScanResult {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~WifiScanResult() override = default;
+
+ // Gets the SSID of this WiFi network.
+ // TODO(b/184975123): replace with real implementation.
+ std::string GetSsid() const override { return "Un-implemented"; }
+ // Gets the signal strength of this WiFi network in dBm.
+ // TODO(b/184975123): replace with real implementation.
+ std::int32_t GetSignalStrengthDbm() const override { return 0; }
+ // Gets the frequency band of this WiFi network in MHz.
+ // TODO(b/184975123): replace with real implementation.
+ std::int32_t GetFrequencyMhz() const override { return 0; }
+ // Gets the authentication type of this WiFi network.
+ // TODO(b/184975123): replace with real implementation.
+ api::WifiAuthType GetAuthType() const override {
+ return api::WifiAuthType::kUnknown;
+ }
+};
+
+// Container of operations that can be performed over the WiFi medium.
+class WifiMedium : public api::WifiMedium {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~WifiMedium() override = default;
+
+ class ScanResultCallback : public api::WifiMedium::ScanResultCallback {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~ScanResultCallback() override = default;
+
+ // TODO(b/184975123): replace with real implementation.
+ void OnScanResults(
+ const std::vector<api::WifiScanResult>& scan_results) override {}
+ };
+
+ // Does not take ownership of the passed-in scan_result_callback -- destroying
+ // that is up to the caller.
+ // TODO(b/184975123): replace with real implementation.
+ bool Scan(const api::WifiMedium::ScanResultCallback& scan_result_callback)
+ override {
+ return false;
+ }
+
+ // If 'password' is an empty string, none has been provided. Returns
+ // WifiConnectionStatus::CONNECTED on success, or the appropriate failure code
+ // otherwise.
+ // TODO(b/184975123): replace with real implementation.
+ api::WifiConnectionStatus ConnectToNetwork(
+ absl::string_view ssid, absl::string_view password,
+ api::WifiAuthType auth_type) override {
+ return api::WifiConnectionStatus::kUnknown;
+ }
+
+ // Blocks until it's certain of there being a connection to the internet, or
+ // returns false if it fails to do so.
+ //
+ // How this method wants to verify said connection is totally up to it (so it
+ // can feel free to ping whatever server, download whatever resource, etc.
+ // that it needs to gain confidence that the internet is reachable hereon in).
+ // TODO(b/184975123): replace with real implementation.
+ bool VerifyInternetConnectivity() override { return false; }
+
+ // Returns the local device's IP address in the IPv4 dotted-quad format.
+ // TODO(b/184975123): replace with real implementation.
+ std::string GetIpAddress() override { return "Un-implemented"; }
+};
+
+} // namespace windows
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_IMPL_WINDOWS_WIFI_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/impl/windows/wifi_lan.h b/chromium/third_party/nearby/src/cpp/platform/impl/windows/wifi_lan.h
new file mode 100644
index 00000000000..84f5c28319d
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/impl/windows/wifi_lan.h
@@ -0,0 +1,160 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_IMPL_WINDOWS_WIFI_LAN_H_
+#define PLATFORM_IMPL_WINDOWS_WIFI_LAN_H_
+
+#include "platform/api/wifi_lan.h"
+#include "platform/base/exception.h"
+#include "platform/base/input_stream.h"
+#include "platform/base/output_stream.h"
+
+namespace location {
+namespace nearby {
+namespace windows {
+
+// Opaque wrapper over a WifiLan service which contains |NsdServiceInfo|.
+class WifiLanService : public api::WifiLanService {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~WifiLanService() override = default;
+
+ // Returns the |NsdServiceInfo| which contains the packed string of
+ // |WifiLanServiceInfo| and the endpoint info with named key in a TXTRecord
+ // map.
+ // The details refer to
+ // https://developer.android.com/reference/android/net/nsd/NsdServiceInfo.html.
+ // TODO(b/184975123): replace with real implementation.
+ NsdServiceInfo GetServiceInfo() const override { return NsdServiceInfo{}; }
+};
+
+class WifiLanSocket : public api::WifiLanSocket {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~WifiLanSocket() override;
+
+ // Returns the InputStream of the WifiLanSocket.
+ // On error, returned stream will report Exception::kIo on any operation.
+ //
+ // The returned object is not owned by the caller, and can be invalidated once
+ // the WifiLanSocket object is destroyed.
+ // TODO(b/184975123): replace with real implementation.
+ InputStream& GetInputStream() override { return fake_input_stream_; }
+
+ // Returns the OutputStream of the WifiLanSocket.
+ // On error, returned stream will report Exception::kIo on any operation.
+ //
+ // The returned object is not owned by the caller, and can be invalidated once
+ // the WifiLanSocket object is destroyed.
+ // TODO(b/184975123): replace with real implementation.
+ OutputStream& GetOutputStream() override { return fake_output_stream_; }
+
+ // Returns Exception::kIo on error, Exception::kSuccess otherwise.
+ // TODO(b/184975123): replace with real implementation.
+ Exception Close() override { return Exception{}; }
+
+ // Returns valid WifiLanService pointer if there is a connection, and
+ // nullptr otherwise.
+ // TODO(b/184975123): replace with real implementation.
+ WifiLanService* GetRemoteWifiLanService() override { return nullptr; }
+
+ private:
+ // TODO(b/184975123): replace with real implementation.
+ class FakeInputStream : public InputStream {
+ ~FakeInputStream() override = default;
+ ExceptionOr<ByteArray> Read(std::int64_t size) override {
+ return ExceptionOr<ByteArray>(Exception::kFailed);
+ }
+ Exception Close() override { return {.value = Exception::kFailed}; }
+ };
+ class FakeOutputStream : public OutputStream {
+ ~FakeOutputStream() override = default;
+
+ Exception Write(const ByteArray& data) override {
+ return {.value = Exception::kFailed};
+ }
+ Exception Flush() override { return {.value = Exception::kFailed}; }
+ Exception Close() override { return {.value = Exception::kFailed}; }
+ };
+ FakeInputStream fake_input_stream_;
+ FakeOutputStream fake_output_stream_;
+};
+
+// Container of operations that can be performed over the WifiLan medium.
+class WifiLanMedium : public api::WifiLanMedium {
+ public:
+ // TODO(b/184975123): replace with real implementation.
+ ~WifiLanMedium() override = default;
+
+ // TODO(b/184975123): replace with real implementation.
+ bool StartAdvertising(const std::string& service_id,
+ const NsdServiceInfo& nsd_service_info) override {
+ return false;
+ }
+ // TODO(b/184975123): replace with real implementation.
+ bool StopAdvertising(const std::string& service_id) override { return false; }
+
+ // Returns true once the WifiLan discovery has been initiated.
+ // TODO(b/184975123): replace with real implementation.
+ bool StartDiscovery(const std::string& service_id,
+ DiscoveredServiceCallback callback) override {
+ return false;
+ }
+
+ // Returns true once WifiLan discovery for service_id is well and truly
+ // stopped; after this returns, there must be no more invocations of the
+ // DiscoveredServiceCallback passed in to StartDiscovery() for service_id.
+ // TODO(b/184975123): replace with real implementation.
+ bool StopDiscovery(const std::string& service_id) override { return false; }
+
+ // Returns true once WifiLan socket connection requests to service_id can be
+ // accepted.
+ // TODO(b/184975123): replace with real implementation.
+ bool StartAcceptingConnections(const std::string& service_id,
+ AcceptedConnectionCallback callback) override {
+ return false;
+ }
+ // TODO(b/184975123): replace with real implementation.
+ bool StopAcceptingConnections(const std::string& service_id) override {
+ return false;
+ }
+
+ // Connects to a WifiLan service.
+ // On success, returns a new WifiLanSocket.
+ // On error, returns nullptr.
+ // TODO(b/184975123): replace with real implementation.
+ std::unique_ptr<api::WifiLanSocket> Connect(
+ api::WifiLanService& wifi_lan_service, const std::string& service_id,
+ CancellationFlag* cancellation_flag) override {
+ return nullptr;
+ }
+
+ // TODO(b/184975123): replace with real implementation.
+ WifiLanService* GetRemoteService(const std::string& ip_address,
+ int port) override {
+ return nullptr;
+ }
+
+ // TODO(b/184975123): replace with real implementation.
+ std::pair<std::string, int> GetServiceAddress(
+ const std::string& service_id) override {
+ return std::pair<std::string, int>{"Un-implemented", 0};
+ }
+};
+
+} // namespace windows
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_IMPL_WINDOWS_WIFI_LAN_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/public/BUILD b/chromium/third_party/nearby/src/cpp/platform/public/BUILD
index 459584d54e3..008dae9e94b 100644
--- a/chromium/third_party/nearby/src/cpp/platform/public/BUILD
+++ b/chromium/third_party/nearby/src/cpp/platform/public/BUILD
@@ -17,6 +17,8 @@ load("//tools/build_defs/cc:cc_fake_binary.bzl", "cc_fake_binary")
cc_library(
name = "types",
srcs = [
+ "monitored_runnable.cc",
+ "pending_job_registry.cc",
"pipe.cc",
],
hdrs = [
@@ -32,9 +34,11 @@ cc_library(
"future.h",
"lockable.h",
"logging.h",
+ "monitored_runnable.h",
"multi_thread_executor.h",
"mutex.h",
"mutex_lock.h",
+ "pending_job_registry.h",
"pipe.h",
"scheduled_executor.h",
"settable_future.h",
diff --git a/chromium/third_party/nearby/src/cpp/platform/public/ble_test.cc b/chromium/third_party/nearby/src/cpp/platform/public/ble_test.cc
index 9c0e248e4ad..8cb15cc7e3f 100644
--- a/chromium/third_party/nearby/src/cpp/platform/public/ble_test.cc
+++ b/chromium/third_party/nearby/src/cpp/platform/public/ble_test.cc
@@ -65,6 +65,7 @@ TEST_P(BleMediumTest, CanStartAcceptingConnectionsAndConnect) {
std::string fast_advertisement_service_uuid(kFastAdvertisementServiceUuid);
CountDownLatch found_latch(1);
CountDownLatch accepted_latch(1);
+ CancellationFlag flag;
BlePeripheral* discovered_peripheral = nullptr;
ble_a.StartScanning(
@@ -102,8 +103,7 @@ TEST_P(BleMediumTest, CanStartAcceptingConnectionsAndConnect) {
{
SingleThreadExecutor client_executor;
client_executor.Execute(
- [&ble_a, &socket_a, discovered_peripheral, &service_id]() {
- CancellationFlag flag;
+ [&ble_a, &socket_a, discovered_peripheral, &service_id, &flag]() {
socket_a = ble_a.Connect(*discovered_peripheral, service_id, &flag);
});
}
@@ -127,6 +127,7 @@ TEST_P(BleMediumTest, CanCancelConnect) {
std::string fast_advertisement_service_uuid(kFastAdvertisementServiceUuid);
CountDownLatch found_latch(1);
CountDownLatch accepted_latch(1);
+ CancellationFlag flag(true);
BlePeripheral* discovered_peripheral = nullptr;
ble_a.StartScanning(
@@ -164,8 +165,7 @@ TEST_P(BleMediumTest, CanCancelConnect) {
{
SingleThreadExecutor client_executor;
client_executor.Execute(
- [&ble_a, &socket_a, discovered_peripheral, &service_id]() {
- CancellationFlag flag(true);
+ [&ble_a, &socket_a, discovered_peripheral, &service_id, &flag]() {
socket_a = ble_a.Connect(*discovered_peripheral, service_id, &flag);
});
}
diff --git a/chromium/third_party/nearby/src/cpp/platform/public/bluetooth_classic.h b/chromium/third_party/nearby/src/cpp/platform/public/bluetooth_classic.h
index 387437521b1..62a2ec12825 100644
--- a/chromium/third_party/nearby/src/cpp/platform/public/bluetooth_classic.h
+++ b/chromium/third_party/nearby/src/cpp/platform/public/bluetooth_classic.h
@@ -27,6 +27,7 @@
#include "platform/base/listeners.h"
#include "platform/base/output_stream.h"
#include "platform/public/bluetooth_adapter.h"
+#include "platform/public/logging.h"
#include "platform/public/mutex.h"
#include "absl/container/flat_hash_map.h"
@@ -101,12 +102,21 @@ class BluetoothServerSocket final {
// On success, returns connected socket, ready to exchange data.
// Returns nullptr on error.
// Once error is reported, it is permanent, and ServerSocket has to be closed.
- BluetoothSocket Accept() { return BluetoothSocket(impl_->Accept()); }
+ BluetoothSocket Accept() {
+ auto socket = impl_->Accept();
+ if (!socket) {
+ NEARBY_LOGS(INFO) << "Accept() failed on server socket: " << this;
+ }
+ return BluetoothSocket(std::move(socket));
+ }
// https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html#close()
//
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
- Exception Close() { return impl_->Close(); }
+ Exception Close() {
+ NEARBY_LOGS(INFO) << "Closing server socket: " << this;
+ return impl_->Close();
+ }
bool IsValid() const { return impl_ != nullptr; }
api::BluetoothServerSocket& GetImpl() { return *impl_; }
diff --git a/chromium/third_party/nearby/src/cpp/platform/public/bluetooth_classic_test.cc b/chromium/third_party/nearby/src/cpp/platform/public/bluetooth_classic_test.cc
index 83f5bad4e7c..2f852052753 100644
--- a/chromium/third_party/nearby/src/cpp/platform/public/bluetooth_classic_test.cc
+++ b/chromium/third_party/nearby/src/cpp/platform/public/bluetooth_classic_test.cc
@@ -108,15 +108,15 @@ TEST_P(BluetoothClassicMediumTest, CanConnectToService) {
EXPECT_FALSE(socket_a.IsValid());
EXPECT_FALSE(socket_b.IsValid());
{
+ CancellationFlag flag;
SingleThreadExecutor server_executor;
SingleThreadExecutor client_executor;
- client_executor.Execute(
- [this, &socket_a, discovered_device, &service_uuid, &server_socket]() {
- CancellationFlag flag;
- socket_a =
- bt_a_->ConnectToService(*discovered_device, service_uuid, &flag);
- if (!socket_a.IsValid()) server_socket.Close();
- });
+ client_executor.Execute([this, &socket_a, discovered_device, &service_uuid,
+ &server_socket, &flag]() {
+ socket_a =
+ bt_a_->ConnectToService(*discovered_device, service_uuid, &flag);
+ if (!socket_a.IsValid()) server_socket.Close();
+ });
server_executor.Execute([&socket_b, &server_socket]() {
socket_b = server_socket.Accept();
if (!socket_b.IsValid()) server_socket.Close();
@@ -157,15 +157,15 @@ TEST_P(BluetoothClassicMediumTest, CanCancelConnect) {
EXPECT_FALSE(socket_a.IsValid());
EXPECT_FALSE(socket_b.IsValid());
{
+ CancellationFlag flag(true);
SingleThreadExecutor server_executor;
SingleThreadExecutor client_executor;
- client_executor.Execute(
- [this, &socket_a, discovered_device, &service_uuid, &server_socket]() {
- CancellationFlag flag(true);
- socket_a =
- bt_a_->ConnectToService(*discovered_device, service_uuid, &flag);
- if (!socket_a.IsValid()) server_socket.Close();
- });
+ client_executor.Execute([this, &socket_a, discovered_device, &service_uuid,
+ &server_socket, &flag]() {
+ socket_a =
+ bt_a_->ConnectToService(*discovered_device, service_uuid, &flag);
+ if (!socket_a.IsValid()) server_socket.Close();
+ });
server_executor.Execute([&socket_b, &server_socket]() {
socket_b = server_socket.Accept();
if (!socket_b.IsValid()) server_socket.Close();
diff --git a/chromium/third_party/nearby/src/cpp/platform/public/count_down_latch_test.cc b/chromium/third_party/nearby/src/cpp/platform/public/count_down_latch_test.cc
index d8699973547..1485070db58 100644
--- a/chromium/third_party/nearby/src/cpp/platform/public/count_down_latch_test.cc
+++ b/chromium/third_party/nearby/src/cpp/platform/public/count_down_latch_test.cc
@@ -57,6 +57,14 @@ TEST(CountDownLatch, LatchAwaitWithTimeoutCanExpire) {
EXPECT_FALSE(response.result());
}
+TEST(CountDownLatch, InitialCountZero_AwaitDoesNotBlock) {
+ CountDownLatch latch(0);
+
+ auto response = latch.Await();
+
+ EXPECT_TRUE(response.Ok());
+}
+
} // namespace
} // namespace nearby
} // namespace location
diff --git a/chromium/third_party/nearby/src/cpp/platform/public/monitored_runnable.cc b/chromium/third_party/nearby/src/cpp/platform/public/monitored_runnable.cc
new file mode 100644
index 00000000000..7478f70e8f6
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/public/monitored_runnable.cc
@@ -0,0 +1,59 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "platform/public/monitored_runnable.h"
+
+#include "platform/public/logging.h"
+#include "platform/public/pending_job_registry.h"
+
+namespace location {
+namespace nearby {
+
+namespace {
+absl::Duration kMinReportedStartDelay = absl::Seconds(5);
+absl::Duration kMinReportedTaskDuration = absl::Seconds(10);
+} // namespace
+
+MonitoredRunnable::MonitoredRunnable(Runnable&& runnable)
+ : runnable_{runnable} {}
+
+MonitoredRunnable::MonitoredRunnable(const std::string& name,
+ Runnable&& runnable)
+ : name_{name}, runnable_{runnable} {
+ PendingJobRegistry::GetInstance().AddPendingJob(name_, post_time_);
+}
+
+MonitoredRunnable::~MonitoredRunnable() = default;
+
+void MonitoredRunnable::operator()() const {
+ auto start_time = SystemClock::ElapsedRealtime();
+ auto start_delay = start_time - post_time_;
+ if (start_delay >= kMinReportedStartDelay) {
+ NEARBY_LOGS(INFO) << "Task: \"" << name_ << "\" started after "
+ << absl::ToInt64Seconds(start_delay) << " seconds";
+ }
+ PendingJobRegistry::GetInstance().RemovePendingJob(name_, post_time_);
+ PendingJobRegistry::GetInstance().AddRunningJob(name_, post_time_);
+ runnable_();
+ auto task_duration = SystemClock::ElapsedRealtime() - start_time;
+ if (task_duration >= kMinReportedTaskDuration) {
+ NEARBY_LOGS(INFO) << "Task: \"" << name_ << "\" finished after "
+ << absl::ToInt64Seconds(task_duration) << " seconds";
+ }
+ PendingJobRegistry::GetInstance().RemoveRunningJob(name_, post_time_);
+ PendingJobRegistry::GetInstance().ListJobs();
+}
+
+} // namespace nearby
+} // namespace location
diff --git a/chromium/third_party/nearby/src/cpp/platform/public/monitored_runnable.h b/chromium/third_party/nearby/src/cpp/platform/public/monitored_runnable.h
new file mode 100644
index 00000000000..b7630b62585
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/public/monitored_runnable.h
@@ -0,0 +1,48 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_PUBLIC_MONITORED_RUNNABLE_H_
+#define PLATFORM_PUBLIC_MONITORED_RUNNABLE_H_
+
+#include <string>
+
+#include "platform/base/runnable.h"
+#include "platform/public/system_clock.h"
+#include "absl/time/time.h"
+
+namespace location {
+namespace nearby {
+
+// A runnable with extra logging
+// We log if the task has been waiting long on the executor or if it was running
+// for a long time. The latter isn't always an issue - some tasks are expected
+// to run for longer periods of time (minutes).
+class MonitoredRunnable {
+ public:
+ explicit MonitoredRunnable(Runnable&& runnable);
+ MonitoredRunnable(const std::string& name, Runnable&& runnable);
+ ~MonitoredRunnable();
+
+ void operator()() const;
+
+ private:
+ const std::string name_;
+ Runnable runnable_;
+ absl::Time post_time_ = SystemClock::ElapsedRealtime();
+};
+
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_PUBLIC_MONITORED_RUNNABLE_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/public/pending_job_registry.cc b/chromium/third_party/nearby/src/cpp/platform/public/pending_job_registry.cc
new file mode 100644
index 00000000000..e4858e4fa60
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/public/pending_job_registry.cc
@@ -0,0 +1,92 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "platform/public/pending_job_registry.h"
+
+#include "platform/public/logging.h"
+#include "platform/public/mutex_lock.h"
+#include "platform/public/system_clock.h"
+
+namespace location {
+namespace nearby {
+
+namespace {
+absl::Duration kMinReportInterval = absl::Seconds(60);
+absl::Duration kReportPendingJobsOlderThan = absl::Seconds(40);
+absl::Duration kReportRunningJobsOlderThan = absl::Seconds(60);
+} // namespace
+
+PendingJobRegistry& PendingJobRegistry::GetInstance() {
+ static PendingJobRegistry* instance = new PendingJobRegistry();
+ return *instance;
+}
+
+PendingJobRegistry::PendingJobRegistry() = default;
+
+PendingJobRegistry::~PendingJobRegistry() = default;
+
+void PendingJobRegistry::AddPendingJob(const std::string& name,
+ absl::Time post_time) {
+ MutexLock lock(&mutex_);
+ pending_jobs_.emplace(CreateKey(name, post_time), post_time);
+}
+
+void PendingJobRegistry::RemovePendingJob(const std::string& name,
+ absl::Time post_time) {
+ MutexLock lock(&mutex_);
+ pending_jobs_.erase(CreateKey(name, post_time));
+}
+
+void PendingJobRegistry::AddRunningJob(const std::string& name,
+ absl::Time post_time) {
+ MutexLock lock(&mutex_);
+ running_jobs_.emplace(CreateKey(name, post_time),
+ SystemClock::ElapsedRealtime());
+}
+
+void PendingJobRegistry::RemoveRunningJob(const std::string& name,
+ absl::Time post_time) {
+ MutexLock lock(&mutex_);
+ running_jobs_.erase(CreateKey(name, post_time));
+}
+
+void PendingJobRegistry::ListJobs() {
+ auto current_time = SystemClock::ElapsedRealtime();
+ MutexLock lock(&mutex_);
+ if (current_time - list_jobs_time_ < kMinReportInterval)
+ return;
+ for (auto& job : pending_jobs_) {
+ auto age = current_time - job.second;
+ if (age >= kReportPendingJobsOlderThan) {
+ NEARBY_LOGS(INFO) << "Task \"" << job.first << "\" is waiting for "
+ << absl::ToInt64Seconds(age) << " s";
+ }
+ }
+ for (auto& job : running_jobs_) {
+ auto age = current_time - job.second;
+ if (age >= kReportRunningJobsOlderThan) {
+ NEARBY_LOGS(INFO) << "Task \"" << job.first << "\" is running for "
+ << absl::ToInt64Seconds(age) << " s";
+ }
+ }
+ list_jobs_time_ = current_time;
+}
+
+std::string PendingJobRegistry::CreateKey(const std::string& name,
+ absl::Time post_time) {
+ return name + "." + std::to_string(absl::ToUnixNanos(post_time));
+}
+
+} // namespace nearby
+} // namespace location
diff --git a/chromium/third_party/nearby/src/cpp/platform/public/pending_job_registry.h b/chromium/third_party/nearby/src/cpp/platform/public/pending_job_registry.h
new file mode 100644
index 00000000000..8b251cb7ff5
--- /dev/null
+++ b/chromium/third_party/nearby/src/cpp/platform/public/pending_job_registry.h
@@ -0,0 +1,55 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PLATFORM_PUBLIC_PENDING_JOB_REGISTRY_H_
+#define PLATFORM_PUBLIC_PENDING_JOB_REGISTRY_H_
+
+#include "platform/public/mutex.h"
+#include "absl/base/thread_annotations.h"
+#include "absl/time/time.h"
+
+namespace location {
+namespace nearby {
+
+// A global registry of running tasks. The goal is to help us monitor
+// tasks that are either waiting too long for their turn or they never finish
+class PendingJobRegistry {
+ public:
+ static PendingJobRegistry& GetInstance();
+
+ ~PendingJobRegistry();
+
+ void AddPendingJob(const std::string& name, absl::Time post_time);
+ void RemovePendingJob(const std::string& name, absl::Time post_time);
+ void AddRunningJob(const std::string& name, absl::Time post_time);
+ void RemoveRunningJob(const std::string& name, absl::Time post_time);
+ void ListJobs();
+
+ private:
+ PendingJobRegistry();
+
+ std::string CreateKey(const std::string& name, absl::Time post_time);
+
+ Mutex mutex_;
+ absl::flat_hash_map<const std::string, absl::Time> pending_jobs_
+ ABSL_GUARDED_BY(mutex_);
+ absl::flat_hash_map<const std::string, absl::Time> running_jobs_
+ ABSL_GUARDED_BY(mutex_);
+ absl::Time list_jobs_time_ ABSL_GUARDED_BY(mutex_) = absl::UnixEpoch();
+};
+
+} // namespace nearby
+} // namespace location
+
+#endif // PLATFORM_PUBLIC_PENDING_JOB_REGISTRY_H_
diff --git a/chromium/third_party/nearby/src/cpp/platform/public/scheduled_executor.h b/chromium/third_party/nearby/src/cpp/platform/public/scheduled_executor.h
index bd603887fee..26dc255382b 100644
--- a/chromium/third_party/nearby/src/cpp/platform/public/scheduled_executor.h
+++ b/chromium/third_party/nearby/src/cpp/platform/public/scheduled_executor.h
@@ -25,6 +25,7 @@
#include "platform/public/cancelable.h"
#include "platform/public/cancellable_task.h"
#include "platform/public/lockable.h"
+#include "platform/public/monitored_runnable.h"
#include "platform/public/mutex.h"
#include "platform/public/mutex_lock.h"
#include "platform/public/thread_check_callable.h"
@@ -59,6 +60,14 @@ class ABSL_LOCKABLE ScheduledExecutor final : public Lockable {
}
return *this;
}
+ void Execute(const std::string& name, Runnable&& runnable)
+ ABSL_LOCKS_EXCLUDED(mutex_) {
+ MutexLock lock(&mutex_);
+ if (impl_)
+ impl_->Execute(MonitoredRunnable(
+ name, ThreadCheckRunnable(this, std::move(runnable))));
+ }
+
void Execute(Runnable&& runnable) ABSL_LOCKS_EXCLUDED(mutex_) {
MutexLock lock(&mutex_);
if (impl_) impl_->Execute(ThreadCheckRunnable(this, std::move(runnable)));
diff --git a/chromium/third_party/nearby/src/cpp/platform/public/single_thread_executor_test.cc b/chromium/third_party/nearby/src/cpp/platform/public/single_thread_executor_test.cc
index f89773f365d..e2059eded11 100644
--- a/chromium/third_party/nearby/src/cpp/platform/public/single_thread_executor_test.cc
+++ b/chromium/third_party/nearby/src/cpp/platform/public/single_thread_executor_test.cc
@@ -16,6 +16,7 @@
#include <atomic>
#include <functional>
+#include <string>
#include "platform/base/exception.h"
#include "gtest/gtest.h"
@@ -47,6 +48,24 @@ TEST(SingleThreadExecutorTest, CanExecute) {
EXPECT_TRUE(done);
}
+TEST(SingleThreadExecutorTest, CanExecuteNamedTask) {
+ absl::CondVar cond;
+ std::atomic_bool done = false;
+ SingleThreadExecutor executor;
+ executor.Execute("my task", [&done, &cond]() {
+ done = true;
+ cond.SignalAll();
+ });
+ absl::Mutex mutex;
+ {
+ absl::MutexLock lock(&mutex);
+ if (!done) {
+ cond.WaitWithTimeout(&mutex, absl::Seconds(1));
+ }
+ }
+ EXPECT_TRUE(done);
+}
+
TEST(SingleThreadExecutorTest, JobsExecuteInOrder) {
std::vector<int> results;
SingleThreadExecutor executor;
diff --git a/chromium/third_party/nearby/src/cpp/platform/public/submittable_executor.h b/chromium/third_party/nearby/src/cpp/platform/public/submittable_executor.h
index c5c6f3ab886..8e4e073154f 100644
--- a/chromium/third_party/nearby/src/cpp/platform/public/submittable_executor.h
+++ b/chromium/third_party/nearby/src/cpp/platform/public/submittable_executor.h
@@ -26,6 +26,7 @@
#include "platform/base/runnable.h"
#include "platform/public/future.h"
#include "platform/public/lockable.h"
+#include "platform/public/monitored_runnable.h"
#include "platform/public/mutex.h"
#include "platform/public/mutex_lock.h"
#include "platform/public/thread_check_callable.h"
@@ -57,9 +58,19 @@ class ABSL_LOCKABLE SubmittableExecutor : public api::SubmittableExecutor,
}
return *this;
}
+ void Execute(const std::string& name, Runnable&& runnable)
+ ABSL_LOCKS_EXCLUDED(mutex_) {
+ MutexLock lock(&mutex_);
+ if (impl_)
+ impl_->Execute(MonitoredRunnable(
+ name, ThreadCheckRunnable(this, std::move(runnable))));
+ }
+
void Execute(Runnable&& runnable) ABSL_LOCKS_EXCLUDED(mutex_) override {
MutexLock lock(&mutex_);
- if (impl_) impl_->Execute(ThreadCheckRunnable(this, std::move(runnable)));
+ if (impl_)
+ impl_->Execute(
+ MonitoredRunnable(ThreadCheckRunnable(this, std::move(runnable))));
}
int GetTid(int index) const ABSL_LOCKS_EXCLUDED(mutex_) override {
diff --git a/chromium/third_party/nearby/src/cpp/platform/public/wifi_lan_test.cc b/chromium/third_party/nearby/src/cpp/platform/public/wifi_lan_test.cc
index f3992771b0b..17985109bcb 100644
--- a/chromium/third_party/nearby/src/cpp/platform/public/wifi_lan_test.cc
+++ b/chromium/third_party/nearby/src/cpp/platform/public/wifi_lan_test.cc
@@ -64,6 +64,7 @@ TEST_P(WifiLanMediumTest, CanStartAcceptingConnectionsAndConnect) {
std::string endpoint_info_name{kEndpointName};
CountDownLatch found_latch(1);
CountDownLatch accepted_latch(1);
+ CancellationFlag flag;
WifiLanService* discovered_service = nullptr;
wifi_a.StartDiscovery(
@@ -102,8 +103,7 @@ TEST_P(WifiLanMediumTest, CanStartAcceptingConnectionsAndConnect) {
{
SingleThreadExecutor client_executor;
client_executor.Execute(
- [&wifi_a, &socket_a, discovered_service, &service_id]() {
- CancellationFlag flag;
+ [&wifi_a, &socket_a, discovered_service, &service_id, &flag]() {
socket_a = wifi_a.Connect(*discovered_service, service_id, &flag);
});
}
@@ -126,6 +126,7 @@ TEST_P(WifiLanMediumTest, CanCancelConnect) {
std::string endpoint_info_name{kEndpointName};
CountDownLatch found_latch(1);
CountDownLatch accepted_latch(1);
+ CancellationFlag flag(true);
WifiLanService* discovered_service = nullptr;
wifi_a.StartDiscovery(
@@ -164,9 +165,7 @@ TEST_P(WifiLanMediumTest, CanCancelConnect) {
{
SingleThreadExecutor client_executor;
client_executor.Execute(
- [&wifi_a, &socket_a, discovered_service, &service_id]() {
- // Make it as Cancelled.
- CancellationFlag flag(true);
+ [&wifi_a, &socket_a, discovered_service, &service_id, &flag]() {
socket_a = wifi_a.Connect(*discovered_service, service_id, &flag);
});
}
diff --git a/chromium/third_party/nearby/src/proto/BUILD b/chromium/third_party/nearby/src/proto/BUILD
index 880147c8b93..6c7f2ff29b3 100644
--- a/chromium/third_party/nearby/src/proto/BUILD
+++ b/chromium/third_party/nearby/src/proto/BUILD
@@ -204,3 +204,23 @@ go_proto_library(
name = "nearby_event_codes_go_proto",
deps = [":nearby_event_codes_proto"],
)
+
+proto_library(
+ name = "uwb_enums_proto",
+ srcs = ["uwb_enums.proto"],
+ cc_api_version = 2,
+ compatible_with = ["//buildenv/target:appengine"],
+ deps = [
+ "//logs/proto/logs_annotations",
+ ],
+)
+
+java_lite_proto_library(
+ name = "uwb_enums_java_proto_lite",
+ deps = [":uwb_enums_proto"],
+)
+
+java_proto_library(
+ name = "uwb_enums_java_proto",
+ deps = [":uwb_enums_proto"],
+)
diff --git a/chromium/third_party/nearby/src/proto/connections/offline_wire_formats.proto b/chromium/third_party/nearby/src/proto/connections/offline_wire_formats.proto
index 5e582539118..ed7ce124363 100644
--- a/chromium/third_party/nearby/src/proto/connections/offline_wire_formats.proto
+++ b/chromium/third_party/nearby/src/proto/connections/offline_wire_formats.proto
@@ -84,6 +84,8 @@ message ConnectionRequestFrame {
repeated Medium mediums = 5;
optional bytes endpoint_info = 6;
optional MediumMetadata medium_metadata = 7;
+ optional int32 keep_alive_interval_millis = 8;
+ optional int32 keep_alive_timeout_millis = 9;
}
message ConnectionResponseFrame {
diff --git a/chromium/third_party/nearby/src/proto/connections_enums.proto b/chromium/third_party/nearby/src/proto/connections_enums.proto
index 4674a4cf20e..b1f8096c8fc 100644
--- a/chromium/third_party/nearby/src/proto/connections_enums.proto
+++ b/chromium/third_party/nearby/src/proto/connections_enums.proto
@@ -67,9 +67,10 @@ enum SessionRole {
DISCOVERER = 2;
}
+// LINT.IfChange
enum Medium {
UNKNOWN_MEDIUM = 0;
- MDNS = 1;
+ MDNS = 1 [deprecated = true];
BLUETOOTH = 2;
WIFI_HOTSPOT = 3;
BLE = 4;
@@ -79,6 +80,7 @@ enum Medium {
WIFI_DIRECT = 8;
WEB_RTC = 9;
}
+// LINT.ThenChange(//depot/google3/java/com/google/android/gmscore/integ/client/nearby/src/com/google/android/gms/nearby/connection/Medium.java)
// The result of a ConnectionRequest.
enum ConnectionRequestResponse {
diff --git a/chromium/third_party/nearby/src/proto/discovery_enums.proto b/chromium/third_party/nearby/src/proto/discovery_enums.proto
index 19901df44d6..40596e6ded3 100644
--- a/chromium/third_party/nearby/src/proto/discovery_enums.proto
+++ b/chromium/third_party/nearby/src/proto/discovery_enums.proto
@@ -21,7 +21,7 @@ option optimize_for = LITE_RUNTIME;
option java_package = "com.google.location.nearby.proto";
option java_outer_classname = "DiscoveryEnums";
-// NEXT ID: 148
+// NEXT ID: 149
enum DiscoveryEvent {
UNKNOWN_DISCOVERY_EVENT = 0;
@@ -456,6 +456,9 @@ enum DiscoveryEvent {
// time
HALF_SHEET_CONNECTION_AFTER_BAN = 147;
+ // User has clicked the companion header slice from device settings.
+ FAST_PAIR_DEVICE_COMPANION_HEADER_CLICKED = 148;
+
// Deprecated.
reserved 65, 67 to 72;
}
diff --git a/chromium/third_party/nearby/src/proto/magic_pair_enums.proto b/chromium/third_party/nearby/src/proto/magic_pair_enums.proto
index a0633f9be38..b6c35115e07 100644
--- a/chromium/third_party/nearby/src/proto/magic_pair_enums.proto
+++ b/chromium/third_party/nearby/src/proto/magic_pair_enums.proto
@@ -70,6 +70,8 @@ message MagicPairEvent {
UNKNOWN_BOND_ERROR_CODE = 0;
BOND_BROKEN = 1;
POSSIBLE_MITM = 2;
+ NO_PERMISSION = 3;
+ INCORRECT_VARIANT = 4;
}
enum ConnectErrorCode {
diff --git a/chromium/third_party/nearby/src/proto/nearby_event_codes.proto b/chromium/third_party/nearby/src/proto/nearby_event_codes.proto
index 7d0939e046b..092fea71cc6 100644
--- a/chromium/third_party/nearby/src/proto/nearby_event_codes.proto
+++ b/chromium/third_party/nearby/src/proto/nearby_event_codes.proto
@@ -66,5 +66,10 @@ message NearbyEvent {
BISTO_PAIR_END = 1340;
REMOTE_PAIR_START = 1350;
REMOTE_PAIR_END = 1360;
+ BEFORE_CREATE_BOND = 1370;
+ BEFORE_CREATE_BOND_BONDING = 1380;
+ BEFORE_CREATE_BOND_BONDED = 1390;
+ BEFORE_CONNECT_PROFILE = 1400;
+ HANDLE_PAIRING_REQUEST = 1410;
}
}
diff --git a/chromium/third_party/nearby/src/proto/sharing_enums.proto b/chromium/third_party/nearby/src/proto/sharing_enums.proto
index b43a82bcdc2..f6803167bdd 100644
--- a/chromium/third_party/nearby/src/proto/sharing_enums.proto
+++ b/chromium/third_party/nearby/src/proto/sharing_enums.proto
@@ -160,6 +160,9 @@ enum EventType {
// Receiver verification of APKs status.
VERIFY_APK = 41;
+
+ // User starts a consent.
+ LAUNCH_CONSENT = 42;
}
// Event category to differentiate whether this comes from sender or receiver,
@@ -340,6 +343,12 @@ enum ActivityName {
CONSENTS_ACTIVITY = 6;
}
+enum ConsentType {
+ CONSENT_TYPE_UNKNOWN = 0;
+
+ CONSENT_TYPE_C11N = 1;
+}
+
enum ApkSource {
UNKNOWN_APK_SOURCE = 0;
diff --git a/chromium/third_party/nearby/src/proto/uwb_enums.proto b/chromium/third_party/nearby/src/proto/uwb_enums.proto
new file mode 100644
index 00000000000..9af4d221d30
--- /dev/null
+++ b/chromium/third_party/nearby/src/proto/uwb_enums.proto
@@ -0,0 +1,41 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto2";
+
+package location.nearby.proto.uwb;
+
+
+option optimize_for = LITE_RUNTIME;
+option java_package = "com.google.location.nearby.proto";
+option java_outer_classname = "UwbEnums";
+option objc_class_prefix = "GNUP";
+
+// The role which the device takes during UWB ranging.
+// LINT.IfChange()
+enum RangingRole {
+ ROLE_UNKNOWN = 0;
+ ROLE_CONTROLLER = 1;
+ ROLE_CONTROLLEE = 2;
+}
+// LINT.ThenChange(//depot/google3/java/com/google/android/gmscore/integ/client/nearby/src/com/google/android/gms/nearby/uwb/UwbOptions.java)
+
+// The type how a UWB session should be created.
+// LINT.IfChange()
+enum SessionType {
+ TYPE_UNKNOWN = 0;
+ TYPE_UNICAST = 1;
+ TYPE_MULTICAST = 2;
+}
+// LINT.ThenChange(//depot/google3/java/com/google/android/gmscore/integ/client/nearby/src/com/google/android/gms/nearby/uwb/UwbOptions.java)