diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-05-12 15:59:20 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-05-25 06:57:22 +0000 |
commit | f7eaed5286974984ba5f9e3189d8f49d03e99f81 (patch) | |
tree | caed19b2af2024f35449fb0b781d0a25e09d4f8f /chromium/third_party/nearby/src/cpp/core/internal/mediums | |
parent | 9729c4479fe23554eae6e6dd1f30ff488f470c84 (diff) | |
download | qtwebengine-chromium-f7eaed5286974984ba5f9e3189d8f49d03e99f81.tar.gz |
BASELINE: Update Chromium to 100.0.4896.167
Change-Id: I98cbeb5d7543d966ffe04d8cefded0c493a11333
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/nearby/src/cpp/core/internal/mediums')
61 files changed, 0 insertions, 10321 deletions
diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/BUILD b/chromium/third_party/nearby/src/cpp/core/internal/mediums/BUILD deleted file mode 100644 index 7f5307234a3..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/BUILD +++ /dev/null @@ -1,142 +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. -licenses(["notice"]) - -cc_library( - name = "mediums", - srcs = [ - "ble.cc", - "bloom_filter.cc", - "bluetooth_classic.cc", - "bluetooth_radio.cc", - "mediums.cc", - "uuid.cc", - "webrtc.cc", - "wifi_lan.cc", - ], - hdrs = [ - "ble.h", - "bloom_filter.h", - "bluetooth_classic.h", - "bluetooth_radio.h", - "lost_entity_tracker.h", - "mediums.h", - "uuid.h", - "webrtc.h", - "wifi_lan.h", - ], - compatible_with = ["//buildenv/target:non_prod"], - visibility = [ - "//core/internal:__subpackages__", - ], - deps = [ - ":utils", - "//absl/container:flat_hash_map", - "//absl/container:flat_hash_set", - "//absl/functional:bind_front", - "//absl/numeric:int128", - "//absl/strings", - "//absl/strings:str_format", - "//absl/time", - "//core:core_types", - "//core/internal/mediums/ble_v2", - "//core/internal/mediums/webrtc", - "//core/internal/mediums/webrtc:data_types", - "//platform/base", - "//platform/base:cancellation_flag", - "//platform/public:comm", - "//platform/public:logging", - "//platform/public:types", - "//proto/connections:offline_wire_formats_portable_proto", - "//proto/mediums:web_rtc_signaling_frames_cc_proto", - "//smhasher:libmurmur3", - "//webrtc/api:libjingle_peerconnection_api", - ], -) - -cc_library( - name = "utils", - srcs = [ - "utils.cc", - "webrtc_peer_id.cc", - ], - hdrs = [ - "utils.h", - "webrtc_peer_id.h", - "webrtc_socket_wrapper.h", - ], - compatible_with = ["//buildenv/target:non_prod"], - visibility = [ - "//core/internal:__pkg__", - "//core/internal/mediums:__pkg__", - "//core/internal/mediums/webrtc:__pkg__", - ], - deps = [ - "//absl/strings", - "//core/internal/mediums/webrtc:data_types", - "//platform/base", - "//platform/public:types", - "//proto/connections:offline_wire_formats_portable_proto", - ], -) - -cc_test( - name = "core_internal_mediums_test", - size = "small", - srcs = [ - "ble_test.cc", - "bloom_filter_test.cc", - "bluetooth_classic_test.cc", - "bluetooth_radio_test.cc", - "lost_entity_tracker_test.cc", - "uuid_test.cc", - "wifi_lan_test.cc", - ], - shard_count = 16, - deps = [ - ":mediums", - ":utils", - "//testing/base/public:gunit_main", - "//absl/strings", - "//absl/time", - "//platform/base", - "//platform/base:test_util", - "//platform/impl/g3", # build_cleaner: keep - "//platform/public:comm", - "//platform/public:types", - ], -) - -cc_test( - name = "core_internal_mediums_webrtc_test", - size = "small", - srcs = [ - "webrtc_peer_id_test.cc", - "webrtc_test.cc", - ], - shard_count = 16, - tags = [ - "notsan", # NOTE(b/139734036): known data race in usrsctplib. - "requires-net:external", - ], - deps = [ - ":mediums", - ":utils", - "//testing/base/public:gunit_main", - "//platform/base", - "//platform/base:test_util", - "//platform/impl/g3", # build_cleaner: keep - "//platform/public:types", - ], -) 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 deleted file mode 100644 index 63e54f8dce7..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble.cc +++ /dev/null @@ -1,361 +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/ble.h" - -#include <memory> -#include <string> -#include <utility> - -#include "absl/strings/escaping.h" -#include "core/internal/mediums/ble_v2/ble_advertisement.h" -#include "core/internal/mediums/utils.h" -#include "platform/base/prng.h" -#include "platform/public/logging.h" -#include "platform/public/mutex_lock.h" - -namespace location { -namespace nearby { -namespace connections { - -ByteArray Ble::GenerateHash(const std::string& source, size_t size) { - return Utils::Sha256Hash(source, size); -} - -ByteArray Ble::GenerateDeviceToken() { - return Utils::Sha256Hash(std::to_string(Prng().NextUint32()), - mediums::BleAdvertisement::kDeviceTokenLength); -} - -Ble::Ble(BluetoothRadio& radio) : radio_(radio) {} - -bool Ble::IsAvailable() const { - MutexLock lock(&mutex_); - - return IsAvailableLocked(); -} - -bool Ble::IsAvailableLocked() const { return medium_.IsValid(); } - -bool Ble::StartAdvertising(const std::string& service_id, - const ByteArray& advertisement_bytes, - const std::string& fast_advertisement_service_uuid) { - MutexLock lock(&mutex_); - - if (advertisement_bytes.Empty()) { - NEARBY_LOGS(INFO) - << "Refusing to turn on BLE advertising. Empty advertisement data."; - return false; - } - - if (advertisement_bytes.size() > kMaxAdvertisementLength) { - NEARBY_LOG(INFO, - "Refusing to start BLE advertising because the advertisement " - "was too long. Expected at most %d bytes but received %d.", - kMaxAdvertisementLength, advertisement_bytes.size()); - return false; - } - - if (IsAdvertisingLocked(service_id)) { - NEARBY_LOGS(INFO) - << "Failed to BLE advertise because we're already advertising."; - return false; - } - - if (!radio_.IsEnabled()) { - NEARBY_LOGS(INFO) - << "Can't start BLE scanning because Bluetooth was never turned on"; - return false; - } - - if (!IsAvailableLocked()) { - NEARBY_LOGS(INFO) << "Can't turn on BLE advertising. BLE is not available."; - return false; - } - - NEARBY_LOGS(INFO) << "Turning on BLE advertising (advertisement size=" - << advertisement_bytes.size() << ")" - << ", service id=" << service_id - << ", fast advertisement service uuid=" - << fast_advertisement_service_uuid; - - // Wrap the connections advertisement to the medium advertisement. - const bool fast_advertisement = !fast_advertisement_service_uuid.empty(); - ByteArray service_id_hash{GenerateHash( - service_id, mediums::BleAdvertisement::kServiceIdHashLength)}; - ByteArray medium_advertisement_bytes{mediums::BleAdvertisement{ - mediums::BleAdvertisement::Version::kV2, - mediums::BleAdvertisement::SocketVersion::kV2, - fast_advertisement ? ByteArray{} : service_id_hash, advertisement_bytes, - GenerateDeviceToken()}}; - if (medium_advertisement_bytes.Empty()) { - NEARBY_LOGS(INFO) << "Failed to BLE advertise because we could not " - "create a medium advertisement."; - return false; - } - - if (!medium_.StartAdvertising(service_id, medium_advertisement_bytes, - fast_advertisement_service_uuid)) { - NEARBY_LOGS(ERROR) - << "Failed to turn on BLE advertising with advertisement bytes=" - << absl::BytesToHexString(advertisement_bytes.data()) - << ", size=" << advertisement_bytes.size() - << ", fast advertisement service uuid=" - << fast_advertisement_service_uuid; - return false; - } - - advertising_info_.Add(service_id); - return true; -} - -bool Ble::StopAdvertising(const std::string& service_id) { - MutexLock lock(&mutex_); - - if (!IsAdvertisingLocked(service_id)) { - NEARBY_LOGS(INFO) << "Can't turn off BLE advertising; it is already off"; - return false; - } - - NEARBY_LOGS(INFO) << "Turned off BLE advertising with service id=" - << service_id; - bool ret = medium_.StopAdvertising(service_id); - // Reset our bundle of advertising state to mark that we're no longer - // advertising. - advertising_info_.Remove(service_id); - return ret; -} - -bool Ble::IsAdvertising(const std::string& service_id) { - MutexLock lock(&mutex_); - - return IsAdvertisingLocked(service_id); -} - -bool Ble::IsAdvertisingLocked(const std::string& service_id) { - return advertising_info_.Existed(service_id); -} - -bool Ble::StartScanning(const std::string& service_id, - const std::string& fast_advertisement_service_uuid, - DiscoveredPeripheralCallback callback) { - MutexLock lock(&mutex_); - - discovered_peripheral_callback_ = std::move(callback); - - if (service_id.empty()) { - NEARBY_LOGS(INFO) - << "Refusing to start BLE scanning with empty service id."; - return false; - } - - if (IsScanningLocked(service_id)) { - NEARBY_LOGS(INFO) << "Refusing to start scan of BLE peripherals because " - "another scanning is already in-progress."; - return false; - } - - if (!radio_.IsEnabled()) { - NEARBY_LOGS(INFO) - << "Can't start BLE scanning because Bluetooth was never turned on"; - return false; - } - - if (!IsAvailableLocked()) { - NEARBY_LOGS(INFO) - << "Can't scan BLE peripherals because BLE isn't available."; - return false; - } - - if (!medium_.StartScanning( - service_id, fast_advertisement_service_uuid, - { - .peripheral_discovered_cb = - [this](BlePeripheral& peripheral, - const std::string& service_id, - const ByteArray& medium_advertisement_bytes, - bool fast_advertisement) { - // Don't bother trying to parse zero byte advertisements. - if (medium_advertisement_bytes.size() == 0) { - NEARBY_LOGS(INFO) << "Skipping zero byte advertisement " - << "with service_id: " << service_id; - return; - } - // Unwrap connection BleAdvertisement from medium - // BleAdvertisement. - auto connection_advertisement_bytes = - UnwrapAdvertisementBytes(medium_advertisement_bytes); - discovered_peripheral_callback_.peripheral_discovered_cb( - peripheral, service_id, connection_advertisement_bytes, - fast_advertisement); - }, - .peripheral_lost_cb = - [this](BlePeripheral& peripheral, - const std::string& service_id) { - discovered_peripheral_callback_.peripheral_lost_cb( - peripheral, service_id); - }, - })) { - NEARBY_LOGS(INFO) << "Failed to start scan of BLE services."; - return false; - } - - NEARBY_LOGS(INFO) << "Turned on BLE scanning with service id=" << service_id; - // Mark the fact that we're currently performing a BLE discovering. - scanning_info_.Add(service_id); - return true; -} - -bool Ble::StopScanning(const std::string& service_id) { - MutexLock lock(&mutex_); - - if (!IsScanningLocked(service_id)) { - NEARBY_LOGS(INFO) << "Can't turn off BLE sacanning because we never " - "started scanning."; - return false; - } - - NEARBY_LOG(INFO, "Turned off BLE scanning with service id=%s", - service_id.c_str()); - bool ret = medium_.StopScanning(service_id); - scanning_info_.Clear(); - return ret; -} - -bool Ble::IsScanning(const std::string& service_id) { - MutexLock lock(&mutex_); - - return IsScanningLocked(service_id); -} - -bool Ble::IsScanningLocked(const std::string& service_id) { - return scanning_info_.Existed(service_id); -} - -bool Ble::StartAcceptingConnections(const std::string& service_id, - AcceptedConnectionCallback callback) { - MutexLock lock(&mutex_); - - if (service_id.empty()) { - NEARBY_LOGS(INFO) - << "Refusing to start accepting BLE connections with empty service id."; - return false; - } - - if (IsAcceptingConnectionsLocked(service_id)) { - NEARBY_LOGS(INFO) - << "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."; - return false; - } - - if (!IsAvailableLocked()) { - NEARBY_LOGS(INFO) << "Can't start accepting BLE connections for " - << service_id << " because BLE isn't available."; - return false; - } - - if (!medium_.StartAcceptingConnections(service_id, callback)) { - NEARBY_LOGS(INFO) << "Failed to accept connections callback for " - << service_id << " ."; - return false; - } - - accepting_connections_info_.Add(service_id); - return true; -} - -bool Ble::StopAcceptingConnections(const std::string& service_id) { - MutexLock lock(&mutex_); - - if (!IsAcceptingConnectionsLocked(service_id)) { - NEARBY_LOGS(INFO) - << "Can't stop accepting BLE connections because it was never started."; - return false; - } - - bool ret = medium_.StopAcceptingConnections(service_id); - // Reset our bundle of accepting connections state to mark that we're no - // longer accepting connections. - accepting_connections_info_.Remove(service_id); - return ret; -} - -bool Ble::IsAcceptingConnections(const std::string& service_id) { - MutexLock lock(&mutex_); - - return IsAcceptingConnectionsLocked(service_id); -} - -bool Ble::IsAcceptingConnectionsLocked(const std::string& service_id) { - return accepting_connections_info_.Existed(service_id); -} - -BleSocket Ble::Connect(BlePeripheral& peripheral, const std::string& service_id, - CancellationFlag* cancellation_flag) { - MutexLock lock(&mutex_); - NEARBY_LOGS(INFO) << "BLE::Connect: service=" << &peripheral; - // Socket to return. To allow for NRVO to work, it has to be a single object. - BleSocket socket; - - if (service_id.empty()) { - NEARBY_LOGS(INFO) << "Refusing to create BLE socket with empty service_id."; - return socket; - } - - if (!radio_.IsEnabled()) { - NEARBY_LOGS(INFO) << "Can't create client BLE socket to " << &peripheral - << " because Bluetooth isn't enabled."; - return socket; - } - - if (!IsAvailableLocked()) { - NEARBY_LOGS(INFO) << "Can't create client BLE socket [service_id=" - << service_id << "]; BLE isn't available."; - return socket; - } - - if (cancellation_flag->Cancelled()) { - NEARBY_LOGS(INFO) << "Can't create client BLE socket due to cancel."; - return socket; - } - - socket = medium_.Connect(peripheral, service_id, cancellation_flag); - if (!socket.IsValid()) { - NEARBY_LOGS(INFO) << "Failed to Connect via BLE [service=" << service_id - << "]"; - } - - return socket; -} - -ByteArray Ble::UnwrapAdvertisementBytes( - const ByteArray& medium_advertisement_data) { - mediums::BleAdvertisement medium_ble_advertisement{medium_advertisement_data}; - if (!medium_ble_advertisement.IsValid()) { - return ByteArray{}; - } - - return medium_ble_advertisement.GetData(); -} - -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble.h deleted file mode 100644 index bfacb340bfb..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble.h +++ /dev/null @@ -1,188 +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_BLE_H_ -#define CORE_INTERNAL_MEDIUMS_BLE_H_ - -#include <cstdint> -#include <string> - -#include "absl/container/flat_hash_map.h" -#include "absl/container/flat_hash_set.h" -#include "core/internal/mediums/bluetooth_radio.h" -#include "core/listeners.h" -#include "platform/base/byte_array.h" -#include "platform/base/cancellation_flag.h" -#include "platform/public/ble.h" -#include "platform/public/multi_thread_executor.h" -#include "platform/public/mutex.h" - -namespace location { -namespace nearby { -namespace connections { - -class Ble { - public: - using DiscoveredPeripheralCallback = BleMedium::DiscoveredPeripheralCallback; - using AcceptedConnectionCallback = BleMedium::AcceptedConnectionCallback; - - explicit Ble(BluetoothRadio& bluetooth_radio); - ~Ble() = default; - - // Returns true, if Ble communications are supported by a platform. - bool IsAvailable() const ABSL_LOCKS_EXCLUDED(mutex_); - - // Sets custom advertisement data, and then enables Ble advertising. - // Returns true, if data is successfully set, and false otherwise. - bool StartAdvertising(const std::string& service_id, - const ByteArray& advertisement_bytes, - const std::string& fast_advertisement_service_uuid) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Disables Ble advertising. - bool StopAdvertising(const std::string& service_id) - ABSL_LOCKS_EXCLUDED(mutex_); - - bool IsAdvertising(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_); - - // Enables Ble scanning mode. Will report any discoverable peripherals in - // range through a callback. Returns true, if scanning mode was enabled, - // false otherwise. - bool StartScanning(const std::string& service_id, - const std::string& fast_advertisement_service_uuid, - DiscoveredPeripheralCallback callback) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Disables Ble discovery mode. - bool StopScanning(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_); - - bool IsScanning(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_); - - // Starts a worker thread, creates a Ble socket, associates it with a - // service id. - bool StartAcceptingConnections(const std::string& service_id, - AcceptedConnectionCallback callback) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Closes socket corresponding to a service id. - bool StopAcceptingConnections(const std::string& service_id) - ABSL_LOCKS_EXCLUDED(mutex_); - - bool IsAcceptingConnections(const std::string& service_id) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Returns true if this object owns a valid platform implementation. - bool IsMediumValid() const ABSL_LOCKS_EXCLUDED(mutex_) { - MutexLock lock(&mutex_); - return medium_.IsValid(); - } - - // Returns true if this object has a valid BluetoothAdapter reference. - bool IsAdapterValid() const ABSL_LOCKS_EXCLUDED(mutex_) { - MutexLock lock(&mutex_); - return adapter_.IsValid(); - } - - // Establishes connection to Ble peripheral that was might be started on - // another peripheral with StartAcceptingConnections() using the same - // service_id. Blocks until connection is established, or server-side is - // terminated. Returns socket instance. On success, BleSocket.IsValid() return - // true. - BleSocket Connect(BlePeripheral& peripheral, const std::string& service_id, - CancellationFlag* cancellation_flag) - ABSL_LOCKS_EXCLUDED(mutex_); - - private: - struct AdvertisingInfo { - bool Empty() const { return service_ids.empty(); } - void Clear() { service_ids.clear(); } - void Add(const std::string& service_id) { service_ids.emplace(service_id); } - void Remove(const std::string& service_id) { - service_ids.erase(service_id); - } - bool Existed(const std::string& service_id) const { - return service_ids.contains(service_id); - } - - absl::flat_hash_set<std::string> service_ids; - }; - - struct ScanningInfo { - bool Empty() const { return service_ids.empty(); } - void Clear() { service_ids.clear(); } - void Add(const std::string& service_id) { service_ids.emplace(service_id); } - void Remove(const std::string& service_id) { - service_ids.erase(service_id); - } - bool Existed(const std::string& service_id) const { - return service_ids.contains(service_id); - } - - absl::flat_hash_set<std::string> service_ids; - }; - - struct AcceptingConnectionsInfo { - bool Empty() const { return service_ids.empty(); } - void Clear() { service_ids.clear(); } - void Add(const std::string& service_id) { service_ids.emplace(service_id); } - void Remove(const std::string& service_id) { - service_ids.erase(service_id); - } - bool Existed(const std::string& service_id) const { - return service_ids.contains(service_id); - } - - absl::flat_hash_set<std::string> service_ids; - }; - - static constexpr int kMaxAdvertisementLength = 512; - - static ByteArray GenerateHash(const std::string& source, size_t size); - static ByteArray GenerateDeviceToken(); - - // Same as IsAvailable(), but must be called with mutex_ held. - bool IsAvailableLocked() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Same as IsAdvertising(), but must be called with mutex_ held. - bool IsAdvertisingLocked(const std::string& service_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Same as IsDiscovering(), but must be called with mutex_ held. - bool IsScanningLocked(const std::string& service_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Same as IsAcceptingConnections(), but must be called with mutex_ held. - bool IsAcceptingConnectionsLocked(const std::string& service_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Extract connection advertisement from medium advertisement. - ByteArray UnwrapAdvertisementBytes( - const ByteArray& medium_advertisement_data); - - mutable Mutex mutex_; - BluetoothRadio& radio_ ABSL_GUARDED_BY(mutex_); - BluetoothAdapter& adapter_ ABSL_GUARDED_BY(mutex_){ - radio_.GetBluetoothAdapter()}; - BleMedium medium_ ABSL_GUARDED_BY(mutex_){adapter_}; - AdvertisingInfo advertising_info_ ABSL_GUARDED_BY(mutex_); - ScanningInfo scanning_info_ ABSL_GUARDED_BY(mutex_); - DiscoveredPeripheralCallback discovered_peripheral_callback_; - AcceptingConnectionsInfo accepting_connections_info_ ABSL_GUARDED_BY(mutex_); -}; - -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_BLE_H_ diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_test.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_test.cc deleted file mode 100644 index 6f03e677617..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_test.cc +++ /dev/null @@ -1,263 +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/ble.h" - -#include <string> - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "core/internal/mediums/bluetooth_radio.h" -#include "platform/base/medium_environment.h" -#include "platform/public/ble.h" -#include "platform/public/count_down_latch.h" -#include "platform/public/logging.h" - -namespace location { -namespace nearby { -namespace connections { -namespace { - -using FeatureFlags = FeatureFlags::Flags; - -constexpr FeatureFlags kTestCases[] = { - FeatureFlags{ - .enable_cancellation_flag = true, - }, - FeatureFlags{ - .enable_cancellation_flag = false, - }, -}; - -constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000); -constexpr absl::string_view kServiceID{"com.google.location.nearby.apps.test"}; -constexpr absl::string_view kAdvertisementString{"\x0a\x0b\x0c\x0d"}; -constexpr absl::string_view kFastAdvertisementServiceUuid{"\xf3\xfe"}; - -class BleTest : public ::testing::TestWithParam<FeatureFlags> { - protected: - using DiscoveredPeripheralCallback = BleMedium::DiscoveredPeripheralCallback; - - BleTest() { env_.Stop(); } - - MediumEnvironment& env_{MediumEnvironment::Instance()}; -}; - -TEST_P(BleTest, CanStartAcceptingConnectionsAndConnect) { - FeatureFlags feature_flags = GetParam(); - env_.SetFeatureFlags(feature_flags); - env_.Start(); - BluetoothRadio radio_a; - BluetoothRadio radio_b; - Ble ble_a{radio_a}; - Ble ble_b{radio_b}; - radio_a.Enable(); - radio_b.Enable(); - std::string service_id(kServiceID); - ByteArray advertisement_bytes{std::string(kAdvertisementString)}; - std::string fast_advertisement_service_uuid(kFastAdvertisementServiceUuid); - CountDownLatch found_latch(1); - CountDownLatch accept_latch(1); - - ble_a.StartAdvertising(service_id, advertisement_bytes, - fast_advertisement_service_uuid); - ble_a.StartAcceptingConnections( - service_id, - { - .accepted_cb = [&accept_latch]( - BleSocket socket, - const std::string&) { accept_latch.CountDown(); }, - }); - BlePeripheral discovered_peripheral; - ble_b.StartScanning( - service_id, fast_advertisement_service_uuid, - { - .peripheral_discovered_cb = - [&found_latch, &discovered_peripheral]( - BlePeripheral& peripheral, const std::string& service_id, - const ByteArray& advertisement_bytes, - bool fast_advertisement) { - discovered_peripheral = peripheral; - NEARBY_LOG( - INFO, - "Discovered peripheral=%p [impl=%p], fast advertisement=%d", - &peripheral, &peripheral.GetImpl(), fast_advertisement); - found_latch.CountDown(); - }, - }); - - EXPECT_TRUE(found_latch.Await(kWaitDuration).result()); - ASSERT_TRUE(discovered_peripheral.IsValid()); - CancellationFlag flag; - BleSocket socket = ble_b.Connect(discovered_peripheral, service_id, &flag); - EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(socket.IsValid()); - ble_b.StopScanning(service_id); - ble_a.StopAdvertising(service_id); - env_.Stop(); -} - -TEST_P(BleTest, CanCancelConnect) { - FeatureFlags feature_flags = GetParam(); - env_.SetFeatureFlags(feature_flags); - env_.Start(); - BluetoothRadio radio_a; - BluetoothRadio radio_b; - Ble ble_a{radio_a}; - Ble ble_b{radio_b}; - radio_a.Enable(); - radio_b.Enable(); - std::string service_id(kServiceID); - ByteArray advertisement_bytes{std::string(kAdvertisementString)}; - std::string fast_advertisement_service_uuid(kFastAdvertisementServiceUuid); - CountDownLatch found_latch(1); - CountDownLatch accept_latch(1); - - ble_a.StartAdvertising(service_id, advertisement_bytes, - fast_advertisement_service_uuid); - ble_a.StartAcceptingConnections( - service_id, - { - .accepted_cb = [&accept_latch]( - BleSocket socket, - const std::string&) { accept_latch.CountDown(); }, - }); - BlePeripheral discovered_peripheral; - ble_b.StartScanning( - service_id, fast_advertisement_service_uuid, - { - .peripheral_discovered_cb = - [&found_latch, &discovered_peripheral]( - BlePeripheral& peripheral, const std::string& service_id, - const ByteArray& advertisement_bytes, - bool fast_advertisement) { - discovered_peripheral = peripheral; - NEARBY_LOG( - INFO, - "Discovered peripheral=%p [impl=%p], fast advertisement=%d", - &peripheral, &peripheral.GetImpl(), fast_advertisement); - found_latch.CountDown(); - }, - }); - - EXPECT_TRUE(found_latch.Await(kWaitDuration).result()); - ASSERT_TRUE(discovered_peripheral.IsValid()); - CancellationFlag flag(true); - BleSocket socket = ble_b.Connect(discovered_peripheral, service_id, &flag); - // If FeatureFlag is disabled, Cancelled is false as no-op. - if (!feature_flags.enable_cancellation_flag) { - EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(socket.IsValid()); - } else { - EXPECT_FALSE(accept_latch.Await(kWaitDuration).result()); - EXPECT_FALSE(socket.IsValid()); - } - ble_b.StopScanning(service_id); - ble_a.StopAdvertising(service_id); - env_.Stop(); -} - -INSTANTIATE_TEST_SUITE_P(ParametrisedBleTest, BleTest, - ::testing::ValuesIn(kTestCases)); - -TEST_F(BleTest, CanConstructValidObject) { - env_.Start(); - BluetoothRadio radio_a; - BluetoothRadio radio_b; - Ble ble_a{radio_a}; - Ble ble_b{radio_b}; - - EXPECT_TRUE(ble_a.IsMediumValid()); - EXPECT_TRUE(ble_a.IsAdapterValid()); - EXPECT_TRUE(ble_a.IsAvailable()); - EXPECT_TRUE(ble_b.IsMediumValid()); - EXPECT_TRUE(ble_b.IsAdapterValid()); - EXPECT_TRUE(ble_b.IsAvailable()); - EXPECT_NE(&radio_a.GetBluetoothAdapter(), &radio_b.GetBluetoothAdapter()); - env_.Stop(); -} - -TEST_F(BleTest, CanStartAdvertising) { - env_.Start(); - BluetoothRadio radio_a; - BluetoothRadio radio_b; - Ble ble_a{radio_a}; - Ble ble_b{radio_b}; - radio_a.Enable(); - radio_b.Enable(); - std::string service_id(kServiceID); - ByteArray advertisement_bytes{std::string(kAdvertisementString)}; - std::string fast_advertisement_service_uuid(kFastAdvertisementServiceUuid); - CountDownLatch found_latch(1); - - ble_b.StartScanning( - service_id, fast_advertisement_service_uuid, - DiscoveredPeripheralCallback{ - .peripheral_discovered_cb = - [&found_latch]( - BlePeripheral& peripheral, const std::string& service_id, - const ByteArray& advertisement_bytes, - bool fast_advertisement) { found_latch.CountDown(); }, - }); - - EXPECT_TRUE(ble_a.StartAdvertising(service_id, advertisement_bytes, - fast_advertisement_service_uuid)); - EXPECT_TRUE(found_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(ble_a.StopAdvertising(service_id)); - EXPECT_TRUE(ble_b.StopScanning(service_id)); - env_.Stop(); -} - -TEST_F(BleTest, CanStartDiscovery) { - env_.Start(); - BluetoothRadio radio_a; - BluetoothRadio radio_b; - Ble ble_a{radio_a}; - Ble ble_b{radio_b}; - radio_a.Enable(); - radio_b.Enable(); - std::string service_id(kServiceID); - ByteArray advertisement_bytes{std::string(kAdvertisementString)}; - std::string fast_advertisement_service_uuid(kFastAdvertisementServiceUuid); - CountDownLatch accept_latch(1); - CountDownLatch lost_latch(1); - - ble_b.StartAdvertising(service_id, advertisement_bytes, - fast_advertisement_service_uuid); - - EXPECT_TRUE(ble_a.StartScanning( - service_id, fast_advertisement_service_uuid, - DiscoveredPeripheralCallback{ - .peripheral_discovered_cb = - [&accept_latch]( - BlePeripheral& peripheral, const std::string& service_id, - const ByteArray& advertisement_bytes, - bool fast_advertisement) { accept_latch.CountDown(); }, - .peripheral_lost_cb = - [&lost_latch](BlePeripheral& peripheral, - const std::string& service_id) { - lost_latch.CountDown(); - }, - })); - EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); - ble_b.StopAdvertising(service_id); - EXPECT_TRUE(lost_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(ble_a.StopScanning(service_id)); - env_.Stop(); -} - -} // namespace -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/BUILD b/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/BUILD deleted file mode 100644 index 6aff35972f6..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/BUILD +++ /dev/null @@ -1,67 +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. -licenses(["notice"]) - -cc_library( - name = "ble_v2", - srcs = [ - "advertisement_read_result.cc", - "ble_advertisement.cc", - "ble_advertisement_header.cc", - "ble_packet.cc", - ], - hdrs = [ - "advertisement_read_result.h", - "ble_advertisement.h", - "ble_advertisement_header.h", - "ble_packet.h", - "ble_peripheral.h", - "discovered_peripheral_callback.h", - ], - compatible_with = ["//buildenv/target:non_prod"], - copts = ["-DCORE_ADAPTER_DLL"], - visibility = [ - "//core/internal:__subpackages__", - ], - deps = [ - "//absl/container:flat_hash_map", - "//absl/container:flat_hash_set", - "//absl/strings", - "//absl/time", - "//core:core_types", - "//platform/base", - "//platform/base:util", - "//platform/public:logging", - "//platform/public:types", - ], -) - -cc_test( - name = "ble_v2_test", - srcs = [ - "advertisement_read_result_test.cc", - "ble_advertisement_header_test.cc", - "ble_advertisement_test.cc", - "ble_packet_test.cc", - "ble_peripheral_test.cc", - ], - deps = [ - ":ble_v2", - "//testing/base/public:gunit_main", - "//absl/time", - "//platform/base", - "//platform/impl/g3", # buildcleaner: keep - "//platform/public:comm", - ], -) diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/advertisement_read_result.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/advertisement_read_result.cc deleted file mode 100644 index aa82f0ed522..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/advertisement_read_result.cc +++ /dev/null @@ -1,139 +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/ble_v2/advertisement_read_result.h" - -#include <algorithm> -#include <vector> - -#include "absl/container/flat_hash_set.h" -#include "absl/time/clock.h" -#include "platform/public/mutex_lock.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -const AdvertisementReadResult::Config AdvertisementReadResult::kDefaultConfig{ - .backoff_multiplier = 2.0, - .base_backoff_duration = absl::Seconds(1), - .max_backoff_duration = absl::Minutes(5), -}; - -// Adds a successfully read advertisement for the specified slot to this read -// result. This is fundamentally different from RecordLastReadStatus() because -// we can report a read failure, but still manage to read some advertisements. -void AdvertisementReadResult::AddAdvertisement(std::int32_t slot, - const ByteArray& advertisement) { - MutexLock lock(&mutex_); - - // Blindly remove from the advertisements map to make sure any existing - // key-value pair is destroyed. - advertisements_.emplace(slot, advertisement); -} - -// Determines whether or not an advertisement was successfully read at the -// specified slot. -bool AdvertisementReadResult::HasAdvertisement(std::int32_t slot) const { - MutexLock lock(&mutex_); - - return advertisements_.contains(slot); -} - -// Retrieves all raw advertisements that were successfully read. -std::vector<const ByteArray*> AdvertisementReadResult::GetAdvertisements() - const { - MutexLock lock(&mutex_); - - std::vector<const ByteArray*> all_advertisements; - all_advertisements.reserve(advertisements_.size()); - for (const auto& item : advertisements_) { - all_advertisements.emplace_back(&item.second); - } - - return all_advertisements; -} - -// Determines what stage we're in for retrying a read from an advertisement -// GATT server. -AdvertisementReadResult::RetryStatus -AdvertisementReadResult::EvaluateRetryStatus() const { - MutexLock lock(&mutex_); - - // Check if we have already succeeded reading this advertisement. - if (status_ == Status::kSuccess) { - return RetryStatus::kPreviouslySucceeded; - } - - // Check if we have recently failed to read this advertisement. - if (GetDurationSinceReadLocked() < backoff_duration_) { - return RetryStatus::kTooSoon; - } - - return RetryStatus::kRetry; -} - -// Records the status of the latest read, and updates the next backoff -// duration for subsequent reads. Be sure to also call -// AddAdvertisement() if any advertisements were read. -void AdvertisementReadResult::RecordLastReadStatus(bool is_success) { - MutexLock lock(&mutex_); - - // Update the last read timestamp. - last_read_timestamp_ = SystemClock::ElapsedRealtime(); - - // Update the backoff duration. - if (is_success) { - // Reset the backoff duration now that we had a successful read. - backoff_duration_ = config_.base_backoff_duration; - } else { - // Determine whether or not we were already failing before. If we were, we - // should increase the backoff duration. - if (status_ == Status::kFailure) { - // Use exponential backoff to determine the next backoff duration. This - // simply involves multiplying our current backoff duration by some - // multiplier. - absl::Duration next_backoff_duration = - config_.backoff_multiplier * backoff_duration_; - // Update the backoff duration, making sure not to blow past the - // ceiling. - backoff_duration_ = - std::min(next_backoff_duration, config_.max_backoff_duration); - } else { - // This is our first time failing, so we should only backoff for the - // initial duration. - backoff_duration_ = config_.base_backoff_duration; - } - } - - // Update the internal result. - status_ = is_success ? Status::kSuccess : Status::kFailure; -} - -// Returns how much time has passed since we last tried reading from an -// advertisement GATT server. -absl::Duration AdvertisementReadResult::GetDurationSinceRead() const { - MutexLock lock(&mutex_); - return GetDurationSinceReadLocked(); -} - -absl::Duration AdvertisementReadResult::GetDurationSinceReadLocked() const { - return SystemClock::ElapsedRealtime() - last_read_timestamp_; -} - -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/advertisement_read_result.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/advertisement_read_result.h deleted file mode 100644 index afd8bb848e8..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/advertisement_read_result.h +++ /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. - -#ifndef CORE_INTERNAL_MEDIUMS_BLE_V2_ADVERTISEMENT_READ_RESULT_H_ -#define CORE_INTERNAL_MEDIUMS_BLE_V2_ADVERTISEMENT_READ_RESULT_H_ - -#include <cstdint> -#include <vector> - -#include "absl/container/flat_hash_map.h" -#include "absl/container/flat_hash_set.h" -#include "absl/time/clock.h" -#include "platform/base/byte_array.h" -#include "platform/public/mutex.h" -#include "platform/public/system_clock.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -// Representation of a GATT advertisement read result. This object helps us -// determine whether or not we need to retry GATT reads. -class AdvertisementReadResult { - public: - // We need a long enough duration such that we always trigger a read - // retry AND we always connect to it without delay. The former case - // helps us initialize an AdvertisementReadResult so that we - // unconditionally try reading on the first sighting. And the latter - // case helps us connect immediately when we initialize a dummy read - // result for fast advertisements (which don't use the GATT server). - - struct Config { - // How much to multiply the backoff duration by with every failure to read - // from the advertisement GATT server. This should never be below 1! - float backoff_multiplier; - // The initial backoff duration when we fail to read from an advertisement - // GATT server. - absl::Duration base_backoff_duration; - // The maximum backoff duration allowed between advertisement GATT server - // reads. - absl::Duration max_backoff_duration; - }; - - static const Config kDefaultConfig; - explicit AdvertisementReadResult(const Config& config = kDefaultConfig) - : config_(config) {} - ~AdvertisementReadResult() = default; - - enum class RetryStatus { - kUnknown = 0, - kRetry = 1, - kPreviouslySucceeded = 2, - kTooSoon = 3, - }; - - void AddAdvertisement(std::int32_t slot, const ByteArray& advertisement) - ABSL_LOCKS_EXCLUDED(mutex_); - bool HasAdvertisement(std::int32_t slot) const ABSL_LOCKS_EXCLUDED(mutex_); - std::vector<const ByteArray*> GetAdvertisements() const - ABSL_LOCKS_EXCLUDED(mutex_); - RetryStatus EvaluateRetryStatus() const ABSL_LOCKS_EXCLUDED(mutex_); - void RecordLastReadStatus(bool is_success) ABSL_LOCKS_EXCLUDED(mutex_); - absl::Duration GetDurationSinceRead() const ABSL_LOCKS_EXCLUDED(mutex_); - - private: - enum class Status { - kUnknown = 0, - kSuccess = 1, - kFailure = 2, - }; - - absl::Duration GetDurationSinceReadLocked() const - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - mutable Mutex mutex_; - - // Maps slot numbers to the GATT advertisement found in that slot. - absl::flat_hash_map<std::int32_t, ByteArray> advertisements_ - ABSL_GUARDED_BY(mutex_); - - Config config_; - absl::Duration backoff_duration_ ABSL_GUARDED_BY(mutex_); - absl::Time last_read_timestamp_ ABSL_GUARDED_BY(mutex_); - Status status_ ABSL_GUARDED_BY(mutex_) = Status::kUnknown; -}; - -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_BLE_V2_ADVERTISEMENT_READ_RESULT_H_ diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/advertisement_read_result_test.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/advertisement_read_result_test.cc deleted file mode 100644 index 90ce51c9a74..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/advertisement_read_result_test.cc +++ /dev/null @@ -1,143 +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/ble_v2/advertisement_read_result.h" - -#include "gtest/gtest.h" -#include "absl/time/clock.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { -namespace { - -constexpr char kAdvertisementBytes[] = "\x0A\x0B\x0C"; - -// Default values may be too big and impractical to wait for in the test. -// For the test platform, we redefine them to some reasonable values. -const absl::Duration kAdvertisementBaseBackoffDuration = absl::Seconds(1); -const absl::Duration kAdvertisementMaxBackoffDuration = absl::Seconds(6); - -const AdvertisementReadResult::Config test_config{ - .backoff_multiplier = - AdvertisementReadResult::kDefaultConfig.backoff_multiplier, - .base_backoff_duration = kAdvertisementBaseBackoffDuration, - .max_backoff_duration = kAdvertisementMaxBackoffDuration, -}; - -TEST(AdvertisementReadResultTest, AdvertisementExists) { - AdvertisementReadResult advertisement_read_result(test_config); - advertisement_read_result.RecordLastReadStatus(/* is_success= */ true); - - std::int32_t slot = 6; - advertisement_read_result.AddAdvertisement(slot, - ByteArray(kAdvertisementBytes)); - - EXPECT_TRUE(advertisement_read_result.HasAdvertisement(slot)); -} - -TEST(AdvertisementReadResultTest, AdvertisementNonExistent) { - AdvertisementReadResult advertisement_read_result(test_config); - advertisement_read_result.RecordLastReadStatus(/* is_success= */ true); - - std::int32_t slot = 6; - - EXPECT_FALSE(advertisement_read_result.HasAdvertisement(slot)); -} - -TEST(AdvertisementReadResultTest, EvaluateRetryStatusInitialized) { - AdvertisementReadResult advertisement_read_result(test_config); - - EXPECT_EQ(advertisement_read_result.EvaluateRetryStatus(), - AdvertisementReadResult::RetryStatus::kRetry); -} - -TEST(AdvertisementReadResultTest, EvaluateRetryStatusSuccess) { - AdvertisementReadResult advertisement_read_result(test_config); - advertisement_read_result.RecordLastReadStatus(/* is_success= */ true); - - EXPECT_EQ(advertisement_read_result.EvaluateRetryStatus(), - AdvertisementReadResult::RetryStatus::kPreviouslySucceeded); -} - -TEST(AdvertisementReadResultTest, EvaluateRetryStatusTooSoon) { - AdvertisementReadResult advertisement_read_result(test_config); - advertisement_read_result.RecordLastReadStatus(/* is_success= */ false); - - // Sleep for some time, but not long enough to warrant a retry. - absl::SleepFor(kAdvertisementBaseBackoffDuration / 2); - - EXPECT_EQ(advertisement_read_result.EvaluateRetryStatus(), - AdvertisementReadResult::RetryStatus::kTooSoon); -} - -TEST(AdvertisementReadResultTest, EvaluateRetryStatusRetry) { - AdvertisementReadResult advertisement_read_result(test_config); - advertisement_read_result.RecordLastReadStatus(/* is_success= */ false); - - // Sleep long enough to warrant a retry. - absl::SleepFor(kAdvertisementBaseBackoffDuration); - - EXPECT_EQ(advertisement_read_result.EvaluateRetryStatus(), - AdvertisementReadResult::RetryStatus::kRetry); -} - -TEST(AdvertisementReadResultTest, ReportStatusExponentialBackoff) { - AdvertisementReadResult advertisement_read_result(test_config); - advertisement_read_result.RecordLastReadStatus(/* is_success= */ false); - - // Record an additional failure so our backoff duration increases. - advertisement_read_result.RecordLastReadStatus(/* is_success= */ false); - - // Sleep for the backoff duration. We shouldn't trigger a retry because the - // backoff should have increased from failing a second time. - absl::SleepFor(kAdvertisementBaseBackoffDuration); - - EXPECT_EQ(advertisement_read_result.EvaluateRetryStatus(), - AdvertisementReadResult::RetryStatus::kTooSoon); -} - -TEST(AdvertisementReadResultTest, ReportStatusExponentialBackoffMax) { - AdvertisementReadResult advertisement_read_result(test_config); - advertisement_read_result.RecordLastReadStatus(/* is_success= */ false); - - // Record an absurd amount of failures so we hit the maximum backoff duration. - for (std::int32_t i = 0; i < 1000; i++) { - advertisement_read_result.RecordLastReadStatus(/* is_success= */ false); - } - - // Sleep for the maximum backoff duration. This should be enough to warrant a - // retry. - absl::SleepFor(kAdvertisementMaxBackoffDuration); - - EXPECT_EQ(advertisement_read_result.EvaluateRetryStatus(), - AdvertisementReadResult::RetryStatus::kRetry); -} - -TEST(AdvertisementReadResultTest, GetDurationSinceRead) { - AdvertisementReadResult advertisement_read_result(test_config); - advertisement_read_result.RecordLastReadStatus(/* is_success= */ true); - - absl::Duration sleepTime = absl::Milliseconds(420); - absl::SleepFor(sleepTime); - - EXPECT_GE(advertisement_read_result.GetDurationSinceRead(), sleepTime); -} - -} // namespace -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_advertisement.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_advertisement.cc deleted file mode 100644 index f6280611954..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_advertisement.cc +++ /dev/null @@ -1,245 +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/ble_v2/ble_advertisement.h" - -#include <inttypes.h> - -#include "absl/strings/str_cat.h" -#include "platform/base/base_input_stream.h" -#include "platform/public/logging.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -BleAdvertisement::BleAdvertisement(Version version, - SocketVersion socket_version, - const ByteArray &service_id_hash, - const ByteArray &data, - const ByteArray &device_token) { - DoInitialize(/*fast_advertisement=*/service_id_hash.Empty(), version, - socket_version, service_id_hash, data, device_token); -} - -void BleAdvertisement::DoInitialize(bool fast_advertisement, Version version, - SocketVersion socket_version, - const ByteArray &service_id_hash, - const ByteArray &data, - const ByteArray &device_token) { - // Check that the given input is valid. - fast_advertisement_ = fast_advertisement; - if (!fast_advertisement_) { - if (service_id_hash.size() != kServiceIdHashLength) return; - } - if (!IsSupportedVersion(version) || - !IsSupportedSocketVersion(socket_version) || - (!device_token.Empty() && device_token.size() != kDeviceTokenLength)) { - return; - } - - int advertisement_Length = ComputeAdvertisementLength( - data.size(), device_token.size(), fast_advertisement_); - int max_advertisement_length = fast_advertisement - ? kMaxFastAdvertisementLength - : kMaxAdvertisementLength; - if (advertisement_Length > max_advertisement_length) { - return; - } - - version_ = version; - socket_version_ = socket_version; - if (!fast_advertisement_) service_id_hash_ = service_id_hash; - data_ = data; - device_token_ = device_token; -} - -BleAdvertisement::BleAdvertisement(const ByteArray &ble_advertisement_bytes) { - if (ble_advertisement_bytes.Empty()) { - NEARBY_LOG(INFO, - "Cannot deserialize BleAdvertisement: null bytes passed in."); - return; - } - - if (ble_advertisement_bytes.size() < kVersionLength) { - NEARBY_LOG( - INFO, - "Cannot deserialize BleAdvertisement: expecting min %d raw bytes to " - "parse the version, got %" PRIu64, - kVersionLength, ble_advertisement_bytes.size()); - return; - } - - ByteArray advertisement_bytes{ble_advertisement_bytes}; - BaseInputStream base_input_stream{advertisement_bytes}; - // The first 1 byte is supposed to be the version, socket version and the fast - // advertisement flag. - auto version_byte = static_cast<char>(base_input_stream.ReadUint8()); - - // Version. - version_ = static_cast<Version>((version_byte & kVersionBitmask) >> 5); - if (!IsSupportedVersion(version_)) { - NEARBY_LOG(INFO, - "Cannot deserialize BleAdvertisement: unsupported Version %u", - version_); - return; - } - - // Socket version. - socket_version_ = - static_cast<SocketVersion>((version_byte & kSocketVersionBitmask) >> 2); - if (!IsSupportedSocketVersion(socket_version_)) { - NEARBY_LOG( - INFO, - "Cannot deserialize BleAdvertisement: unsupported SocketVersion %u", - socket_version_); - version_ = Version::kUndefined; - return; - } - - // Fast advertisement flag. - fast_advertisement_ = - static_cast<bool>((version_byte & kFastAdvertisementFlagBitmask) >> 1); - - // The next 3 bytes are supposed to be the service_id_hash if not fast - // advertisement. - if (!fast_advertisement_) { - service_id_hash_ = base_input_stream.ReadBytes(kServiceIdHashLength); - } - - // Data length. - int expected_data_size = - fast_advertisement_ - ? static_cast<int>( - base_input_stream.ReadBytes(kFastDataSizeLength).data()[0]) - : static_cast<int>(base_input_stream.ReadUint32()); - if (expected_data_size < 0) { - NEARBY_LOG(INFO, - "Cannot deserialize BleAdvertisement: negative data size %d", - expected_data_size); - version_ = Version::kUndefined; - return; - } - - // Data. - // Check that the stated data size is the same as what we received. - data_ = base_input_stream.ReadBytes(expected_data_size); - if (data_.size() != expected_data_size) { - NEARBY_LOG(INFO, - "Cannot deserialize BleAdvertisement: expected data to be %u " - "bytes, got %" PRIu64 " bytes ", - expected_data_size, data_.size()); - version_ = Version::kUndefined; - return; - } - - // Device token. If the number of remaining bytes are valid for device token, - // then read it. - if (base_input_stream.IsAvailable(kDeviceTokenLength)) { - device_token_ = base_input_stream.ReadBytes(kDeviceTokenLength); - } -} - -BleAdvertisement::operator ByteArray() const { - if (!IsValid()) { - return ByteArray{}; - } - - // The first 3 bits are the Version. - char version_byte = (static_cast<char>(version_) << 5) & kVersionBitmask; - // The next 3 bits are the Socket version. 2 bits left are reserved. - version_byte |= - (static_cast<char>(socket_version_) << 2) & kSocketVersionBitmask; - // The next 1 bit is the fast advertisement flag. 1 bit left is reserved. - version_byte |= (static_cast<char>(fast_advertisement_ ? 1 : 0) << 1) & - kFastAdvertisementFlagBitmask; - - // Serialize Data size bytes - ByteArray data_size_bytes{static_cast<size_t>( - fast_advertisement_ ? kFastDataSizeLength : kDataSizeLength)}; - auto *data_size_bytes_write_ptr = data_size_bytes.data(); - SerializeDataSize(fast_advertisement_, data_size_bytes_write_ptr, - data_.size()); - - // clang-format on - if (fast_advertisement_) { - std::string out = - absl::StrCat(std::string(1, version_byte), std::string(data_size_bytes), - std::string(data_), std::string(device_token_)); - return ByteArray{std::move(out)}; - } else { - std::string out = absl::StrCat( - std::string(1, version_byte), std::string(service_id_hash_), - std::string(data_size_bytes), std::string(data_), - std::string(device_token_)); - return ByteArray{std::move(out)}; - } - // clang-format on -} - -bool BleAdvertisement::operator==(const BleAdvertisement &rhs) const { - return this->GetVersion() == rhs.GetVersion() && - this->GetSocketVersion() == rhs.GetSocketVersion() && - this->GetServiceIdHash() == rhs.GetServiceIdHash() && - this->GetData() == rhs.GetData() && - this->GetDeviceToken() == rhs.GetDeviceToken(); -} - -bool BleAdvertisement::operator<(const BleAdvertisement &rhs) const { - if (this->GetVersion() != rhs.GetVersion()) { - return this->GetVersion() < rhs.GetVersion(); - } - if (this->GetSocketVersion() != rhs.GetSocketVersion()) { - return this->GetSocketVersion() < rhs.GetSocketVersion(); - } - if (this->GetServiceIdHash() != rhs.GetServiceIdHash()) { - return this->GetServiceIdHash() < rhs.GetServiceIdHash(); - } - if (this->GetDeviceToken() != rhs.GetDeviceToken()) { - return this->GetDeviceToken() < rhs.GetDeviceToken(); - } - return this->GetData() < rhs.GetData(); -} - -bool BleAdvertisement::IsSupportedVersion(Version version) const { - return version >= Version::kV1 && version <= Version::kV2; -} - -bool BleAdvertisement::IsSupportedSocketVersion( - SocketVersion socket_version) const { - return socket_version >= SocketVersion::kV1 && - socket_version <= SocketVersion::kV2; -} - -void BleAdvertisement::SerializeDataSize(bool fast_advertisement, - char *data_size_bytes_write_ptr, - size_t data_size) const { - // Get a raw representation of the data size bytes in memory. - char *data_size_bytes = reinterpret_cast<char *>(&data_size); - - const int data_size_length = - fast_advertisement ? kFastDataSizeLength : kDataSizeLength; - - // Append these raw bytes to advertisement bytes, keeping in mind that we need - // to convert from Little Endian to Big Endian in the process. - for (int i = 0; i < data_size_length; ++i) { - data_size_bytes_write_ptr[i] = data_size_bytes[data_size_length - i - 1]; - } -} - -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_advertisement.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_advertisement.h deleted file mode 100644 index 176f4bfd7b0..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_advertisement.h +++ /dev/null @@ -1,139 +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_BLE_V2_BLE_ADVERTISEMENT_H_ -#define CORE_INTERNAL_MEDIUMS_BLE_V2_BLE_ADVERTISEMENT_H_ - -#include <utility> - -#include "platform/base/byte_array.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -// Represents the format of the Mediums BLE Advertisement used in Advertising + -// Discovery. -// -// [VERSION][SOCKET_VERSION][FAST_ADVERTISEMENT_FLAG][1_RESERVED_BIT][SERVICE_ID_HASH][DATA_SIZE][DATA][DEVICE_TOKEN] -// -// For fast advertisement, we remove SERVICE_ID_HASH since we already have one -// copy in Nearby Connections(b/138447288) -// [VERSION][SOCKET_VERSION][FAST_ADVERTISEMENT_FLAG][1_RESERVED_BIT][DATA_SIZE][DATA][DEVICE_TOKEN] -// -// See go/nearby-ble-design for more information. -class BleAdvertisement { - public: - // Versions of the BleAdvertisement. - enum class Version { - kUndefined = 0, - kV1 = 1, - kV2 = 2, - // Version is only allocated 3 bits in the BleAdvertisement, so this can - // never go beyond V7. - }; - - // Versions of the BLESocket. - enum class SocketVersion { - kUndefined = 0, - kV1 = 1, - kV2 = 2, - // SocketVersion is only allocated 3 bits in the BleAdvertisement, so this - // can never go beyond V7. - }; - - static constexpr int kServiceIdHashLength = 3; - static constexpr int kDeviceTokenLength = 2; - - BleAdvertisement() = default; - BleAdvertisement(Version version, SocketVersion socket_version, - const ByteArray &service_id_hash, const ByteArray &data, - const ByteArray &device_token); - explicit BleAdvertisement(const ByteArray &ble_advertisement_bytes); - BleAdvertisement(const BleAdvertisement &) = default; - BleAdvertisement &operator=(const BleAdvertisement &) = default; - BleAdvertisement(BleAdvertisement &&) = default; - BleAdvertisement &operator=(BleAdvertisement &&) = default; - ~BleAdvertisement() = default; - - explicit operator ByteArray() const; - // Operator overloads when comparing BleAdvertisement. - bool operator==(const BleAdvertisement &rhs) const; - bool operator<(const BleAdvertisement &rhs) const; - - bool IsValid() const { return IsSupportedVersion(version_); } - Version GetVersion() const { return version_; } - SocketVersion GetSocketVersion() const { return socket_version_; } - bool IsFastAdvertisement() const { return fast_advertisement_; } - ByteArray GetServiceIdHash() const { return service_id_hash_; } - ByteArray &GetData() & { return data_; } - const ByteArray &GetData() const & { return data_; } - ByteArray &&GetData() && { return std::move(data_); } - const ByteArray &&GetData() const && { return std::move(data_); } - ByteArray GetDeviceToken() const { return device_token_; } - - private: - void DoInitialize(bool fast_advertisement, Version version, - SocketVersion socket_version, - const ByteArray &service_id_hash, const ByteArray &data, - const ByteArray &device_token); - bool IsSupportedVersion(Version version) const; - bool IsSupportedSocketVersion(SocketVersion socket_version) const; - void SerializeDataSize(bool fast_advertisement, - char *data_size_bytes_write_ptr, - size_t data_size) const; - int ComputeAdvertisementLength(int data_length, int total_optional_length, - bool fast_advertisement) const { - // The advertisement length is the minimum length + the length of the data + - // the length of in-use optional fields. - return fast_advertisement ? (kMinFastAdvertisementLegth + data_length + - total_optional_length) - : (kMinAdvertisementLength + data_length + - total_optional_length); - } - - static constexpr int kVersionLength = 1; - static constexpr int kVersionBitmask = 0x0E0; - static constexpr int kSocketVersionBitmask = 0x01C; - static constexpr int kFastAdvertisementFlagBitmask = 0x002; - static constexpr int kDataSizeLength = 4; // Length of one int. - static constexpr int kFastDataSizeLength = 1; // Length of one byte. - static constexpr int kMinAdvertisementLength = - kVersionLength + kServiceIdHashLength + kDataSizeLength; - // The maximum length for a Gatt characteristic value is 512 bytes, so make - // sure the entire advertisement is less than that. The data can take up - // whatever space is remaining after the bytes preceding it. - static constexpr int kMaxAdvertisementLength = 512; - static constexpr int kMinFastAdvertisementLegth = - kVersionLength + kFastDataSizeLength; - // The maximum length for the scan response is 31 bytes. However, with the - // required header that comes before the service data, this leaves the - // advertiser with 27 leftover bytes. - static constexpr int kMaxFastAdvertisementLength = 27; - - Version version_{Version::kUndefined}; - SocketVersion socket_version_{SocketVersion::kUndefined}; - bool fast_advertisement_ = false; - ByteArray service_id_hash_; - ByteArray data_; - ByteArray device_token_; -}; - -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_BLE_V2_BLE_ADVERTISEMENT_H_ diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_advertisement_header.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_advertisement_header.cc deleted file mode 100644 index 321924e4f90..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_advertisement_header.cc +++ /dev/null @@ -1,131 +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/ble_v2/ble_advertisement_header.h" - -#include <inttypes.h> - -#include "absl/strings/str_cat.h" -#include "platform/base/base64_utils.h" -#include "platform/base/base_input_stream.h" -#include "platform/public/logging.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -BleAdvertisementHeader::BleAdvertisementHeader( - Version version, int num_slots, const ByteArray &service_id_bloom_filter, - const ByteArray &advertisement_hash) { - if (version != Version::kV2 || num_slots <= 0 || - service_id_bloom_filter.size() != kServiceIdBloomFilterLength || - advertisement_hash.size() != kAdvertisementHashLength) { - return; - } - - version_ = version; - num_slots_ = num_slots; - service_id_bloom_filter_ = service_id_bloom_filter; - advertisement_hash_ = advertisement_hash; -} - -BleAdvertisementHeader::BleAdvertisementHeader( - const std::string &ble_advertisement_header_string) { - ByteArray ble_advertisement_header_bytes = - Base64Utils::Decode(ble_advertisement_header_string); - - if (ble_advertisement_header_bytes.Empty()) { - NEARBY_LOG( - ERROR, - "Cannot deserialize BLEAdvertisementHeader: failed Base64 decoding"); - return; - } - - if (ble_advertisement_header_bytes.size() < kMinAdvertisementHeaderLength) { - NEARBY_LOG(ERROR, - "Cannot deserialize BleAdvertisementHeader: expecting min %u " - "raw bytes, got %" PRIu64 " instead", - kMinAdvertisementHeaderLength, - ble_advertisement_header_bytes.size()); - return; - } - - BaseInputStream base_input_stream{ble_advertisement_header_bytes}; - // The first 1 byte is supposed to be the version and number of slots. - auto version_and_pcp_byte = static_cast<char>(base_input_stream.ReadUint8()); - // The upper 3 bits are supposed to be the version. - version_ = - static_cast<Version>((version_and_pcp_byte & kVersionBitmask) >> 5); - if (version_ != Version::kV2) { - NEARBY_LOG( - ERROR, - "Cannot deserialize BleAdvertisementHeader: unsupported Version %d", - version_); - return; - } - // The lower 5 bits are supposed to be the number of slots. - num_slots_ = static_cast<int>(version_and_pcp_byte & kNumSlotsBitmask); - if (num_slots_ <= 0) { - version_ = Version::kUndefined; - return; - } - - // The next 10 bytes are supposed to be the service_id_bloom_filter. - service_id_bloom_filter_ = - base_input_stream.ReadBytes(kServiceIdBloomFilterLength); - - // The next 4 bytes are supposed to be the advertisement_hash. - advertisement_hash_ = base_input_stream.ReadBytes(kAdvertisementHashLength); -} - -BleAdvertisementHeader::operator std::string() const { - if (!IsValid()) { - return ""; - } - - // The first 3 bits are the Version. - char version_and_num_slots_byte = - (static_cast<char>(version_) << 5) & kVersionBitmask; - // The next 5 bits are the number of slots. - version_and_num_slots_byte |= - static_cast<char>(num_slots_) & kNumSlotsBitmask; - - // clang-format off - std::string out = absl::StrCat(std::string(1, version_and_num_slots_byte), - std::string(service_id_bloom_filter_), - std::string(advertisement_hash_)); - // clang-format on - - return Base64Utils::Encode(ByteArray(std::move(out))); -} - -bool BleAdvertisementHeader::operator<( - const BleAdvertisementHeader &rhs) const { - if (this->GetVersion() != rhs.GetVersion()) { - return this->GetVersion() < rhs.GetVersion(); - } - if (this->GetNumSlots() != rhs.GetNumSlots()) { - return this->GetNumSlots() < rhs.GetNumSlots(); - } - if (this->GetServiceIdBloomFilter() != rhs.GetServiceIdBloomFilter()) { - return this->GetServiceIdBloomFilter() < rhs.GetServiceIdBloomFilter(); - } - return this->GetAdvertisementHash() < rhs.GetAdvertisementHash(); -} - -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_advertisement_header.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_advertisement_header.h deleted file mode 100644 index fbf0d457599..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_advertisement_header.h +++ /dev/null @@ -1,97 +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_BLE_V2_BLE_ADVERTISEMENT_HEADER_H_ -#define CORE_INTERNAL_MEDIUMS_BLE_V2_BLE_ADVERTISEMENT_HEADER_H_ - -#include <string> - -#include "platform/base/byte_array.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -// Represents the format of the Mediums BLE Advertisement Header used in -// Advertising + Discovery. -// -// [VERSION][NUM_SLOTS][SERVICE_ID_BLOOM_FILTER][ADVERTISEMENT_HASH] -// -// See go/nearby-ble-design for more information. -// -// Note. The object constructed by default constructor or the parameterized -// constructor with invalid value(s) is treated as invalid instance. Caller -// should be responsible to call IsValid() to check the instance is invalid in -// advance before continue on. -class BleAdvertisementHeader { - public: - // Versions of the BleAdvertisementHeader. - enum class Version { - kUndefined = 0, - kV1 = 1, - kV2 = 2, - // Version is only allocated 3 bits in the BleAdvertisementHeader, so this - // can never go beyond V7. - // - // V1 is not present because it's an old format used in Nearby Connections - // before this logic was pushed down into Nearby Mediums. V1 put - // everything in the service data, while V2 puts the data inside a GATT - // characteristic so the two are not compatible. - }; - - BleAdvertisementHeader() = default; - BleAdvertisementHeader(Version version, int num_slots, - const ByteArray &service_id_bloom_filter, - const ByteArray &advertisement_hash); - explicit BleAdvertisementHeader( - const std::string &ble_advertisement_header_string); - BleAdvertisementHeader(const BleAdvertisementHeader &) = default; - BleAdvertisementHeader &operator=(const BleAdvertisementHeader &) = default; - BleAdvertisementHeader(BleAdvertisementHeader &&) = default; - BleAdvertisementHeader &operator=(BleAdvertisementHeader &&) = default; - ~BleAdvertisementHeader() = default; - - // Produces an encoded binary string which can be decoded by the explicit - // constructor. The returned string is empty if BleAdvertisementHeader is not - // valid - false on IsValid(). - explicit operator std::string() const; - bool operator<(const BleAdvertisementHeader &rhs) const; - - bool IsValid() const { return version_ == Version::kV2; } - Version GetVersion() const { return version_; } - int GetNumSlots() const { return num_slots_; } - ByteArray GetServiceIdBloomFilter() const { return service_id_bloom_filter_; } - ByteArray GetAdvertisementHash() const { return advertisement_hash_; } - - private: - static constexpr int kServiceIdBloomFilterLength = 10; - static constexpr int kAdvertisementHashLength = 4; - static constexpr int kMinAdvertisementHeaderLength = - 1 + kServiceIdBloomFilterLength + kAdvertisementHashLength; - static constexpr int kVersionBitmask = 0x0E0; - static constexpr int kNumSlotsBitmask = 0x01F; - - Version version_ = Version::kUndefined; - int num_slots_; - ByteArray service_id_bloom_filter_; - ByteArray advertisement_hash_; -}; - -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_BLE_V2_BLE_ADVERTISEMENT_HEADER_H_ diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_advertisement_header_test.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_advertisement_header_test.cc deleted file mode 100644 index bfd9bb991aa..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_advertisement_header_test.cc +++ /dev/null @@ -1,202 +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/ble_v2/ble_advertisement_header.h" - -#include "gtest/gtest.h" -#include "platform/base/base64_utils.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { -namespace { - -constexpr BleAdvertisementHeader::Version kVersion = - BleAdvertisementHeader::Version::kV2; -constexpr int kNumSlots = 2; -constexpr absl::string_view kServiceIDBloomFilter{ - "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"}; -constexpr absl::string_view kAdvertisementHash{"\x0a\x0b\x0c\x0d"}; - -TEST(BleAdvertisementHeaderTest, ConstructionWorks) { - ByteArray service_id_bloom_filter{std::string(kServiceIDBloomFilter)}; - ByteArray advertisement_hash{std::string(kAdvertisementHash)}; - - BleAdvertisementHeader ble_advertisement_header{ - kVersion, kNumSlots, service_id_bloom_filter, advertisement_hash}; - - EXPECT_TRUE(ble_advertisement_header.IsValid()); - EXPECT_EQ(kVersion, ble_advertisement_header.GetVersion()); - EXPECT_EQ(kNumSlots, ble_advertisement_header.GetNumSlots()); - EXPECT_EQ(service_id_bloom_filter, - ble_advertisement_header.GetServiceIdBloomFilter()); - EXPECT_EQ(advertisement_hash, - ble_advertisement_header.GetAdvertisementHash()); -} - -TEST(BleAdvertisementHeaderTest, ConstructionFailsWithBadVersion) { - auto bad_version = static_cast<BleAdvertisementHeader::Version>(666); - - ByteArray service_id_bloom_filter{std::string(kServiceIDBloomFilter)}; - ByteArray advertisement_hash{std::string(kAdvertisementHash)}; - - BleAdvertisementHeader ble_advertisement_header{ - bad_version, kNumSlots, service_id_bloom_filter, advertisement_hash}; - - EXPECT_FALSE(ble_advertisement_header.IsValid()); -} - -TEST(BleAdvertisementHeaderTest, ConstructionFailsWitZeroNumSlot) { - int num_slot = 0; - - ByteArray service_id_bloom_filter{std::string(kServiceIDBloomFilter)}; - ByteArray advertisement_hash{std::string(kAdvertisementHash)}; - - BleAdvertisementHeader ble_advertisement_header{ - kVersion, num_slot, service_id_bloom_filter, advertisement_hash}; - - EXPECT_FALSE(ble_advertisement_header.IsValid()); -} - -TEST(BleAdvertisementHeaderTest, - ConstructionFailsWithShortServiceIdBloomFilter) { - char short_service_id_bloom_filter[] = "\x01\x02\x03\x04\x05\x06\x07\x08\x09"; - - ByteArray short_service_id_bloom_filter_bytes{short_service_id_bloom_filter}; - ByteArray advertisement_hash{std::string(kAdvertisementHash)}; - - BleAdvertisementHeader ble_advertisement_header{ - kVersion, kNumSlots, short_service_id_bloom_filter_bytes, - advertisement_hash}; - - EXPECT_FALSE(ble_advertisement_header.IsValid()); -} - -TEST(BleAdvertisementHeaderTest, - ConstructionFailsWithLongServiceIdBloomFilter) { - char long_service_id_bloom_filter[] = - "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b"; - - ByteArray service_id_bloom_filter{long_service_id_bloom_filter}; - ByteArray advertisement_hash{std::string(kAdvertisementHash)}; - - BleAdvertisementHeader ble_advertisement_header{ - kVersion, kNumSlots, service_id_bloom_filter, advertisement_hash}; - - EXPECT_FALSE(ble_advertisement_header.IsValid()); -} - -TEST(BleAdvertisementHeaderTest, ConstructionFailsWithShortAdvertisementHash) { - char short_advertisement_hash[] = "\x0a\x0b\x0c"; - - ByteArray service_id_bloom_filter{std::string(kServiceIDBloomFilter)}; - ByteArray advertisement_hash{short_advertisement_hash}; - - BleAdvertisementHeader ble_advertisement_header{ - kVersion, kNumSlots, service_id_bloom_filter, advertisement_hash}; - - EXPECT_FALSE(ble_advertisement_header.IsValid()); -} - -TEST(BleAdvertisementHeaderTest, ConstructionFailsWithLongAdvertisementHash) { - char long_advertisement_hash[] = "\x0a\x0b\x0c\x0d\x0e"; - - ByteArray service_id_bloom_filter{std::string(kServiceIDBloomFilter)}; - ByteArray advertisement_hash{long_advertisement_hash}; - BleAdvertisementHeader ble_advertisement_header{ - kVersion, kNumSlots, service_id_bloom_filter, advertisement_hash}; - - EXPECT_FALSE(ble_advertisement_header.IsValid()); -} - -TEST(BleAdvertisementHeaderTest, ConstructionFromSerializedStringWorks) { - ByteArray service_id_bloom_filter{std::string(kServiceIDBloomFilter)}; - ByteArray advertisement_hash{std::string(kAdvertisementHash)}; - - BleAdvertisementHeader org_ble_advertisement_header{ - kVersion, kNumSlots, service_id_bloom_filter, advertisement_hash}; - auto ble_advertisement_header_string = - std::string(org_ble_advertisement_header); - - BleAdvertisementHeader ble_advertisement_header{ - ble_advertisement_header_string}; - - EXPECT_TRUE(ble_advertisement_header.IsValid()); - EXPECT_EQ(kVersion, ble_advertisement_header.GetVersion()); - EXPECT_EQ(kNumSlots, ble_advertisement_header.GetNumSlots()); - EXPECT_EQ(service_id_bloom_filter, - ble_advertisement_header.GetServiceIdBloomFilter()); - EXPECT_EQ(advertisement_hash, - ble_advertisement_header.GetAdvertisementHash()); -} - -TEST(BleAdvertisementHeaderTest, ConstructionFromExtraBytesWorks) { - ByteArray service_id_bloom_filter{std::string(kServiceIDBloomFilter)}; - ByteArray advertisement_hash{std::string(kAdvertisementHash)}; - - BleAdvertisementHeader ble_advertisement_header{ - kVersion, kNumSlots, service_id_bloom_filter, advertisement_hash}; - auto ble_advertisement_header_string = std::string(ble_advertisement_header); - - // Base64 decode the string, add a character, and then re-encode it. - ByteArray ble_advertisement_header_bytes = - Base64Utils::Decode(ble_advertisement_header_string); - ByteArray long_ble_advertisement_header_bytes{ - ble_advertisement_header_bytes.size() + 1}; - long_ble_advertisement_header_bytes.CopyAt(0, ble_advertisement_header_bytes); - std::string long_ble_advertisement_header_string{ - Base64Utils::Encode(long_ble_advertisement_header_bytes)}; - - BleAdvertisementHeader long_ble_advertisement_header{ - long_ble_advertisement_header_string}; - - EXPECT_TRUE(long_ble_advertisement_header.IsValid()); - EXPECT_EQ(kVersion, long_ble_advertisement_header.GetVersion()); - EXPECT_EQ(kNumSlots, long_ble_advertisement_header.GetNumSlots()); - EXPECT_EQ(service_id_bloom_filter, - long_ble_advertisement_header.GetServiceIdBloomFilter()); - EXPECT_EQ(advertisement_hash, - long_ble_advertisement_header.GetAdvertisementHash()); -} - -TEST(BleAdvertisementHeaderTest, ConstructionFromShortLengthFails) { - ByteArray service_id_bloom_filter{std::string(kServiceIDBloomFilter)}; - ByteArray advertisement_hash{std::string(kAdvertisementHash)}; - - BleAdvertisementHeader ble_advertisement_header{ - kVersion, kNumSlots, service_id_bloom_filter, advertisement_hash}; - auto ble_advertisement_header_string = std::string(ble_advertisement_header); - - // Base64 decode the string, remove a character, and then re-encode it. - ByteArray ble_advertisement_header_bytes = - Base64Utils::Decode(ble_advertisement_header_string); - ByteArray short_ble_advertisement_header_bytes{ - ble_advertisement_header_bytes.size() - 1}; - short_ble_advertisement_header_bytes.CopyAt(0, - ble_advertisement_header_bytes); - std::string short_ble_advertisement_header_string{ - Base64Utils::Encode(short_ble_advertisement_header_bytes)}; - - BleAdvertisementHeader short_ble_advertisement_header{ - short_ble_advertisement_header_string}; - - EXPECT_FALSE(short_ble_advertisement_header.IsValid()); -} - -} // namespace -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_advertisement_test.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_advertisement_test.cc deleted file mode 100644 index b91e8d95ca5..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_advertisement_test.cc +++ /dev/null @@ -1,455 +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/ble_v2/ble_advertisement.h" - -#include <algorithm> - -#include "gtest/gtest.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { -namespace { - -constexpr BleAdvertisement::Version kVersion = BleAdvertisement::Version::kV2; -constexpr BleAdvertisement::SocketVersion kSocketVersion = - BleAdvertisement::SocketVersion::kV2; -constexpr absl::string_view kServiceIDHashBytes{"\x0a\x0b\x0c"}; -constexpr absl::string_view kData{ - "How much wood can a woodchuck chuck if a wood chuck would chuck wood?"}; -constexpr absl::string_view kFastData{"Fast Advertise"}; -constexpr absl::string_view kDeviceToken{"\x04\x20"}; -// kAdvertisementLength/kFastAdvertisementLength corresponds to the length of a -// specific BleAdvertisement packed with the kData/kFastData given above. Be -// sure to update this if kData/kFastData ever changes. -constexpr size_t kAdvertisementLength = 77; -constexpr size_t kFastAdvertisementLength = 16; -constexpr size_t kLongAdvertisementLength = kAdvertisementLength + 1000; - -TEST(BleAdvertisementTest, ConstructionWorksV1) { - ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; - ByteArray data{std::string(kData)}; - ByteArray device_token{std::string(kDeviceToken)}; - - BleAdvertisement ble_advertisement{BleAdvertisement::Version::kV1, - BleAdvertisement::SocketVersion::kV1, - service_id_hash, data, device_token}; - - EXPECT_TRUE(ble_advertisement.IsValid()); - EXPECT_FALSE(ble_advertisement.IsFastAdvertisement()); - EXPECT_EQ(BleAdvertisement::Version::kV1, ble_advertisement.GetVersion()); - EXPECT_EQ(BleAdvertisement::SocketVersion::kV1, - ble_advertisement.GetSocketVersion()); - EXPECT_EQ(service_id_hash, ble_advertisement.GetServiceIdHash()); - EXPECT_EQ(data.size(), ble_advertisement.GetData().size()); - EXPECT_EQ(data, ble_advertisement.GetData()); - EXPECT_EQ(device_token, ble_advertisement.GetDeviceToken()); -} - -TEST(BleAdvertisementTest, ConstructionWorksV1ForFastAdvertisement) { - ByteArray fast_data{std::string(kFastData)}; - ByteArray device_token{std::string(kDeviceToken)}; - - BleAdvertisement ble_advertisement{BleAdvertisement::Version::kV1, - BleAdvertisement::SocketVersion::kV1, - ByteArray{}, fast_data, device_token}; - - EXPECT_TRUE(ble_advertisement.IsValid()); - EXPECT_TRUE(ble_advertisement.IsFastAdvertisement()); - EXPECT_EQ(BleAdvertisement::Version::kV1, ble_advertisement.GetVersion()); - EXPECT_EQ(BleAdvertisement::SocketVersion::kV1, - ble_advertisement.GetSocketVersion()); - EXPECT_EQ(fast_data.size(), ble_advertisement.GetData().size()); - EXPECT_EQ(fast_data, ble_advertisement.GetData()); - EXPECT_EQ(device_token, ble_advertisement.GetDeviceToken()); -} - -TEST(BleAdvertisementTest, ConstructionFailsWithBadVersion) { - BleAdvertisement::Version bad_version = - static_cast<BleAdvertisement::Version>(666); - - ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; - ByteArray data{std::string(kData)}; - ByteArray device_token{std::string(kDeviceToken)}; - - BleAdvertisement ble_advertisement{bad_version, kSocketVersion, - service_id_hash, data, device_token}; - EXPECT_FALSE(ble_advertisement.IsValid()); - - BleAdvertisement fast_ble_advertisement{bad_version, kSocketVersion, - ByteArray{}, data, device_token}; - EXPECT_FALSE(fast_ble_advertisement.IsValid()); -} - -TEST(BleAdvertisementTest, ConstructionFailsWithBadSocketVersion) { - BleAdvertisement::SocketVersion bad_socket_version = - static_cast<BleAdvertisement::SocketVersion>(666); - - ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; - ByteArray data{std::string(kData)}; - ByteArray device_token{std::string(kDeviceToken)}; - - BleAdvertisement ble_advertisement{kVersion, bad_socket_version, - service_id_hash, data, device_token}; - EXPECT_FALSE(ble_advertisement.IsValid()); - - BleAdvertisement fast_ble_advertisement{kVersion, bad_socket_version, - ByteArray{}, data, device_token}; - EXPECT_FALSE(fast_ble_advertisement.IsValid()); -} - -TEST(BleAdvertisementTest, ConstructionFailsWithShortServiceIdHash) { - char short_service_id_hash_bytes[] = "\x0a\x0b"; - - ByteArray bad_service_id_hash{short_service_id_hash_bytes}; - ByteArray data{std::string(kData)}; - ByteArray device_token{std::string(kDeviceToken)}; - - BleAdvertisement ble_advertisement{kVersion, kSocketVersion, - bad_service_id_hash, data, device_token}; - - EXPECT_FALSE(ble_advertisement.IsValid()); -} - -TEST(BleAdvertisementTest, ConstructionFailsWithLongServiceIdHash) { - char long_service_id_hash_bytes[] = "\x0a\x0b\x0c\x0d"; - - ByteArray bad_service_id_hash{long_service_id_hash_bytes}; - ByteArray data{std::string(kData)}; - ByteArray device_token{std::string(kDeviceToken)}; - - BleAdvertisement ble_advertisement{kVersion, kSocketVersion, - bad_service_id_hash, data, device_token}; - - EXPECT_FALSE(ble_advertisement.IsValid()); -} - -TEST(BleAdvertisementTest, ConstructionFailsWithLongData) { - // BleAdvertisement shouldn't be able to support data with the max GATT - // attribute length because it needs some room for the preceding fields. - char long_data[512]{}; - - ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; - ByteArray bad_data{long_data, 512}; - ByteArray device_token{std::string(kDeviceToken)}; - - BleAdvertisement ble_advertisement{kVersion, kSocketVersion, service_id_hash, - bad_data, device_token}; - EXPECT_FALSE(ble_advertisement.IsValid()); - - BleAdvertisement fast_ble_advertisement{kVersion, kSocketVersion, ByteArray{}, - bad_data, device_token}; - EXPECT_FALSE(fast_ble_advertisement.IsValid()); -} - -TEST(BleAdvertisementTest, ConstructionWorksWithEmptyDeviceToken) { - ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; - ByteArray data{std::string(kData)}; - - BleAdvertisement ble_advertisement{kVersion, kSocketVersion, service_id_hash, - data, ByteArray{}}; - - EXPECT_TRUE(ble_advertisement.IsValid()); - EXPECT_FALSE(ble_advertisement.IsFastAdvertisement()); - EXPECT_EQ(kVersion, ble_advertisement.GetVersion()); - EXPECT_EQ(kSocketVersion, ble_advertisement.GetSocketVersion()); - EXPECT_EQ(service_id_hash, ble_advertisement.GetServiceIdHash()); - EXPECT_EQ(data.size(), ble_advertisement.GetData().size()); - EXPECT_EQ(data, ble_advertisement.GetData()); - EXPECT_TRUE(ble_advertisement.GetDeviceToken().Empty()); -} - -TEST(BleAdvertisementTest, - ConstructionWorksWithEmptyDeviceTokenForFastAdvertisement) { - ByteArray fast_data{std::string(kFastData)}; - - BleAdvertisement ble_advertisement{kVersion, kSocketVersion, ByteArray{}, - fast_data, ByteArray{}}; - - EXPECT_TRUE(ble_advertisement.IsValid()); - EXPECT_TRUE(ble_advertisement.IsFastAdvertisement()); - EXPECT_EQ(kVersion, ble_advertisement.GetVersion()); - EXPECT_EQ(kSocketVersion, ble_advertisement.GetSocketVersion()); - EXPECT_EQ(fast_data.size(), ble_advertisement.GetData().size()); - EXPECT_EQ(fast_data, ble_advertisement.GetData()); - EXPECT_TRUE(ble_advertisement.GetDeviceToken().Empty()); -} - -TEST(BleAdvertisementTest, ConstructionFailsWithWrongSizeofDeviceToken) { - char wrong_device_token_bytes_1[] = "\x04\x2\x10"; // over 2 bytes - char wrong_device_token_bytes_2[] = "\x04"; // 1 byte - - ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; - ByteArray data{std::string(kData)}; - ByteArray bad_device_token_1{wrong_device_token_bytes_1}; - ByteArray bad_device_token_2{wrong_device_token_bytes_2}; - - BleAdvertisement ble_advertisement_1{ - kVersion, kSocketVersion, service_id_hash, data, bad_device_token_1}; - EXPECT_FALSE(ble_advertisement_1.IsValid()); - - BleAdvertisement ble_advertisement_2{ - kVersion, kSocketVersion, service_id_hash, data, bad_device_token_2}; - EXPECT_FALSE(ble_advertisement_2.IsValid()); - - BleAdvertisement fast_ble_advertisement_1{ - kVersion, kSocketVersion, ByteArray{}, data, bad_device_token_1}; - EXPECT_FALSE(fast_ble_advertisement_1.IsValid()); - - BleAdvertisement fast_ble_advertisement_2{ - kVersion, kSocketVersion, ByteArray{}, data, bad_device_token_2}; - EXPECT_FALSE(fast_ble_advertisement_2.IsValid()); -} - -TEST(BleAdvertisementTest, ConstructionFromSerializedBytesWorks) { - ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; - ByteArray data{std::string(kData)}; - ByteArray device_token{std::string(kDeviceToken)}; - - BleAdvertisement org_ble_advertisement{kVersion, kSocketVersion, - service_id_hash, data, device_token}; - - ByteArray ble_advertisement_bytes{org_ble_advertisement}; - BleAdvertisement ble_advertisement{ble_advertisement_bytes}; - - EXPECT_TRUE(ble_advertisement.IsValid()); - EXPECT_FALSE(ble_advertisement.IsFastAdvertisement()); - EXPECT_EQ(kVersion, ble_advertisement.GetVersion()); - EXPECT_EQ(kSocketVersion, ble_advertisement.GetSocketVersion()); - EXPECT_EQ(service_id_hash, ble_advertisement.GetServiceIdHash()); - EXPECT_EQ(data.size(), ble_advertisement.GetData().size()); - EXPECT_EQ(data, ble_advertisement.GetData()); - EXPECT_EQ(device_token, ble_advertisement.GetDeviceToken()); -} - -TEST(BleAdvertisementTest, - ConstructionFromSerializedBytesWorksForAdvertisement) { - ByteArray fast_data{std::string(kFastData)}; - ByteArray device_token{std::string(kDeviceToken)}; - - BleAdvertisement org_ble_advertisement{kVersion, kSocketVersion, ByteArray{}, - fast_data, device_token}; - - ByteArray ble_advertisement_bytes{org_ble_advertisement}; - BleAdvertisement ble_advertisement{ble_advertisement_bytes}; - - EXPECT_TRUE(ble_advertisement.IsValid()); - EXPECT_TRUE(ble_advertisement.IsFastAdvertisement()); - EXPECT_EQ(kVersion, ble_advertisement.GetVersion()); - EXPECT_EQ(kSocketVersion, ble_advertisement.GetSocketVersion()); - EXPECT_EQ(fast_data.size(), ble_advertisement.GetData().size()); - EXPECT_EQ(fast_data, ble_advertisement.GetData()); - EXPECT_EQ(device_token, ble_advertisement.GetDeviceToken()); -} - -TEST(BleAdvertisementTest, ConstructionFromSerializedBytesWithEmptyDataWorks) { - ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; - ByteArray device_token{std::string(kDeviceToken)}; - - BleAdvertisement org_ble_advertisement{ - kVersion, kSocketVersion, service_id_hash, ByteArray(), device_token}; - ByteArray ble_advertisement_bytes{org_ble_advertisement}; - BleAdvertisement ble_advertisement{ble_advertisement_bytes}; - - EXPECT_TRUE(ble_advertisement.IsValid()); - EXPECT_FALSE(ble_advertisement.IsFastAdvertisement()); - EXPECT_EQ(kVersion, ble_advertisement.GetVersion()); - EXPECT_EQ(kSocketVersion, ble_advertisement.GetSocketVersion()); - EXPECT_EQ(service_id_hash, ble_advertisement.GetServiceIdHash()); - EXPECT_TRUE(ble_advertisement.GetData().Empty()); - EXPECT_EQ(device_token, ble_advertisement.GetDeviceToken()); -} - -TEST(BleAdvertisementTest, - ConstructionFromSerializedBytesWithEmptyDataWorksForFastAdvertisement) { - ByteArray device_token{std::string(kDeviceToken)}; - - BleAdvertisement org_ble_advertisement{kVersion, kSocketVersion, ByteArray{}, - ByteArray(), device_token}; - ByteArray ble_advertisement_bytes{org_ble_advertisement}; - BleAdvertisement ble_advertisement{ble_advertisement_bytes}; - - EXPECT_TRUE(ble_advertisement.IsValid()); - EXPECT_TRUE(ble_advertisement.IsFastAdvertisement()); - EXPECT_EQ(kVersion, ble_advertisement.GetVersion()); - EXPECT_EQ(kSocketVersion, ble_advertisement.GetSocketVersion()); - EXPECT_TRUE(ble_advertisement.GetData().Empty()); - EXPECT_EQ(device_token, ble_advertisement.GetDeviceToken()); -} - -TEST(BleAdvertisementTest, ConstructionFromExtraSerializedBytesWorks) { - ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; - ByteArray data{std::string(kData)}; - ByteArray device_token{std::string(kDeviceToken)}; - - BleAdvertisement org_ble_advertisement{kVersion, kSocketVersion, - service_id_hash, data, device_token}; - ByteArray org_ble_advertisement_bytes{org_ble_advertisement}; - - // Copy the bytes into a new array with extra bytes. We must explicitly - // define how long our array is because we can't use variable length arrays. - char raw_ble_advertisement_bytes[kLongAdvertisementLength]{}; - memcpy(raw_ble_advertisement_bytes, org_ble_advertisement_bytes.data(), - std::min(sizeof(raw_ble_advertisement_bytes), - org_ble_advertisement_bytes.size())); - - // Re-parse the Ble advertisement using our extra long advertisement bytes. - ByteArray long_ble_advertisement_bytes{raw_ble_advertisement_bytes, - kLongAdvertisementLength}; - BleAdvertisement long_ble_advertisement{long_ble_advertisement_bytes}; - - EXPECT_TRUE(long_ble_advertisement.IsValid()); - EXPECT_FALSE(long_ble_advertisement.IsFastAdvertisement()); - EXPECT_EQ(kVersion, long_ble_advertisement.GetVersion()); - EXPECT_EQ(kSocketVersion, long_ble_advertisement.GetSocketVersion()); - EXPECT_EQ(service_id_hash, long_ble_advertisement.GetServiceIdHash()); - EXPECT_EQ(data.size(), long_ble_advertisement.GetData().size()); - EXPECT_EQ(data, long_ble_advertisement.GetData()); - EXPECT_EQ(device_token, long_ble_advertisement.GetDeviceToken()); -} - -TEST(BleAdvertisementTest, - ConstructionFromExtraSerializedBytesWorksForFastAdvertisement) { - ByteArray fast_data{std::string(kFastData)}; - ByteArray device_token{std::string(kDeviceToken)}; - - BleAdvertisement org_ble_advertisement{kVersion, kSocketVersion, ByteArray{}, - fast_data, device_token}; - ByteArray org_ble_advertisement_bytes{org_ble_advertisement}; - - // Copy the bytes into a new array with extra bytes. We must explicitly - // define how long our array is because we can't use variable length arrays. - char raw_ble_advertisement_bytes[kLongAdvertisementLength]{}; - memcpy(raw_ble_advertisement_bytes, org_ble_advertisement_bytes.data(), - std::min(sizeof(raw_ble_advertisement_bytes), - org_ble_advertisement_bytes.size())); - - // Re-parse the Ble advertisement using our extra long advertisement bytes. - ByteArray long_ble_advertisement_bytes{raw_ble_advertisement_bytes, - kLongAdvertisementLength}; - BleAdvertisement long_ble_advertisement{long_ble_advertisement_bytes}; - - EXPECT_TRUE(long_ble_advertisement.IsValid()); - EXPECT_TRUE(long_ble_advertisement.IsFastAdvertisement()); - EXPECT_EQ(kVersion, long_ble_advertisement.GetVersion()); - EXPECT_EQ(kSocketVersion, long_ble_advertisement.GetSocketVersion()); - EXPECT_EQ(fast_data.size(), long_ble_advertisement.GetData().size()); - EXPECT_EQ(fast_data, long_ble_advertisement.GetData()); - EXPECT_EQ(device_token, long_ble_advertisement.GetDeviceToken()); -} - -TEST(BleAdvertisementTest, ConstructionFromNullBytesFails) { - BleAdvertisement ble_advertisement{ByteArray{}}; - - EXPECT_FALSE(ble_advertisement.IsValid()); -} - -TEST(BleAdvertisementTest, ConstructionFromShortLengthSerializedBytesFails) { - ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; - ByteArray data{std::string(kData)}; - ByteArray device_token{std::string(kDeviceToken)}; - - BleAdvertisement org_ble_advertisement{kVersion, kSocketVersion, - service_id_hash, data, device_token}; - ByteArray org_ble_advertisement_bytes{org_ble_advertisement}; - - // Cut off the advertisement so that it's too short. - ByteArray short_ble_advertisement_bytes{org_ble_advertisement_bytes.data(), - 7}; - BleAdvertisement short_ble_advertisement{short_ble_advertisement_bytes}; - - EXPECT_FALSE(short_ble_advertisement.IsValid()); -} - -TEST(BleAdvertisementTest, - ConstructionFromShortLengthSerializedBytesFailsForFastAdvertisement) { - ByteArray fast_data{std::string(kFastData)}; - ByteArray device_token{std::string(kDeviceToken)}; - - BleAdvertisement org_ble_advertisement{kVersion, kSocketVersion, ByteArray{}, - fast_data, device_token}; - ByteArray org_ble_advertisement_bytes{org_ble_advertisement}; - - // Cut off the advertisement so that it's too short. - ByteArray short_ble_advertisement_bytes{org_ble_advertisement_bytes.data(), - 2}; - BleAdvertisement short_ble_advertisement{short_ble_advertisement_bytes}; - - EXPECT_FALSE(short_ble_advertisement.IsValid()); -} - -TEST(BleAdvertisementTest, - ConstructionFromSerializedBytesWithInvalidDataLengthFails) { - ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; - ByteArray data{std::string(kData)}; - ByteArray device_token{std::string(kDeviceToken)}; - - BleAdvertisement org_ble_advertisement{kVersion, kSocketVersion, - service_id_hash, data, device_token}; - ByteArray org_ble_advertisement_bytes{org_ble_advertisement}; - - // Corrupt the DATA_SIZE bits. Start by making a raw copy of the Ble - // advertisement bytes so we can modify it. We must explicitly define how - // long our array is because we can't use variable length arrays. - char raw_ble_advertisement_bytes[kAdvertisementLength]; - memcpy(raw_ble_advertisement_bytes, org_ble_advertisement_bytes.data(), - kAdvertisementLength); - - // The data size field lives in indices 4-7. Corrupt it. - memset(raw_ble_advertisement_bytes + 4, 0xFF, 4); - - // Try to parse the Ble advertisement using our corrupted advertisement bytes. - ByteArray corrupted_ble_advertisement_bytes{raw_ble_advertisement_bytes, - kAdvertisementLength}; - BleAdvertisement corrupted_ble_advertisement{ - corrupted_ble_advertisement_bytes}; - - EXPECT_FALSE(corrupted_ble_advertisement.IsValid()); -} - -TEST(BleAdvertisementTest, - ConstructionFromSerializedBytesWithInvalidDataLengthFails2) { - ByteArray fast_data{std::string(kFastData)}; - ByteArray device_token{std::string(kDeviceToken)}; - - BleAdvertisement org_ble_advertisement{kVersion, kSocketVersion, ByteArray{}, - fast_data, device_token}; - ByteArray org_ble_advertisement_bytes{org_ble_advertisement}; - - // Corrupt the DATA_SIZE bits. Start by making a raw copy of the Ble - // advertisement bytes so we can modify it. We must explicitly define how - // long our array is because we can't use variable length arrays. - char raw_ble_advertisement_bytes[kFastAdvertisementLength]; - memcpy(raw_ble_advertisement_bytes, org_ble_advertisement_bytes.data(), - kFastAdvertisementLength); - - // The data size field lives in index 1. Corrupt it. - memset(raw_ble_advertisement_bytes + 1, 0xFF, 1); - - // Try to parse the Ble advertisement using our corrupted advertisement bytes. - ByteArray corrupted_ble_advertisement_bytes{raw_ble_advertisement_bytes, - kFastAdvertisementLength}; - BleAdvertisement corrupted_ble_advertisement{ - corrupted_ble_advertisement_bytes}; - - EXPECT_FALSE(corrupted_ble_advertisement.IsValid()); -} - -} // namespace -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_packet.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_packet.cc deleted file mode 100644 index 17ab10e3472..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_packet.cc +++ /dev/null @@ -1,73 +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/ble_v2/ble_packet.h" - -#include "absl/strings/str_cat.h" -#include "platform/base/base_input_stream.h" -#include "platform/public/logging.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -BlePacket::BlePacket(const ByteArray& service_id_hash, const ByteArray& data) { - if (service_id_hash.size() != kServiceIdHashLength || - data.size() > kMaxDataSize) { - return; - } - service_id_hash_ = service_id_hash; - data_ = data; -} - -BlePacket::BlePacket(const ByteArray& ble_packet_bytes) { - if (ble_packet_bytes.Empty()) { - NEARBY_LOG(ERROR, "Cannot deserialize BlePacket: null bytes passed in"); - return; - } - - if (ble_packet_bytes.size() < kServiceIdHashLength) { - NEARBY_LOG( - INFO, - "Cannot deserialize BlePacket: expecting min %u raw bytes, got %zu", - kServiceIdHashLength, ble_packet_bytes.size()); - return; - } - - ByteArray packet_bytes{ble_packet_bytes}; - BaseInputStream base_input_stream{packet_bytes}; - // The first 3 bytes are supposed to be the service_id_hash. - service_id_hash_ = base_input_stream.ReadBytes(kServiceIdHashLength); - - // The rest bytes are supposed to be the data. - data_ = base_input_stream.ReadBytes(ble_packet_bytes.size() - - kServiceIdHashLength); -} - -BlePacket::operator ByteArray() const { - if (!IsValid()) { - return ByteArray(); - } - - std::string out = - absl::StrCat(std::string(service_id_hash_), std::string(data_)); - - return ByteArray(std::move(out)); -} - -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_packet.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_packet.h deleted file mode 100644 index b559d4adda3..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_packet.h +++ /dev/null @@ -1,64 +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_BLE_V2_BLE_PACKET_H_ -#define CORE_INTERNAL_MEDIUMS_BLE_V2_BLE_PACKET_H_ - -#include <limits> - -#include "platform/base/byte_array.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -// Represents the format of data sent over Ble sockets. -// -// [SERVICE_ID_HASH][DATA] -// -// See go/nearby-ble-design for more information. -class BlePacket { - public: - static const std::uint32_t kServiceIdHashLength = 3; - - BlePacket() = default; - BlePacket(const ByteArray& service_id_hash, const ByteArray& data); - explicit BlePacket(const ByteArray& ble_packet_byte); - BlePacket(const BlePacket&) = default; - BlePacket& operator=(const BlePacket&) = default; - BlePacket(BlePacket&&) = default; - BlePacket& operator=(BlePacket&&) = default; - ~BlePacket() = default; - - explicit operator ByteArray() const; - - bool IsValid() const { return !service_id_hash_.Empty(); } - ByteArray GetServiceIdHash() const { return service_id_hash_; } - ByteArray GetData() const { return data_; } - - private: - static const std::uint32_t kMaxDataSize = - std::numeric_limits<int32_t>::max() - kServiceIdHashLength; - - ByteArray service_id_hash_; - ByteArray data_; -}; - -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_BLE_V2_BLE_PACKET_H_ diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_packet_test.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_packet_test.cc deleted file mode 100644 index df52c3d6743..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_packet_test.cc +++ /dev/null @@ -1,111 +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/ble_v2/ble_packet.h" - -#include "gtest/gtest.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -constexpr absl::string_view kServiceIDHash{"\x0a\x0b\x0c"}; -constexpr absl::string_view kData{"\x01\x02\x03\x04\x05"}; - -TEST(BlePacketTest, ConstructionWorks) { - ByteArray service_id_hash{std::string(kServiceIDHash)}; - ByteArray data{std::string(kData)}; - - BlePacket ble_packet{service_id_hash, data}; - - EXPECT_TRUE(ble_packet.IsValid()); - EXPECT_EQ(service_id_hash, ble_packet.GetServiceIdHash()); - EXPECT_EQ(data, ble_packet.GetData()); -} - -TEST(BlePacketTest, ConstructionWorksWithEmptyData) { - char empty_data[] = ""; - - ByteArray service_id_hash{std::string(kServiceIDHash)}; - ByteArray data{empty_data}; - - BlePacket ble_packet{service_id_hash, data}; - - EXPECT_TRUE(ble_packet.IsValid()); - EXPECT_EQ(service_id_hash, ble_packet.GetServiceIdHash()); - EXPECT_EQ(data, ble_packet.GetData()); -} - -TEST(BlePacketTest, ConstructionFailsWithShortServiceIdHash) { - char short_service_id_hash[] = "\x0a\x0b"; - - ByteArray service_id_hash{short_service_id_hash}; - ByteArray data{std::string(kData)}; - - BlePacket ble_packet(service_id_hash, data); - - EXPECT_FALSE(ble_packet.IsValid()); -} - -TEST(BlePacketTest, ConstructionFailsWithLongServiceIdHash) { - char long_service_id_hash[] = "\x0a\x0b\x0c\x0d"; - - ByteArray service_id_hash{long_service_id_hash}; - ByteArray data{std::string(kData)}; - - BlePacket ble_packet{service_id_hash, data}; - - EXPECT_FALSE(ble_packet.IsValid()); -} - -TEST(BlePacketTest, ConstructionFromSerializedBytesWorks) { - ByteArray service_id_hash{std::string(kServiceIDHash)}; - ByteArray data{std::string(kData)}; - - BlePacket org_ble_packet{service_id_hash, data}; - ByteArray ble_packet_bytes{org_ble_packet}; - - BlePacket ble_packet{ble_packet_bytes}; - - EXPECT_TRUE(ble_packet.IsValid()); - EXPECT_EQ(service_id_hash, ble_packet.GetServiceIdHash()); - EXPECT_EQ(data, ble_packet.GetData()); -} - -TEST(BlePacketTest, ConstructionFromNullBytesFails) { - BlePacket ble_packet{ByteArray{}}; - - EXPECT_FALSE(ble_packet.IsValid()); -} - -TEST(BlePacketTest, ConstructionFromShortLengthDataFails) { - ByteArray service_id_hash{std::string(kServiceIDHash)}; - ByteArray data{std::string(kData)}; - - BlePacket org_ble_packet{service_id_hash, data}; - ByteArray org_ble_packet_bytes{org_ble_packet}; - - // Cut off the packet so that it's too short - ByteArray short_ble_packet_bytes{ByteArray{org_ble_packet_bytes.data(), 2}}; - - BlePacket short_ble_packet{short_ble_packet_bytes}; - - EXPECT_FALSE(short_ble_packet.IsValid()); -} - -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_peripheral.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_peripheral.h deleted file mode 100644 index e3b51a41466..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_peripheral.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_BLE_V2_BLE_PERIPHERAL_H_ -#define CORE_INTERNAL_MEDIUMS_BLE_V2_BLE_PERIPHERAL_H_ - -#include "platform/base/byte_array.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -class BlePeripheral { - public: - BlePeripheral() = default; - explicit BlePeripheral(const ByteArray& id) : id_(id) {} - BlePeripheral(const BlePeripheral&) = default; - BlePeripheral& operator=(const BlePeripheral&) = default; - BlePeripheral(BlePeripheral&&) = default; - BlePeripheral& operator=(BlePeripheral&&) = default; - ~BlePeripheral() = default; - - bool IsValid() const { return !id_.Empty(); } - ByteArray GetId() const { return id_; } - - private: - // A unique identifier for this peripheral. It can be the BLE advertisement it - // was found on, or even simply the BLE MAC address. - ByteArray id_; -}; - -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_BLE_V2_BLE_PERIPHERAL_H_ diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_peripheral_test.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_peripheral_test.cc deleted file mode 100644 index c0a4ecb0899..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/ble_peripheral_test.cc +++ /dev/null @@ -1,47 +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/ble_v2/ble_peripheral.h" - -#include "gtest/gtest.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { -namespace { - -constexpr absl::string_view kId{"AB12"}; - -TEST(BlePeripheralTest, ConstructionWorks) { - ByteArray id{std::string(kId)}; - - BlePeripheral ble_peripheral{id}; - - EXPECT_TRUE(ble_peripheral.IsValid()); - EXPECT_EQ(id, ble_peripheral.GetId()); -} - -TEST(BlePeripheralTest, ConstructionEmptyFails) { - BlePeripheral ble_peripheral; - - EXPECT_FALSE(ble_peripheral.IsValid()); - EXPECT_TRUE(ble_peripheral.GetId().Empty()); -} - -} // namespace -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/discovered_peripheral_callback.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/discovered_peripheral_callback.h deleted file mode 100644 index 8aacfed4d2e..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/ble_v2/discovered_peripheral_callback.h +++ /dev/null @@ -1,45 +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_BLE_V2_DISCOVERED_PERIPHERAL_CALLBACK_H_ -#define CORE_INTERNAL_MEDIUMS_BLE_V2_DISCOVERED_PERIPHERAL_CALLBACK_H_ - -#include "core/internal/mediums/ble_v2/ble_peripheral.h" -#include "core/listeners.h" -#include "platform/base/byte_array.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -/** Callback that is invoked when a {@link BlePeripheral} is discovered. */ -struct DiscoveredPeripheralCallback { - std::function<void(BlePeripheral& peripheral, const std::string& service_id, - const ByteArray& advertisement_byts, - bool fast_advertisement)> - peripheral_discovered_cb = - DefaultCallback<BlePeripheral&, const std::string&, const ByteArray&, - bool>(); - std::function<void(BlePeripheral& peripheral, const std::string& service_id)> - peripheral_lost_cb = - DefaultCallback<BlePeripheral&, const std::string&>(); -}; - -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_BLE_V2_DISCOVERED_PERIPHERAL_CALLBACK_H_ diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/bloom_filter.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/bloom_filter.cc deleted file mode 100644 index 20a2370bf0a..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/bloom_filter.cc +++ /dev/null @@ -1,105 +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/bloom_filter.h" - -#include "absl/numeric/int128.h" -#include "absl/strings/numbers.h" -#include "smhasher/src/MurmurHash3.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -BloomFilterBase::BloomFilterBase(const ByteArray& bytes, BitSet* bit_set) - : bits_(bit_set) { - const char* bytes_read_ptr = bytes.data(); - for (size_t byte_index = 0; byte_index < bytes.size(); byte_index++) { - for (size_t bit_index = 0; bit_index < 8; bit_index++) { - bits_->Set((byte_index * 8) + bit_index, - (*bytes_read_ptr >> bit_index) & 0x01); - } - bytes_read_ptr++; - } -} - -BloomFilterBase::operator ByteArray() const { - // Gets a binary string representation of the bitset where the leftmost - // character corresponds to bitset position (total size) - 1. - // - // If the bitset's internal representation is: - // [position 0] 0 0 1 1 0 0 0 1 0 1 0 1 [position 11] - // The string representation will be outputted like this: - // "1 0 1 0 1 0 0 0 1 1 0 0" - std::string bitset_binary_string = bits_->ToString(); - - ByteArray result_bytes(GetMinBytesForBits()); - char* result_bytes_write_ptr = result_bytes.data(); - // We go through the string backwards because the rightmost character - // corresponds to position 0 in the bitset. - for (size_t i = bits_->Size(); i > 0; i -= 8) { - std::string byte_binary_string = bitset_binary_string.substr(i - 8, 8); - std::uint32_t byte_value; - absl::numbers_internal::safe_strtou32_base(byte_binary_string, &byte_value, - /* base= */ 2); - *result_bytes_write_ptr = static_cast<char>(byte_value & 0x000000FF); - result_bytes_write_ptr++; - } - return result_bytes; -} - -void BloomFilterBase::Add(const std::string& s) { - std::vector<std::int32_t> hashes = GetHashes(s); - for (int32_t hash : hashes) { - size_t position = static_cast<size_t>(hash) % bits_->Size(); - bits_->Set(position, true); - } -} - -bool BloomFilterBase::PossiblyContains(const std::string& s) { - std::vector<std::int32_t> hashes = GetHashes(s); - for (int32_t hash : hashes) { - size_t position = static_cast<size_t>(hash) % bits_->Size(); - if (!bits_->Test(position)) { - return false; - } - } - return true; -} - -std::vector<std::int32_t> BloomFilterBase::GetHashes(const std::string& s) { - std::vector<std::int32_t> hashes(kHasherNumberOfRepetitions, 0); - - absl::uint128 hash128; - MurmurHash3_x64_128(s.data(), s.size(), 0, &hash128); - std::uint64_t hash64 = - absl::Uint128Low64(hash128); // the lower 64 bits of the 128-bit hash - std::int32_t hash1 = static_cast<std::int32_t>( - hash64 & 0x00000000FFFFFFFF); // the lower 32 bits of the 64-bit hash - std::int32_t hash2 = static_cast<std::int32_t>( - (hash64 >> 32) & 0x0FFFFFFFF); // the upper 32 bits of the 64-bit hash - for (size_t i = 1; i <= kHasherNumberOfRepetitions; i++) { - std::int32_t combinedHash = static_cast<std::int32_t>(hash1 + (i * hash2)); - // Flip all the bits if it's negative (guaranteed positive number) - if (combinedHash < 0) combinedHash = ~combinedHash; - hashes[i - 1] = combinedHash; - } - return hashes; -} - -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/bloom_filter.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/bloom_filter.h deleted file mode 100644 index 3d3f45c9d36..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/bloom_filter.h +++ /dev/null @@ -1,101 +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_BLOOM_FILTER_H_ -#define CORE_INTERNAL_MEDIUMS_BLOOM_FILTER_H_ - -#include <bitset> -#include <vector> - -#include "platform/base/byte_array.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -/** - * A bloom filter that gives access to the underlying BitSet. The implementation - * is copied from our Java version of Bloom filter, which in turn copies from - * Guava's BloomFilter. - * - * BloomFilter is templatized on the size of the byte array and not the size of - * the bit set to ensure the bit set's length is a multiple of 8 (and can - * neatly be returned as a ByteArray). - */ -class BloomFilterBase { - public: - explicit operator ByteArray() const; - - void Add(const std::string& s); - bool PossiblyContains(const std::string& s); - - protected: - class BitSet { - public: - virtual ~BitSet() = default; - virtual std::string ToString() const = 0; - virtual void Set(size_t pos, bool value) = 0; - virtual bool Test(size_t pos) const = 0; - virtual size_t Size() const = 0; - }; - - BloomFilterBase(const ByteArray& bytes, BitSet* bit_set); - virtual ~BloomFilterBase() = default; - - constexpr static int kHasherNumberOfRepetitions = 5; - std::vector<std::int32_t> GetHashes(const std::string& s); - - private: - int GetMinBytesForBits() const { return (bits_->Size() + 7) >> 3; } - - BitSet* bits_; -}; - -template <size_t CapacityInBytes> -class BloomFilter final : public BloomFilterBase { - public: - BloomFilter() : BloomFilterBase(ByteArray{}, &bits_) {} - explicit BloomFilter(const ByteArray& bytes) - : BloomFilterBase(bytes, &bits_) {} - BloomFilter(const BloomFilter&) = default; - BloomFilter& operator=(const BloomFilter&) = default; - BloomFilter(BloomFilter&& other) : BloomFilterBase(ByteArray{}, &bits_) { - *this = std::move(other); - } - BloomFilter& operator=(BloomFilter&& other) { - std::swap((*this).bits_, other.bits_); - return *this; - } - ~BloomFilter() override = default; - - private: - class BitSetImpl final : public BitSet { - public: - std::string ToString() const override { return bits_.to_string(); } - void Set(size_t pos, bool value) override { bits_.set(pos, value); } - bool Test(size_t pos) const override { return bits_.test(pos); } - size_t Size() const override { return bits_.size(); } - - private: - std::bitset<CapacityInBytes * 8> bits_; - } bits_; -}; - -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_BLOOM_FILTER_H_ diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/bloom_filter_test.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/bloom_filter_test.cc deleted file mode 100644 index 70e846a69dc..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/bloom_filter_test.cc +++ /dev/null @@ -1,207 +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/bloom_filter.h" - -#include <algorithm> - -#include "gtest/gtest.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { -namespace { - -constexpr size_t kByteArrayLength = 100; - -TEST(BloomFilterTest, EmptyFilterReturnsEmptyArray) { - BloomFilter<kByteArrayLength> bloom_filter; - - ByteArray bloom_filter_bytes(bloom_filter); - std::string empty_string(kByteArrayLength, '\0'); - - EXPECT_EQ(empty_string, std::string(bloom_filter_bytes)); -} - -TEST(BloomFilterTest, EmptyFilterNeverContains) { - BloomFilter<kByteArrayLength> bloom_filter; - - EXPECT_FALSE(bloom_filter.PossiblyContains("ELEMENT_1")); - EXPECT_FALSE(bloom_filter.PossiblyContains("ELEMENT_2")); - EXPECT_FALSE(bloom_filter.PossiblyContains("ELEMENT_3")); -} - -TEST(BloomFilterTest, AddSuccess) { - BloomFilter<kByteArrayLength> bloom_filter; - - EXPECT_FALSE(bloom_filter.PossiblyContains("ELEMENT_1")); - - bloom_filter.Add("ELEMENT_1"); - - EXPECT_TRUE(bloom_filter.PossiblyContains("ELEMENT_1")); -} - -TEST(BloomFilterTest, AddOnlyGivenArg) { - BloomFilter<kByteArrayLength> bloom_filter; - - bloom_filter.Add("ELEMENT_1"); - - EXPECT_TRUE(bloom_filter.PossiblyContains("ELEMENT_1")); - EXPECT_FALSE(bloom_filter.PossiblyContains("ELEMENT_2")); - EXPECT_FALSE(bloom_filter.PossiblyContains("ELEMENT_3")); -} - -TEST(BloomFilterTest, AddMultipleArgs) { - BloomFilter<kByteArrayLength> bloom_filter; - - bloom_filter.Add("ELEMENT_1"); - bloom_filter.Add("ELEMENT_2"); - - EXPECT_TRUE(bloom_filter.PossiblyContains("ELEMENT_1")); - EXPECT_TRUE(bloom_filter.PossiblyContains("ELEMENT_2")); - EXPECT_FALSE(bloom_filter.PossiblyContains("ELEMENT_3")); -} - -TEST(BloomFilterTest, AddMultipleArgsReturnsNonemptyArray) { - BloomFilter<10> bloom_filter; - - bloom_filter.Add("ELEMENT_1"); - bloom_filter.Add("ELEMENT_2"); - bloom_filter.Add("ELEMENT_3"); - - ByteArray bloom_filter_bytes(bloom_filter); - std::string empty_string(kByteArrayLength, '\0'); - - EXPECT_NE(std::string(bloom_filter_bytes), empty_string); -} - -TEST(BloomFilterTest, CopyConstructorAndAssignmentSuccess) { - BloomFilter<kByteArrayLength> bloom_filter; - - EXPECT_FALSE(bloom_filter.PossiblyContains("ELEMENT_1")); - - bloom_filter.Add("ELEMENT_1"); - - BloomFilter<kByteArrayLength> bloom_filter_copy_1{bloom_filter}; - BloomFilter<kByteArrayLength> bloom_filter_copy_2 = bloom_filter; - - EXPECT_TRUE(bloom_filter.PossiblyContains("ELEMENT_1")); - EXPECT_TRUE(bloom_filter_copy_1.PossiblyContains("ELEMENT_1")); - EXPECT_TRUE(bloom_filter_copy_2.PossiblyContains("ELEMENT_1")); -} - -TEST(BloomFilterTest, MoveConstructorSuccess) { - BloomFilter<kByteArrayLength> bloom_filter; - - bloom_filter.Add("ELEMENT_1"); - - BloomFilter<kByteArrayLength> bloom_filter_move{std::move(bloom_filter)}; - - EXPECT_TRUE(bloom_filter_move.PossiblyContains("ELEMENT_1")); -} - -TEST(BloomFilterTest, MoveAssignmentSuccess) { - BloomFilter<kByteArrayLength> bloom_filter; - - bloom_filter.Add("ELEMENT_1"); - - BloomFilter<kByteArrayLength> bloom_filter_move = std::move(bloom_filter); - - EXPECT_TRUE(bloom_filter_move.PossiblyContains("ELEMENT_1")); -} - -/** - * This test was added because of a bug where the BloomFilter doesn't utilize - * all bits given. Functionally, the filter still works, but we just have a much - * higher false positive rate. The bug was caused by confusing bit length and - * byte length, which made our BloomFilter only set bits on the first byteLength - * (bitLength / 8) bits rather than the whole bitLength bits. - * - * <p>Here, we're verifying that the bits set are somewhat scattered. So instead - * of something like [ 0, 1, 1, 0, 0, 0, 0, ..., 0 ], we should be getting - * something like [ 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, ..., 1, 0]. - */ -TEST(BloomFilterTest, RandomnessNoEndBias) { - BloomFilter<kByteArrayLength> bloom_filter; - - // Add one element to our BloomFilter. - bloom_filter.Add("ELEMENT_1"); - - std::int32_t non_zero_count = 0; - std::int32_t longest_zero_streak = 0; - std::int32_t current_zero_streak = 0; - - // Record the amount of non-zero bytes and the longest streak of zero bytes in - // the resulting BloomFilter. This is an approximation of reasonable - // distribution since we're recording by bytes instead of bits. - ByteArray bloom_filter_bytes(bloom_filter); - const char* bloom_filter_bytes_read_ptr = bloom_filter_bytes.data(); - for (int i = 0; i < bloom_filter_bytes.size(); i++) { - if (*bloom_filter_bytes_read_ptr == '\0') { - current_zero_streak++; - } else { - // Increment the number of non-zero bytes we've seen, update the longest - // zero streak, and then reset the current zero streak. - non_zero_count++; - longest_zero_streak = std::max(longest_zero_streak, current_zero_streak); - current_zero_streak = 0; - } - bloom_filter_bytes_read_ptr++; - } - // Update the longest zero streak again for the tail case. - longest_zero_streak = std::min(longest_zero_streak, current_zero_streak); - - // Since randomness is hard to measure within one unit test, we instead do a - // sanity check. All non-zero bytes should not be packed into one end of the - // array. - // - // In this case, the size of one end is approximated to be: - // kByteArrayLength / nonZeroCount. - // Therefore, the longest zero streak should be less than: - // kByteArrayLength - one end of the array. - std::int32_t longest_acceptable_zero_streak = - kByteArrayLength - (kByteArrayLength / non_zero_count); - - EXPECT_TRUE(longest_zero_streak <= longest_acceptable_zero_streak); -} - -TEST(BloomFilterTest, RandomnessFalsePositiveRate) { - BloomFilter<10> bloom_filter; - - // Add 5 distinct elements to the BloomFilter. - bloom_filter.Add("ELEMENT_1"); - bloom_filter.Add("ELEMENT_2"); - bloom_filter.Add("ELEMENT_3"); - bloom_filter.Add("ELEMENT_4"); - bloom_filter.Add("ELEMENT_5"); - - std::int32_t false_positives = 0; - // Now test 100 other elements and record the number of false positives. - for (int i = 5; i < 105; i++) { - false_positives += - bloom_filter.PossiblyContains("ELEMENT_" + std::to_string(i)) ? 1 : 0; - } - - // We expect the false positive rate to be 3% with 5 elements in a 10 byte - // filter. Thus, we give a little leeway and verify that the false positive - // rate is no more than 5%. - EXPECT_LE(false_positives, 5); -} - -} // namespace -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location 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 deleted file mode 100644 index bfa15992b26..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/bluetooth_classic.cc +++ /dev/null @@ -1,434 +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/bluetooth_classic.h" - -#include <memory> -#include <string> -#include <utility> - -#include "core/internal/mediums/uuid.h" -#include "platform/public/logging.h" -#include "platform/public/mutex_lock.h" - -namespace location { -namespace nearby { -namespace connections { - -BluetoothClassic::BluetoothClassic(BluetoothRadio& radio) : radio_(radio) {} - -BluetoothClassic::~BluetoothClassic() { - // Destructor is not taking locks, but methods it is calling are. - StopDiscovery(); - while (!server_sockets_.empty()) { - StopAcceptingConnections(server_sockets_.begin()->first); - } - TurnOffDiscoverability(); - - // All the AcceptLoopRunnable objects in here should already have gotten an - // opportunity to shut themselves down cleanly in the calls to - // StopAcceptingConnections() above. - accept_loops_runner_.Shutdown(); -} - -bool BluetoothClassic::IsAvailable() const { - MutexLock lock(&mutex_); - - return IsAvailableLocked(); -} - -bool BluetoothClassic::IsAvailableLocked() const { - return medium_.IsValid() && adapter_.IsValid(); -} - -bool BluetoothClassic::TurnOnDiscoverability(const std::string& device_name) { - MutexLock lock(&mutex_); - - if (device_name.empty()) { - NEARBY_LOG(INFO, - "Refusing to turn on BT discoverability. Empty device name."); - return false; - } - - if (!radio_.IsEnabled()) { - NEARBY_LOG(INFO, "Can't turn on BT discoverability. BT is off."); - return false; - } - - if (!IsAvailableLocked()) { - NEARBY_LOG(INFO, "Can't turn on BT discoverability. BT is not available."); - return false; - } - - if (IsDiscoverable()) { - NEARBY_LOG(INFO, - "Refusing to turn on BT discoverability; new name='%s'; " - "current name='%s'", - device_name.c_str(), adapter_.GetName().c_str()); - return false; - } - - if (!ModifyDeviceName(device_name)) { - NEARBY_LOG(INFO, - "Failed to turn on BT discoverability; " - "failed to set name to %s", - device_name.c_str()); - return false; - } - - if (!ModifyScanMode(ScanMode::kConnectableDiscoverable)) { - NEARBY_LOG(INFO, - "Failed to turn on BT discoverability; " - "failed to set scan_mode to %d", - ScanMode::kConnectableDiscoverable); - - // Don't forget to perform this rollback of the partial state changes we've - // made til now. - RestoreDeviceName(); - return false; - } - - NEARBY_LOG(INFO, "Turned on BT discoverability with device_name=%s", - device_name.c_str()); - return true; -} - -bool BluetoothClassic::TurnOffDiscoverability() { - MutexLock lock(&mutex_); - - if (!IsDiscoverable()) { - NEARBY_LOG(INFO, "Can't turn off BT discoverability; it is already off"); - return false; - } - - RestoreScanMode(); - RestoreDeviceName(); - - NEARBY_LOG(INFO, "Turned Bluetooth discoverability off"); - return true; -} - -bool BluetoothClassic::IsDiscoverable() const { - return (!original_device_name_.empty() && - (adapter_.GetScanMode() == ScanMode::kConnectableDiscoverable)); -} - -bool BluetoothClassic::ModifyDeviceName(const std::string& device_name) { - if (original_device_name_.empty()) { - original_device_name_ = adapter_.GetName(); - } - - return adapter_.SetName(device_name); -} - -bool BluetoothClassic::ModifyScanMode(ScanMode scan_mode) { - if (original_scan_mode_ == ScanMode::kUnknown) { - original_scan_mode_ = adapter_.GetScanMode(); - } - - if (!adapter_.SetScanMode(scan_mode)) { - original_scan_mode_ = ScanMode::kUnknown; - return false; - } - - return true; -} - -bool BluetoothClassic::RestoreScanMode() { - if (original_scan_mode_ == ScanMode::kUnknown || - !adapter_.SetScanMode(original_scan_mode_)) { - NEARBY_LOG(INFO, "Failed to restore original Bluetooth scan mode to %d", - original_scan_mode_); - return false; - } - - // Regardless of whether or not we could actually restore the Bluetooth scan - // mode, reset our relevant state. - original_scan_mode_ = ScanMode::kUnknown; - return true; -} - -bool BluetoothClassic::RestoreDeviceName() { - if (original_device_name_.empty() || - !adapter_.SetName(original_device_name_)) { - NEARBY_LOG(INFO, "Failed to restore original Bluetooth device name to %s", - original_device_name_.c_str()); - return false; - } - original_device_name_.clear(); - return true; -} - -bool BluetoothClassic::StartDiscovery(DiscoveredDeviceCallback callback) { - MutexLock lock(&mutex_); - - if (!radio_.IsEnabled()) { - NEARBY_LOG(INFO, "Can't discover BT devices because BT isn't enabled."); - return false; - } - - if (!IsAvailableLocked()) { - NEARBY_LOG(INFO, "Can't discover BT devices because BT isn't available."); - return false; - } - - if (IsDiscovering()) { - NEARBY_LOG(INFO, - "Refusing to start discovery of BT devices because another " - "discovery is already in-progress."); - return false; - } - - if (!medium_.StartDiscovery(callback)) { - NEARBY_LOG(INFO, "Failed to start discovery of BT devices."); - return false; - } - - // Mark the fact that we're currently performing a Bluetooth scan. - scan_info_.valid = true; - - return true; -} - -bool BluetoothClassic::StopDiscovery() { - MutexLock lock(&mutex_); - - if (!IsDiscovering()) { - NEARBY_LOG(INFO, - "Can't stop discovery of BT devices because it never started."); - return false; - } - - if (!medium_.StopDiscovery()) { - NEARBY_LOG(INFO, "Failed to stop discovery of Bluetooth devices."); - return false; - } - - scan_info_.valid = false; - return true; -} - -bool BluetoothClassic::IsDiscovering() const { return scan_info_.valid; } - -bool BluetoothClassic::StartAcceptingConnections( - const std::string& service_name, AcceptedConnectionCallback callback) { - MutexLock lock(&mutex_); - - if (service_name.empty()) { - NEARBY_LOG( - INFO, - "Refusing to start accepting BT connections; service name is empty."); - return false; - } - - if (!radio_.IsEnabled()) { - NEARBY_LOG(INFO, - "Can't create BT server socket [service=%s]; BT is disabled.", - service_name.c_str()); - return false; - } - - if (!IsAvailableLocked()) { - NEARBY_LOG( - INFO, - "Can't start accepting BT connections [service=%s]; BT not available.", - service_name.c_str()); - return false; - } - - if (IsAcceptingConnectionsLocked(service_name)) { - NEARBY_LOG(INFO, - "Refusing to start accepting BT connections [service=%s]; BT " - "server is already in-progress with the same name.", - service_name.c_str()); - return false; - } - - BluetoothServerSocket socket = medium_.ListenForService( - service_name, GenerateUuidFromString(service_name)); - if (!socket.IsValid()) { - NEARBY_LOG(INFO, "Failed to start accepting Bluetooth connections for %s.", - service_name.c_str()); - return false; - } - - // Mark the fact that there's an in-progress Bluetooth server accepting - // connections. - auto owned_socket = - server_sockets_.emplace(service_name, std::move(socket)).first->second; - - // 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( - "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; -} - -bool BluetoothClassic::IsAcceptingConnections(const std::string& service_name) { - MutexLock lock(&mutex_); - - return IsAcceptingConnectionsLocked(service_name); -} - -bool BluetoothClassic::IsAcceptingConnectionsLocked( - const std::string& service_name) { - return server_sockets_.find(service_name) != server_sockets_.end(); -} - -bool BluetoothClassic::StopAcceptingConnections( - const std::string& service_name) { - MutexLock lock(&mutex_); - - if (service_name.empty()) { - NEARBY_LOG(INFO, - "Unable to stop accepting BT connections because the " - "service_name is empty."); - return false; - } - - const auto& it = server_sockets_.find(service_name); - if (it == server_sockets_.end()) { - NEARBY_LOG(INFO, - "Can't stop accepting BT connections for %s because it was " - "never started.", - service_name.c_str()); - return false; - } - - // Closing the BluetoothServerSocket will kick off the suicide of the thread - // in accept_loops_thread_pool_ that blocks on BluetoothServerSocket.accept(). - // That may take some time to complete, but there's no particular reason to - // wait around for it. - auto item = server_sockets_.extract(it); - - // Store a handle to the BluetoothServerSocket, so we can use it after - // removing the entry from server_sockets_; making it scoped - // is a bonus that takes care of deallocation before we leave this method. - BluetoothServerSocket& listening_socket = item.mapped(); - - // Regardless of whether or not we fail to close the existing - // BluetoothServerSocket, remove it from server_sockets_ so that it - // frees up this service for another round. - - // Finally, close the BluetoothServerSocket. - if (!listening_socket.Close().Ok()) { - NEARBY_LOG(INFO, "Failed to close BT server socket for %s.", - service_name.c_str()); - return false; - } - - return true; -} - -BluetoothSocket BluetoothClassic::Connect(BluetoothDevice& bluetooth_device, - const std::string& service_name, - CancellationFlag* cancellation_flag) { - for (int attempts_count = 0; attempts_count < kConnectAttemptsLimit; - attempts_count++) { - auto wrapper_result = - AttemptToConnect(bluetooth_device, service_name, cancellation_flag); - if (wrapper_result.IsValid()) { - return wrapper_result; - } - } - return BluetoothSocket(); -} - -BluetoothSocket BluetoothClassic::AttemptToConnect( - BluetoothDevice& bluetooth_device, const std::string& service_name, - CancellationFlag* cancellation_flag) { - MutexLock lock(&mutex_); - NEARBY_LOG(INFO, "BluetoothClassic::Connect: device=%p", &bluetooth_device); - // Socket to return. To allow for NRVO to work, it has to be a single object. - BluetoothSocket socket; - - if (service_name.empty()) { - NEARBY_LOG( - INFO, - "Refusing to create client BT socket because service_name is empty."); - return socket; - } - - if (!radio_.IsEnabled()) { - NEARBY_LOG(INFO, - "Can't create client BT socket [service=%s]: BT isn't enabled.", - service_name.c_str()); - return socket; - } - - if (!IsAvailableLocked()) { - NEARBY_LOG( - INFO, "Can't create client BT socket [service=%s]; BT isn't available.", - service_name.c_str()); - return socket; - } - - if (cancellation_flag->Cancelled()) { - NEARBY_LOGS(INFO) << "Can't create client BT socket due to cancel."; - return socket; - } - - socket = medium_.ConnectToService(bluetooth_device, - GenerateUuidFromString(service_name), - cancellation_flag); - if (!socket.IsValid()) { - NEARBY_LOG(INFO, "Failed to Connect via BT [service=%s]", - service_name.c_str()); - } - - return socket; -} - -BluetoothDevice BluetoothClassic::GetRemoteDevice( - const std::string& mac_address) { - MutexLock lock(&mutex_); - - if (!IsAvailableLocked()) { - return {}; - } - - return medium_.GetRemoteDevice(mac_address); -} - -std::string BluetoothClassic::GetMacAddress() const { - MutexLock lock(&mutex_); - - if (!IsAvailableLocked()) { - return {}; - } - - return medium_.GetMacAddress(); -} - -std::string BluetoothClassic::GenerateUuidFromString(const std::string& data) { - return std::string(Uuid(data)); -} - -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/bluetooth_classic.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/bluetooth_classic.h deleted file mode 100644 index 8389b1a0b7c..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/bluetooth_classic.h +++ /dev/null @@ -1,210 +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_BLUETOOTH_CLASSIC_H_ -#define CORE_INTERNAL_MEDIUMS_BLUETOOTH_CLASSIC_H_ - -#include <cstdint> -#include <string> - -#include "absl/container/flat_hash_map.h" -#include "core/internal/mediums/bluetooth_radio.h" -#include "core/listeners.h" -#include "platform/base/byte_array.h" -#include "platform/base/cancellation_flag.h" -#include "platform/public/bluetooth_adapter.h" -#include "platform/public/bluetooth_classic.h" -#include "platform/public/multi_thread_executor.h" -#include "platform/public/mutex.h" - -namespace location { -namespace nearby { -namespace connections { - -class BluetoothClassic { - public: - using DiscoveredDeviceCallback = BluetoothClassicMedium::DiscoveryCallback; - using ScanMode = BluetoothAdapter::ScanMode; - - // Callback that is invoked when a new connection is accepted. - struct AcceptedConnectionCallback { - std::function<void(BluetoothSocket socket)> accepted_cb = - DefaultCallback<BluetoothSocket>(); - }; - - explicit BluetoothClassic(BluetoothRadio& bluetooth_radio); - ~BluetoothClassic(); - - // Returns true, if BT communications are supported by a platform. - bool IsAvailable() const ABSL_LOCKS_EXCLUDED(mutex_); - - // Sets custom device name, and then enables BT discoverable mode. - // Returns true, if name and scan mode are successfully set, and false - // otherwise. - // Called by server. - bool TurnOnDiscoverability(const std::string& device_name) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Disables BT discoverability, and restores scan mode and device name to - // what they were before the call to TurnOnDiscoverability(). - // Returns false if no successful call TurnOnDiscoverability() was previously - // made, otherwise returns true. - // Called by server. - bool TurnOffDiscoverability() ABSL_LOCKS_EXCLUDED(mutex_); - - // Enables BT discovery mode. Will report any discoverable devices in range - // through a callback. - // Returns true, if discovery mode was enabled, false otherwise. - // Called by client. - bool StartDiscovery(DiscoveredDeviceCallback callback) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Disables BT discovery mode. - // Returns true, if discovery mode was previously enabled, false otherwise. - // Called by client. - bool StopDiscovery() ABSL_LOCKS_EXCLUDED(mutex_); - - // Starts a worker thread, creates a BT server socket, associates it with a - // service name; in a worker thread repeatedly calls ServerSocket::Accept(). - // Any connected sockets returned from Accept() are passed to a callback. - // Returns true, if server socket was successfully created, false otherwise. - // Called by server. - bool StartAcceptingConnections(const std::string& service_name, - AcceptedConnectionCallback callback) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Returns true, if object is currently running a Accept() loop. - bool IsAcceptingConnections(const std::string& service_name) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Closes server socket corresponding to a service name. This automatically - // terminates Accept() loop, if it were running. - // Called by server. - bool StopAcceptingConnections(const std::string& service_name) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Returns true if this object owns a valid platform implementation. - bool IsMediumValid() const ABSL_LOCKS_EXCLUDED(mutex_) { - MutexLock lock(&mutex_); - return medium_.IsValid(); - } - - // Returns true if this object has a valid BluetoothAdapter reference. - bool IsAdapterValid() const ABSL_LOCKS_EXCLUDED(mutex_) { - MutexLock lock(&mutex_); - return adapter_.IsValid(); - } - - // Establishes connection to BT service with internal retry for maximum - // attempts of kConnectAttemptsLimit. - // Blocks until connection is established, or server-side is terminated. - // Returns socket instance. On success, BluetoothSocket.IsValid() return true. - // Called by client. - BluetoothSocket Connect(BluetoothDevice& bluetooth_device, - const std::string& service_name, - CancellationFlag* cancellation_flag) - ABSL_LOCKS_EXCLUDED(mutex_); - - std::string GetMacAddress() const ABSL_LOCKS_EXCLUDED(mutex_); - - BluetoothDevice GetRemoteDevice(const std::string& mac_address) - ABSL_LOCKS_EXCLUDED(mutex_); - - private: - struct ScanInfo { - bool valid = false; - }; - - static constexpr int kMaxConcurrentAcceptLoops = 5; - - static constexpr int kConnectAttemptsLimit = 3; - - // Constructs UUID object from arbitrary string, using MD5 hash, and then - // converts UUID to a readable UUID string and returns it. - static std::string GenerateUuidFromString(const std::string& data); - - // Same as IsAvailable(), but must be called with mutex_ held. - bool IsAvailableLocked() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Same as IsAcceptingConnections(), but must be called with mutex_ held. - bool IsAcceptingConnectionsLocked(const std::string& service_name) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Returns true, if discoverability is enabled with TurnOnDiscoverability(). - bool IsDiscoverable() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Assignes a different name to BT adapter. - // Returns true if successful. Stores original device name. - bool ModifyDeviceName(const std::string& device_name) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Changes current scan mode. This is an implementation of - // Turn<On/Off>Discoveradility() method. Stores original scan mode. - bool ModifyScanMode(ScanMode scan_mode) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Restores original device name (the one before the very first call to - // ModifyDeviceName()). Returns true if successful. - bool RestoreScanMode() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Restores original device scan mode (the one before the very first call to - // ModifyScanMode()). Returns true if successful. - bool RestoreDeviceName() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Returns true if device is currently in discovery mode. - bool IsDiscovering() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Establishes connection to BT service that was might be started on another - // device with StartAcceptingConnections() using the same service_name. - // Blocks until connection is established, or server-side is terminated. - // Returns socket instance. On success, BluetoothSocket.IsValid() return true. - // Called by client. - BluetoothSocket AttemptToConnect(BluetoothDevice& bluetooth_device, - const std::string& service_name, - CancellationFlag* cancellation_flag); - - mutable Mutex mutex_; - BluetoothRadio& radio_ ABSL_GUARDED_BY(mutex_); - BluetoothAdapter& adapter_ ABSL_GUARDED_BY(mutex_){ - radio_.GetBluetoothAdapter()}; - BluetoothClassicMedium medium_ ABSL_GUARDED_BY(mutex_){adapter_}; - - // A bundle of state required to do a Bluetooth Classic scan. When non-null, - // we are currently performing a Bluetooth scan. - ScanInfo scan_info_ ABSL_GUARDED_BY(mutex_); - - // The original scan mode (that controls visibility to scanners) of the device - // before we modified it. Restored when we stop advertising. - ScanMode original_scan_mode_ ABSL_GUARDED_BY(mutex_) = ScanMode::kUnknown; - - // The original Bluetooth device name, before we modified it. If non-empty, we - // are currently Bluetooth discoverable. Restored when we stop advertising. - std::string original_device_name_ ABSL_GUARDED_BY(mutex_); - - // A thread pool dedicated to running all the accept loops from - // StartAcceptingConnections(). - MultiThreadExecutor accept_loops_runner_{kMaxConcurrentAcceptLoops}; - - // A map of service Name -> ServerSocket. If map is non-empty, we - // are currently listening for incoming connections. - // BluetoothServerSocket instances are used from accept_loops_runner_, - // and thus require pointer stability. - absl::flat_hash_map<std::string, BluetoothServerSocket> server_sockets_ - ABSL_GUARDED_BY(mutex_); -}; - -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_BLUETOOTH_CLASSIC_H_ diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/bluetooth_classic_test.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/bluetooth_classic_test.cc deleted file mode 100644 index d386bea51e0..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/bluetooth_classic_test.cc +++ /dev/null @@ -1,290 +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/bluetooth_classic.h" - -#include <string> - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "absl/time/time.h" -#include "core/internal/mediums/bluetooth_radio.h" -#include "platform/base/medium_environment.h" -#include "platform/public/bluetooth_classic.h" -#include "platform/public/count_down_latch.h" -#include "platform/public/logging.h" -#include "platform/public/system_clock.h" - -namespace location { -namespace nearby { -namespace connections { -namespace { - -using FeatureFlags = FeatureFlags::Flags; - -constexpr FeatureFlags kTestCases[] = { - FeatureFlags{ - .enable_cancellation_flag = true, - }, - FeatureFlags{ - .enable_cancellation_flag = false, - }, -}; - -constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000); - -class BluetoothClassicTest : public ::testing::TestWithParam<FeatureFlags> { - protected: - using DiscoveryCallback = BluetoothClassicMedium::DiscoveryCallback; - - BluetoothClassicTest() { - env_.Start(); - env_.Reset(); - radio_a_ = std::make_unique<BluetoothRadio>(); - radio_b_ = std::make_unique<BluetoothRadio>(); - bt_a_ = std::make_unique<BluetoothClassic>(*radio_a_); - bt_b_ = std::make_unique<BluetoothClassic>(*radio_b_); - radio_a_->GetBluetoothAdapter().SetName("Device-A"); - radio_b_->GetBluetoothAdapter().SetName("Device-B"); - radio_a_->Enable(); - radio_b_->Enable(); - env_.Sync(); - } - - ~BluetoothClassicTest() override { - env_.Sync(false); - radio_a_->Disable(); - radio_b_->Disable(); - bt_a_.reset(); - bt_b_.reset(); - env_.Sync(false); - radio_a_.reset(); - radio_b_.reset(); - env_.Reset(); - env_.Stop(); - } - - MediumEnvironment& env_{MediumEnvironment::Instance()}; - - std::unique_ptr<BluetoothRadio> radio_a_; - std::unique_ptr<BluetoothRadio> radio_b_; - std::unique_ptr<BluetoothClassic> bt_a_; - std::unique_ptr<BluetoothClassic> bt_b_; -}; - -TEST_P(BluetoothClassicTest, CanConnect) { - FeatureFlags feature_flags = GetParam(); - env_.SetFeatureFlags(feature_flags); - - constexpr absl::string_view kDeviceName{"Simulated BT device #1"}; - constexpr absl::string_view kServiceName{"service name"}; - - BluetoothRadio& radio_for_client = *radio_a_; - BluetoothRadio& radio_for_server = *radio_b_; - BluetoothClassic& bt_client = *bt_a_; - BluetoothClassic& bt_server = *bt_b_; - - EXPECT_TRUE(radio_for_client.IsEnabled()); - EXPECT_TRUE(radio_for_server.IsEnabled()); - - EXPECT_TRUE(bt_server.TurnOnDiscoverability(std::string(kDeviceName))); - EXPECT_EQ(radio_for_server.GetBluetoothAdapter().GetName(), - std::string(kDeviceName)); - CountDownLatch latch(1); - BluetoothDevice discovered_device; - EXPECT_TRUE(bt_client.StartDiscovery({ - .device_discovered_cb = - [&latch, &discovered_device](BluetoothDevice& device) { - discovered_device = device; - NEARBY_LOG(INFO, "Discovered device=%p [impl=%p]", &device, - &device.GetImpl()); - latch.CountDown(); - }, - })); - EXPECT_TRUE(latch.Await(kWaitDuration).result()); - EXPECT_TRUE(bt_server.TurnOffDiscoverability()); - ASSERT_TRUE(discovered_device.IsValid()); - BluetoothSocket socket_for_server; - CountDownLatch accept_latch(1); - EXPECT_TRUE(bt_server.StartAcceptingConnections( - std::string(kServiceName), - { - .accepted_cb = - [&socket_for_server, &accept_latch](BluetoothSocket socket) { - socket_for_server = std::move(socket); - accept_latch.CountDown(); - }, - })); - CancellationFlag flag; - BluetoothSocket socket_for_client = - bt_client.Connect(discovered_device, std::string(kServiceName), &flag); - EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(bt_server.StopAcceptingConnections(std::string(kServiceName))); - EXPECT_TRUE(socket_for_server.IsValid()); - EXPECT_TRUE(socket_for_client.IsValid()); - EXPECT_TRUE(socket_for_server.GetRemoteDevice().IsValid()); - EXPECT_TRUE(socket_for_client.GetRemoteDevice().IsValid()); -} - -TEST_P(BluetoothClassicTest, CanCancelConnect) { - FeatureFlags feature_flags = GetParam(); - env_.SetFeatureFlags(feature_flags); - - constexpr absl::string_view kDeviceName{"Simulated BT device #1"}; - constexpr absl::string_view kServiceName{"service name"}; - - BluetoothRadio& radio_for_client = *radio_a_; - BluetoothRadio& radio_for_server = *radio_b_; - BluetoothClassic& bt_client = *bt_a_; - BluetoothClassic& bt_server = *bt_b_; - - EXPECT_TRUE(radio_for_client.IsEnabled()); - EXPECT_TRUE(radio_for_server.IsEnabled()); - - EXPECT_TRUE(bt_server.TurnOnDiscoverability(std::string(kDeviceName))); - EXPECT_EQ(radio_for_server.GetBluetoothAdapter().GetName(), - std::string(kDeviceName)); - CountDownLatch latch(1); - BluetoothDevice discovered_device; - EXPECT_TRUE(bt_client.StartDiscovery({ - .device_discovered_cb = - [&latch, &discovered_device](BluetoothDevice& device) { - discovered_device = device; - NEARBY_LOG(INFO, "Discovered device=%p [impl=%p]", &device, - &device.GetImpl()); - latch.CountDown(); - }, - })); - EXPECT_TRUE(latch.Await(kWaitDuration).result()); - EXPECT_TRUE(bt_server.TurnOffDiscoverability()); - ASSERT_TRUE(discovered_device.IsValid()); - BluetoothSocket socket_for_server; - CountDownLatch accept_latch(1); - EXPECT_TRUE(bt_server.StartAcceptingConnections( - std::string(kServiceName), - { - .accepted_cb = - [&socket_for_server, &accept_latch](BluetoothSocket socket) { - socket_for_server = std::move(socket); - accept_latch.CountDown(); - }, - })); - CancellationFlag flag(true); - BluetoothSocket socket_for_client = - bt_client.Connect(discovered_device, std::string(kServiceName), &flag); - // If FeatureFlag is disabled, Cancelled is false as no-op. - if (!feature_flags.enable_cancellation_flag) { - EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(bt_server.StopAcceptingConnections(std::string(kServiceName))); - EXPECT_TRUE(socket_for_server.IsValid()); - EXPECT_TRUE(socket_for_client.IsValid()); - EXPECT_TRUE(socket_for_server.GetRemoteDevice().IsValid()); - EXPECT_TRUE(socket_for_client.GetRemoteDevice().IsValid()); - } else { - EXPECT_FALSE(accept_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(bt_server.StopAcceptingConnections(std::string(kServiceName))); - EXPECT_FALSE(socket_for_server.IsValid()); - EXPECT_FALSE(socket_for_client.IsValid()); - } -} - -INSTANTIATE_TEST_SUITE_P(ParametrisedBluetoothClassicTest, BluetoothClassicTest, - ::testing::ValuesIn(kTestCases)); - -TEST_F(BluetoothClassicTest, CanConstructValidObject) { - EXPECT_TRUE(bt_a_->IsMediumValid()); - EXPECT_TRUE(bt_a_->IsAdapterValid()); - EXPECT_TRUE(bt_a_->IsAvailable()); - EXPECT_TRUE(bt_b_->IsMediumValid()); - EXPECT_TRUE(bt_b_->IsAdapterValid()); - EXPECT_TRUE(bt_b_->IsAvailable()); - EXPECT_NE(&radio_a_->GetBluetoothAdapter(), &radio_b_->GetBluetoothAdapter()); -} - -TEST_F(BluetoothClassicTest, CanStartAdvertising) { - constexpr absl::string_view kDeviceName{"Simulated BT device #1"}; - EXPECT_TRUE(bt_a_->TurnOnDiscoverability(std::string(kDeviceName))); - EXPECT_EQ(radio_a_->GetBluetoothAdapter().GetName(), kDeviceName); -} - -TEST_F(BluetoothClassicTest, CanStopAdvertising) { - constexpr absl::string_view kDeviceName{"Simulated BT device #1"}; - EXPECT_TRUE(bt_a_->TurnOnDiscoverability(std::string(kDeviceName))); - EXPECT_EQ(radio_a_->GetBluetoothAdapter().GetName(), kDeviceName); - EXPECT_TRUE(bt_a_->TurnOffDiscoverability()); -} - -TEST_F(BluetoothClassicTest, CanStartDiscovery) { - constexpr absl::string_view kDeviceName{"Simulated BT device #1"}; - EXPECT_TRUE(bt_a_->TurnOnDiscoverability(std::string(kDeviceName))); - EXPECT_EQ(radio_a_->GetBluetoothAdapter().GetName(), kDeviceName); - CountDownLatch latch(1); - EXPECT_TRUE(bt_b_->StartDiscovery({ - .device_discovered_cb = - [&latch](BluetoothDevice& device) { latch.CountDown(); }, - })); - EXPECT_TRUE(latch.Await(kWaitDuration).result()); - EXPECT_TRUE(bt_a_->TurnOffDiscoverability()); -} - -TEST_F(BluetoothClassicTest, CanStopDiscovery) { - CountDownLatch latch(1); - EXPECT_TRUE(bt_a_->StartDiscovery({ - .device_discovered_cb = - [&latch](BluetoothDevice& device) { latch.CountDown(); }, - })); - EXPECT_FALSE(latch.Await(kWaitDuration).result()); - EXPECT_TRUE(bt_a_->StopDiscovery()); -} - -TEST_F(BluetoothClassicTest, CanStartAcceptingConnections) { - constexpr absl::string_view kDeviceName{"Simulated BT device #1"}; - constexpr absl::string_view kServiceName{"service name"}; - - BluetoothRadio& radio_for_client = *radio_a_; - BluetoothRadio& radio_for_server = *radio_b_; - BluetoothClassic& bt_client = *bt_a_; - BluetoothClassic& bt_server = *bt_b_; - - EXPECT_TRUE(radio_for_client.IsEnabled()); - EXPECT_TRUE(radio_for_server.IsEnabled()); - - EXPECT_TRUE(bt_server.TurnOnDiscoverability(std::string(kDeviceName))); - EXPECT_EQ(radio_for_server.GetBluetoothAdapter().GetName(), kDeviceName); - CountDownLatch latch(1); - BluetoothDevice discovered_device; - EXPECT_TRUE(bt_client.StartDiscovery({ - .device_discovered_cb = - [&latch, &discovered_device](BluetoothDevice& device) { - discovered_device = device; - NEARBY_LOG(INFO, "Discovered device=%p [impl=%p]", &device, - &device.GetImpl()); - latch.CountDown(); - }, - })); - EXPECT_TRUE(latch.Await(kWaitDuration).result()); - EXPECT_TRUE(bt_server.TurnOffDiscoverability()); - EXPECT_TRUE(discovered_device.IsValid()); - EXPECT_TRUE( - bt_server.StartAcceptingConnections(std::string(kServiceName), {})); - // Allow StartAcceptingConnections do something, before stopping it. - // This is best effort, because no callbacks are invoked in this scenario. - SystemClock::Sleep(kWaitDuration); - EXPECT_TRUE(bt_server.StopAcceptingConnections(std::string(kServiceName))); -} - -} // namespace -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/bluetooth_radio.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/bluetooth_radio.cc deleted file mode 100644 index e0ec86149e4..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/bluetooth_radio.cc +++ /dev/null @@ -1,120 +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/bluetooth_radio.h" - -#include "platform/base/exception.h" -#include "platform/public/logging.h" -#include "platform/public/system_clock.h" - -namespace location { -namespace nearby { -namespace connections { - -constexpr absl::Duration BluetoothRadio::kPauseBetweenToggle; - -BluetoothRadio::BluetoothRadio() { - if (!IsAdapterValid()) { - NEARBY_LOG(ERROR, "Bluetooth adapter is not valid: BT is not supported"); - } -} - -BluetoothRadio::~BluetoothRadio() { - // We never enabled Bluetooth, nothing to do. - if (!ever_saved_state_.Get()) { - NEARBY_LOG(INFO, "BT adapter was not used. Not touching HW."); - return; - } - - // Toggle Bluetooth regardless of our original state. Some devices/chips can - // start to freak out after some time (e.g. b/37775337), and this helps to - // ensure BT resets properly. - NEARBY_LOG(INFO, "Toggle BT adapter state before releasing adapter."); - Toggle(); - - NEARBY_LOG(INFO, "Bring BT adapter to original state"); - if (!SetBluetoothState(originally_enabled_.Get())) { - NEARBY_LOG(INFO, "Failed to restore BT adapter original state."); - } -} - -bool BluetoothRadio::Enable() { - if (!SaveOriginalState()) { - return false; - } - - return SetBluetoothState(true); -} - -bool BluetoothRadio::Disable() { - if (!SaveOriginalState()) { - return false; - } - - return SetBluetoothState(false); -} - -bool BluetoothRadio::IsEnabled() const { - return IsAdapterValid() && IsInDesiredState(true); -} - -bool BluetoothRadio::Toggle() { - if (!SaveOriginalState()) { - return false; - } - - if (!SetBluetoothState(false)) { - NEARBY_LOG(INFO, "BT Toggle: Failed to turn BT off."); - return false; - } - - if (SystemClock::Sleep(kPauseBetweenToggle).Raised(Exception::kInterrupted)) { - NEARBY_LOG(INFO, "BT Toggle: interrupted before turing on."); - return false; - } - - if (!SetBluetoothState(true)) { - NEARBY_LOG(INFO, "BT Toggle: Failed to turn BT on."); - return false; - } - - return true; -} - -bool BluetoothRadio::SetBluetoothState(bool enable) { - return bluetooth_adapter_.SetStatus( - enable ? BluetoothAdapter::Status::kEnabled - : BluetoothAdapter::Status::kDisabled); -} - -bool BluetoothRadio::IsInDesiredState(bool should_be_enabled) const { - return bluetooth_adapter_.IsEnabled() == should_be_enabled; -} - -bool BluetoothRadio::SaveOriginalState() { - if (!IsAdapterValid()) { - return false; - } - - // If we haven't saved the original state of the radio, save it. - if (!ever_saved_state_.Set(true)) { - originally_enabled_.Set(bluetooth_adapter_.IsEnabled()); - } - - return true; -} - -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/bluetooth_radio.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/bluetooth_radio.h deleted file mode 100644 index 59ee3f7d572..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/bluetooth_radio.h +++ /dev/null @@ -1,90 +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_BLUETOOTH_RADIO_H_ -#define CORE_INTERNAL_MEDIUMS_BLUETOOTH_RADIO_H_ - -#include <cstdint> - -#include "absl/time/clock.h" -#include "platform/public/atomic_boolean.h" -#include "platform/public/bluetooth_adapter.h" - -namespace location { -namespace nearby { -namespace connections { - -// Provides the operations that can be performed on the Bluetooth radio. -class BluetoothRadio { - public: - BluetoothRadio(); - BluetoothRadio(BluetoothRadio&&) = default; - BluetoothRadio& operator=(BluetoothRadio&&) = default; - - // Reverts the Bluetooth radio to its original state. - ~BluetoothRadio(); - - // Enables Bluetooth. - // - // This must be called before attempting to invoke any other methods of - // this class. - // - // Returns true if enabled successfully. - bool Enable(); - - // Disables Bluetooth. - // - // Returns true if disabled successfully. - bool Disable(); - - // Returns true if the Bluetooth radio is currently enabled. - bool IsEnabled() const; - - // Turn BT radio Off, delay for kPauseBetweenToggle and then turn it On. - // This will block calling thread for at least kPauseBetweenToggle duration. - bool Toggle(); - - // Returns result of BluetoothAdapter::IsValid() for private adapter instance. - bool IsAdapterValid() const { return bluetooth_adapter_.IsValid(); } - - BluetoothAdapter& GetBluetoothAdapter() { return bluetooth_adapter_; } - - private: - static constexpr absl::Duration kPauseBetweenToggle = absl::Seconds(3); - - bool SetBluetoothState(bool enable); - bool IsInDesiredState(bool should_be_enabled) const; - // To be called in enable(), disable(), and toggle(). This will remember the - // original state of the radio before any radio state has been modified. - // Returns false if Bluetooth doesn't exist on the device and the state cannot - // be obtained. - bool SaveOriginalState(); - - // BluetoothAdapter::IsValid() will return false if BT is not supported. - BluetoothAdapter bluetooth_adapter_; - - // The Bluetooth radio's original state, before we modified it. True if - // originally enabled, false if originally disabled. - // We restore the radio to its original state in the destructor. - - AtomicBoolean originally_enabled_{false}; - // false if we never modified the radio state, true otherwise. - AtomicBoolean ever_saved_state_{false}; -}; - -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_BLUETOOTH_RADIO_H_ diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/bluetooth_radio_test.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/bluetooth_radio_test.cc deleted file mode 100644 index 1a10383dd71..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/bluetooth_radio_test.cc +++ /dev/null @@ -1,59 +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/bluetooth_radio.h" - -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -namespace location { -namespace nearby { -namespace connections { -namespace { - -TEST(BluetoothRadioTest, ConstructorDestructorWorks) { - BluetoothRadio radio; - EXPECT_TRUE(radio.IsAdapterValid()); -} - -TEST(BluetoothRadioTest, CanEnable) { - BluetoothRadio radio; - EXPECT_TRUE(radio.IsAdapterValid()); - EXPECT_FALSE(radio.IsEnabled()); - EXPECT_TRUE(radio.Enable()); - EXPECT_TRUE(radio.IsEnabled()); -} - -TEST(BluetoothRadioTest, CanDisable) { - BluetoothRadio radio; - EXPECT_TRUE(radio.IsAdapterValid()); - EXPECT_FALSE(radio.IsEnabled()); - EXPECT_TRUE(radio.Enable()); - EXPECT_TRUE(radio.IsEnabled()); - EXPECT_TRUE(radio.Disable()); - EXPECT_FALSE(radio.IsEnabled()); -} - -TEST(BluetoothRadioTest, CanToggle) { - BluetoothRadio radio; - EXPECT_TRUE(radio.IsAdapterValid()); - EXPECT_FALSE(radio.IsEnabled()); - EXPECT_TRUE(radio.Toggle()); - EXPECT_TRUE(radio.IsEnabled()); -} - -} // namespace -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/lost_entity_tracker.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/lost_entity_tracker.h deleted file mode 100644 index b589155e7ac..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/lost_entity_tracker.h +++ /dev/null @@ -1,94 +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_LOST_ENTITY_TRACKER_H_ -#define CORE_INTERNAL_MEDIUMS_LOST_ENTITY_TRACKER_H_ - -#include "absl/container/flat_hash_set.h" -#include "platform/public/mutex.h" -#include "platform/public/mutex_lock.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -// Tracks "lost" entities based on a manual update/compute model. Used by -// mediums that only report found devices. Lost entities are computed based off -// of whether a specific entity was rediscovered since the last call to -// ComputeLostEntities. -// -// Note: Entity must overload the < and == operators. -template <typename Entity> -class LostEntityTracker { - public: - using EntitySet = absl::flat_hash_set<Entity>; - - LostEntityTracker(); - ~LostEntityTracker(); - - // Records the given entity as being recently found, whether or not this is - // our first time discovering the entity. - void RecordFoundEntity(const Entity& entity) ABSL_LOCKS_EXCLUDED(mutex_); - - // Computes and returns the set of entities considered lost since the last - // time this method was called. - EntitySet ComputeLostEntities() ABSL_LOCKS_EXCLUDED(mutex_); - - private: - Mutex mutex_; - EntitySet current_entities_ ABSL_GUARDED_BY(mutex_); - EntitySet previously_found_entities_ ABSL_GUARDED_BY(mutex_); -}; - -template <typename Entity> -LostEntityTracker<Entity>::LostEntityTracker() - : current_entities_{}, previously_found_entities_{} {} - -template <typename Entity> -LostEntityTracker<Entity>::~LostEntityTracker() { - previously_found_entities_.clear(); - current_entities_.clear(); -} - -template <typename Entity> -void LostEntityTracker<Entity>::RecordFoundEntity(const Entity& entity) { - MutexLock lock(&mutex_); - - current_entities_.insert(entity); -} - -template <typename Entity> -typename LostEntityTracker<Entity>::EntitySet -LostEntityTracker<Entity>::ComputeLostEntities() { - MutexLock lock(&mutex_); - - // The set of lost entities is the previously found set MINUS the currently - // found set. - for (const auto& item : current_entities_) { - previously_found_entities_.erase(item); - } - auto lost_entities = std::move(previously_found_entities_); - previously_found_entities_ = std::move(current_entities_); - current_entities_ = {}; - - return lost_entities; -} - -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_LOST_ENTITY_TRACKER_H_ diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/lost_entity_tracker_test.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/lost_entity_tracker_test.cc deleted file mode 100644 index 0c934e73f74..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/lost_entity_tracker_test.cc +++ /dev/null @@ -1,137 +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/lost_entity_tracker.h" - -#include "gtest/gtest.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { -namespace { - -struct TestEntity { - int id; - - template <typename H> - friend H AbslHashValue(H h, const TestEntity& test_entity) { - return H::combine(std::move(h), test_entity.id); - } - - bool operator==(const TestEntity& other) const { return id == other.id; } - bool operator<(const TestEntity& other) const { return id < other.id; } -}; - -TEST(LostEntityTrackerTest, NoEntitiesLost) { - LostEntityTracker<TestEntity> lost_entity_tracker; - TestEntity entity_1{1}; - TestEntity entity_2{2}; - TestEntity entity_3{3}; - - // Discover some entities. - lost_entity_tracker.RecordFoundEntity(entity_1); - lost_entity_tracker.RecordFoundEntity(entity_2); - lost_entity_tracker.RecordFoundEntity(entity_3); - - // Make sure none are lost on the first round. - ASSERT_TRUE(lost_entity_tracker.ComputeLostEntities().empty()); - - // Rediscover the same entities. - lost_entity_tracker.RecordFoundEntity(entity_1); - lost_entity_tracker.RecordFoundEntity(entity_2); - lost_entity_tracker.RecordFoundEntity(entity_3); - - // Make sure we still didn't lose any entities. - EXPECT_TRUE(lost_entity_tracker.ComputeLostEntities().empty()); -} - -TEST(LostEntityTrackerTest, AllEntitiesLost) { - LostEntityTracker<TestEntity> lost_entity_tracker; - TestEntity entity_1{1}; - TestEntity entity_2{2}; - TestEntity entity_3{3}; - - // Discover some entities. - lost_entity_tracker.RecordFoundEntity(entity_1); - lost_entity_tracker.RecordFoundEntity(entity_2); - lost_entity_tracker.RecordFoundEntity(entity_3); - - // Make sure none are lost on the first round. - EXPECT_TRUE(lost_entity_tracker.ComputeLostEntities().empty()); - - // Go through a round without rediscovering any entities. - typename LostEntityTracker<TestEntity>::EntitySet lost_entities = - lost_entity_tracker.ComputeLostEntities(); - EXPECT_TRUE(lost_entities.find(entity_1) != lost_entities.end()); - EXPECT_TRUE(lost_entities.find(entity_2) != lost_entities.end()); - EXPECT_TRUE(lost_entities.find(entity_3) != lost_entities.end()); -} - -TEST(LostEntityTrackerTest, SomeEntitiesLost) { - LostEntityTracker<TestEntity> lost_entity_tracker; - TestEntity entity_1{1}; - TestEntity entity_2{2}; - TestEntity entity_3{3}; - - // Discover some entities. - lost_entity_tracker.RecordFoundEntity(entity_1); - lost_entity_tracker.RecordFoundEntity(entity_2); - - // Make sure none are lost on the first round. - EXPECT_TRUE(lost_entity_tracker.ComputeLostEntities().empty()); - - // Go through the next round only rediscovering one of our entities and - // discovering an additional entity as well. Then, verify that only one entity - // was lost after the check. - lost_entity_tracker.RecordFoundEntity(entity_1); - lost_entity_tracker.RecordFoundEntity(entity_3); - typename LostEntityTracker<TestEntity>::EntitySet lost_entities = - lost_entity_tracker.ComputeLostEntities(); - EXPECT_TRUE(lost_entities.find(entity_1) == lost_entities.end()); - EXPECT_TRUE(lost_entities.find(entity_2) != lost_entities.end()); - EXPECT_TRUE(lost_entities.find(entity_3) == lost_entities.end()); -} - -TEST(LostEntityTrackerTest, SameEntityMultipleCopies) { - LostEntityTracker<TestEntity> lost_entity_tracker; - TestEntity entity_1{1}; - TestEntity entity_1_copy{1}; - - // Discover an entity. - lost_entity_tracker.RecordFoundEntity(entity_1); - - // Make sure none are lost on the first round. - EXPECT_TRUE(lost_entity_tracker.ComputeLostEntities().empty()); - - // Rediscover the same entity, but through a copy of it. - lost_entity_tracker.RecordFoundEntity(entity_1_copy); - - // Make sure none are lost on the second round. - EXPECT_TRUE(lost_entity_tracker.ComputeLostEntities().empty()); - - // Go through a round without rediscovering any entities and verify that we - // lost an entity equivalent to both copies of it. - typename LostEntityTracker<TestEntity>::EntitySet lost_entities = - lost_entity_tracker.ComputeLostEntities(); - EXPECT_EQ(lost_entities.size(), 1); - EXPECT_TRUE(lost_entities.find(entity_1) != lost_entities.end()); - EXPECT_TRUE(lost_entities.find(entity_1_copy) != lost_entities.end()); -} - -} // namespace -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/mediums.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/mediums.cc deleted file mode 100644 index 8b0b3100ecf..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/mediums.cc +++ /dev/null @@ -1,33 +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/mediums.h" - -namespace location { -namespace nearby { -namespace connections { - -BluetoothRadio& Mediums::GetBluetoothRadio() { return bluetooth_radio_; } - -BluetoothClassic& Mediums::GetBluetoothClassic() { return bluetooth_classic_; } - -Ble& Mediums::GetBle() { return ble_; } - -WifiLan& Mediums::GetWifiLan() { return wifi_lan_; } - -mediums::WebRtc& Mediums::GetWebRtc() { return webrtc_; } - -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/mediums.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/mediums.h deleted file mode 100644 index 4c6127eb957..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/mediums.h +++ /dev/null @@ -1,69 +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_MEDIUMS_H_ -#define CORE_INTERNAL_MEDIUMS_MEDIUMS_H_ - -#include "core/internal/mediums/ble.h" -#include "core/internal/mediums/bluetooth_classic.h" -#include "core/internal/mediums/bluetooth_radio.h" -#include "core/internal/mediums/webrtc.h" -#include "core/internal/mediums/wifi_lan.h" - -namespace location { -namespace nearby { -namespace connections { - -// Facilitates convenient and reliable usage of various wireless mediums. -class Mediums { - public: - Mediums() = default; - ~Mediums() = default; - - // Returns a handle to the Bluetooth radio. - BluetoothRadio& GetBluetoothRadio(); - - // Returns a handle to the Bluetooth Classic medium. - BluetoothClassic& GetBluetoothClassic(); - - // Returns a handle to the Ble medium. - Ble& GetBle(); - - // Returns a handle to the Wifi-Lan medium. - WifiLan& GetWifiLan(); - - // Returns a handle to the WebRtc medium. - mediums::WebRtc& GetWebRtc(); - - private: - // The order of declaration is critical for both construction and - // destruction. - // - // 1) Construction: The individual mediums have a dependency on the - // corresponding radio, so the radio must be initialized first. - // - // 2) Destruction: The individual mediums should be shut down before the - // corresponding radio. - BluetoothRadio bluetooth_radio_; - BluetoothClassic bluetooth_classic_{bluetooth_radio_}; - Ble ble_{bluetooth_radio_}; - WifiLan wifi_lan_; - mediums::WebRtc webrtc_; -}; - -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_MEDIUMS_H_ diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/utils.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/utils.cc deleted file mode 100644 index 11b581f7710..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/utils.cc +++ /dev/null @@ -1,94 +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/utils.h" - -#include <memory> -#include <string> - -#include "platform/base/prng.h" -#include "platform/public/crypto.h" - -namespace location { -namespace nearby { -namespace connections { - -namespace { -constexpr absl::string_view kUpgradeServiceIdPostfix = "_UPGRADE"; -} - -ByteArray Utils::GenerateRandomBytes(size_t length) { - Prng rng; - std::string data; - data.reserve(length); - - // Adds 4 random bytes per iteration. - while (length > 0) { - std::uint32_t val = rng.NextUint32(); - for (int i = 0; i < 4; i++) { - data += val & 0xFF; - val >>= 8; - length--; - - if (!length) break; - } - } - - return ByteArray(data); -} - -ByteArray Utils::Sha256Hash(const ByteArray& source, size_t length) { - return Utils::Sha256Hash(std::string(source), length); -} - -ByteArray Utils::Sha256Hash(const std::string& source, size_t length) { - ByteArray full_hash(length); - full_hash.CopyAt(0, Crypto::Sha256(source)); - return full_hash; -} - -std::string Utils::WrapUpgradeServiceId(const std::string& service_id) { - if (service_id.empty()) { - return {}; - } - return service_id + std::string(kUpgradeServiceIdPostfix); -} - -std::string Utils::UnwrapUpgradeServiceId( - const std::string& upgrade_service_id) { - auto pos = upgrade_service_id.find(std::string(kUpgradeServiceIdPostfix)); - if (pos != std::string::npos) { - return std::string(upgrade_service_id, 0, pos); - } - return upgrade_service_id; -} - -LocationHint Utils::BuildLocationHint(const std::string& location) { - LocationHint location_hint; - location_hint.set_format(LocationStandard::UNKNOWN); - - if (!location.empty()) { - location_hint.set_location(location); - if (location.at(0) == '+') { - location_hint.set_format(LocationStandard::E164_CALLING); - } else { - location_hint.set_format(LocationStandard::ISO_3166_1_ALPHA_2); - } - } - return location_hint; -} - -} // namespace connections -} // namespace nearby -} // namespace location 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 deleted file mode 100644 index 4a26c4e82c6..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/utils.h +++ /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. - -#ifndef CORE_INTERNAL_MEDIUMS_UTILS_H_ -#define CORE_INTERNAL_MEDIUMS_UTILS_H_ - -#include <memory> -#include <string> - -#include "platform/base/byte_array.h" -#include "proto/connections/offline_wire_formats.pb.h" - -namespace location { -namespace nearby { -namespace connections { - -class Utils { - public: - static ByteArray GenerateRandomBytes(size_t length); - static ByteArray Sha256Hash(const ByteArray& source, size_t length); - static ByteArray Sha256Hash(const std::string& source, size_t length); - static std::string WrapUpgradeServiceId(const std::string& service_id); - static std::string UnwrapUpgradeServiceId(const std::string& service_id); - static LocationHint BuildLocationHint(const std::string& location); -}; - -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_UTILS_H_ diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/uuid.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/uuid.cc deleted file mode 100644 index e3c171598fd..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/uuid.cc +++ /dev/null @@ -1,87 +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/uuid.h" - -#include <iomanip> -#include <sstream> - -#include "platform/public/crypto.h" - -namespace location { -namespace nearby { -namespace connections { -namespace { -std::ostream& write_hex(std::ostream& os, absl::string_view data) { - for (const auto b : data) { - os << std::setfill('0') << std::setw(2) << std::hex - << (static_cast<unsigned int>(b) & 0x0ff); - } - return os; -} -} // namespace - -Uuid::Uuid(absl::string_view data) : data_(Crypto::Md5(data)) { - // Based on the Java counterpart at - // http://androidxref.com/8.0.0_r4/xref/libcore/ojluni/src/main/java/java/util/UUID.java#162. - data_[6] &= 0x0f; // Clear version. - data_[6] |= 0x30; // Set to version 3. - data_[8] &= 0x3f; // Clear variant. - data_[8] |= 0x80; // Set to IETF variant. -} - -Uuid::Uuid(std::uint64_t most_sig_bits, std::uint64_t least_sig_bits) { - // Base on the Java counterpart at - // http://androidxref.com/8.0.0_r4/xref/libcore/ojluni/src/main/java/java/util/UUID.java#104. - data_.reserve(sizeof(most_sig_bits) + sizeof(least_sig_bits)); - - data_[0] = static_cast<char>((most_sig_bits >> 56) & 0x0ff); - data_[1] = static_cast<char>((most_sig_bits >> 48) & 0x0ff); - data_[2] = static_cast<char>((most_sig_bits >> 40) & 0x0ff); - data_[3] = static_cast<char>((most_sig_bits >> 32) & 0x0ff); - data_[4] = static_cast<char>((most_sig_bits >> 24) & 0x0ff); - data_[5] = static_cast<char>((most_sig_bits >> 16) & 0x0ff); - data_[6] = static_cast<char>((most_sig_bits >> 8) & 0x0ff); - data_[7] = static_cast<char>((most_sig_bits >> 0) & 0x0ff); - - data_[8] = static_cast<char>((least_sig_bits >> 56) & 0x0ff); - data_[9] = static_cast<char>((least_sig_bits >> 48) & 0x0ff); - data_[10] = static_cast<char>((least_sig_bits >> 40) & 0x0ff); - data_[11] = static_cast<char>((least_sig_bits >> 32) & 0x0ff); - data_[12] = static_cast<char>((least_sig_bits >> 24) & 0x0ff); - data_[13] = static_cast<char>((least_sig_bits >> 16) & 0x0ff); - data_[14] = static_cast<char>((least_sig_bits >> 8) & 0x0ff); - data_[15] = static_cast<char>((least_sig_bits >> 0) & 0x0ff); -} - -Uuid::operator std::string() const { - // Based on the Java counterpart at - // http://androidxref.com/8.0.0_r4/xref/libcore/ojluni/src/main/java/java/util/UUID.java#375. - std::ostringstream md5_hex; - write_hex(md5_hex, absl::string_view(&data_[0], 4)); - md5_hex << "-"; - write_hex(md5_hex, absl::string_view(&data_[4], 2)); - md5_hex << "-"; - write_hex(md5_hex, absl::string_view(&data_[6], 2)); - md5_hex << "-"; - write_hex(md5_hex, absl::string_view(&data_[8], 2)); - md5_hex << "-"; - write_hex(md5_hex, absl::string_view(&data_[10], 6)); - - return md5_hex.str(); -} - -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/uuid.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/uuid.h deleted file mode 100644 index fec9e071c17..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/uuid.h +++ /dev/null @@ -1,57 +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_UUID_H_ -#define CORE_INTERNAL_MEDIUMS_UUID_H_ - -#include <cstdint> -#include <string> - -#include "absl/strings/string_view.h" - -namespace location { -namespace nearby { -namespace connections { - -// A type 3 name-based -// (https://en.wikipedia.org/wiki/Universally_unique_identifier#Versions_3_and_5_(namespace_name-based)) -// UUID. -// -// https://developer.android.com/reference/java/util/UUID.html -class Uuid final { - public: - Uuid() : Uuid("uuid") {} - explicit Uuid(absl::string_view data); - Uuid(std::uint64_t most_sig_bits, std::uint64_t least_sig_bits); - Uuid(const Uuid&) = default; - Uuid& operator=(const Uuid&) = default; - Uuid(Uuid&&) = default; - Uuid& operator=(Uuid&&) = default; - ~Uuid() = default; - - // Returns the canonical textual representation - // (https://en.wikipedia.org/wiki/Universally_unique_identifier#Format) of the - // UUID. - explicit operator std::string() const; - std::string data() const { return data_; } - - private: - std::string data_; -}; - -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_UUID_H_ diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/uuid_test.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/uuid_test.cc deleted file mode 100644 index f5a8303265d..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/uuid_test.cc +++ /dev/null @@ -1,70 +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/uuid.h" - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "platform/public/crypto.h" -#include "platform/public/logging.h" - -namespace location { -namespace nearby { -namespace connections { -namespace { - -constexpr absl::string_view kString{"some string"}; -constexpr std::uint64_t kNum1 = 0x123456789abcdef0; -constexpr std::uint64_t kNum2 = 0x21436587a9cbed0f; - -TEST(UuidTest, CreateFromStringWithMd5) { - Uuid uuid(kString); - std::string uuid_str(uuid); - std::string uuid_data(uuid.data()); - std::string md5_data(Crypto::Md5(kString)); - NEARBY_LOG(INFO, "MD5-based UUID: '%s'", uuid_str.c_str()); - uuid_data[6] = 0; - uuid_data[8] = 0; - md5_data[6] = 0; - md5_data[8] = 0; - EXPECT_EQ(md5_data, uuid_data); -} - -TEST(UuidTest, CreateFromBinary) { - Uuid uuid(kNum1, kNum2); - std::string uuid_data(uuid.data()); - std::string uuid_str(uuid); - NEARBY_LOG(INFO, "UUID: '%s'", uuid_str.c_str()); - EXPECT_EQ(uuid_data[0], (kNum1 >> 56) & 0xFF); - EXPECT_EQ(uuid_data[1], (kNum1 >> 48) & 0xFF); - EXPECT_EQ(uuid_data[2], (kNum1 >> 40) & 0xFF); - EXPECT_EQ(uuid_data[3], (kNum1 >> 32) & 0xFF); - EXPECT_EQ(uuid_data[4], (kNum1 >> 24) & 0xFF); - EXPECT_EQ(uuid_data[5], (kNum1 >> 16) & 0xFF); - EXPECT_EQ(uuid_data[6], (kNum1 >> 8) & 0xFF); - EXPECT_EQ(uuid_data[7], (kNum1 >> 0) & 0xFF); - EXPECT_EQ(uuid_data[8], (kNum2 >> 56) & 0xFF); - EXPECT_EQ(uuid_data[9], (kNum2 >> 48) & 0xFF); - EXPECT_EQ(uuid_data[10], (kNum2 >> 40) & 0xFF); - EXPECT_EQ(uuid_data[11], (kNum2 >> 32) & 0xFF); - EXPECT_EQ(uuid_data[12], (kNum2 >> 24) & 0xFF); - EXPECT_EQ(uuid_data[13], (kNum2 >> 16) & 0xFF); - EXPECT_EQ(uuid_data[14], (kNum2 >> 8) & 0xFF); - EXPECT_EQ(uuid_data[15], (kNum2 >> 0) & 0xFF); -} - -} // namespace -} // namespace connections -} // namespace nearby -} // 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 deleted file mode 100644 index 1edcf63965a..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc.cc +++ /dev/null @@ -1,744 +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.h" - -#include <functional> -#include <memory> - -#include "absl/functional/bind_front.h" -#include "absl/strings/str_cat.h" -#include "absl/time/time.h" -#include "core/internal/mediums/webrtc/session_description_wrapper.h" -#include "core/internal/mediums/webrtc/signaling_frames.h" -#include "core/internal/mediums/webrtc_socket_wrapper.h" -#include "platform/base/byte_array.h" -#include "platform/base/listeners.h" -#include "platform/public/cancelable_alarm.h" -#include "platform/public/future.h" -#include "platform/public/logging.h" -#include "platform/public/mutex_lock.h" -#include "proto/mediums/web_rtc_signaling_frames.pb.h" -#include "webrtc/api/jsep.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -namespace { - -// The maximum amount of time to wait to connect to a data channel via WebRTC. -constexpr absl::Duration kDataChannelTimeout = absl::Seconds(10); - -// Delay between restarting signaling messenger to receive messages. -constexpr absl::Duration kRestartReceiveMessagesDuration = absl::Seconds(60); - -} // namespace - -WebRtc::WebRtc() = default; - -WebRtc::~WebRtc() { - // This ensures that all pending callbacks are run before we reset the medium - // and we are not accepting new runnables. - single_thread_executor_.Shutdown(); - - // Stop accepting all connections - absl::flat_hash_set<std::string> service_ids; - for (auto& item : accepting_connections_info_) { - service_ids.emplace(item.first); - } - for (const auto& service_id : service_ids) { - StopAcceptingConnections(service_id); - } -} - -const std::string WebRtc::GetDefaultCountryCode() { - return medium_.GetDefaultCountryCode(); -} - -bool WebRtc::IsAvailable() { return medium_.IsValid(); } - -bool WebRtc::IsAcceptingConnections(const std::string& service_id) { - MutexLock lock(&mutex_); - return IsAcceptingConnectionsLocked(service_id); -} - -bool WebRtc::IsAcceptingConnectionsLocked(const std::string& service_id) { - return accepting_connections_info_.contains(service_id); -} - -bool WebRtc::StartAcceptingConnections(const std::string& service_id, - const WebrtcPeerId& self_peer_id, - const LocationHint& location_hint, - AcceptedConnectionCallback callback) { - MutexLock lock(&mutex_); - if (!IsAvailable()) { - NEARBY_LOG(WARNING, - "Cannot start accepting WebRTC connections because WebRTC is " - "not available."); - return false; - } - - if (IsAcceptingConnectionsLocked(service_id)) { - NEARBY_LOG(WARNING, - "Cannot start accepting WebRTC connections because service %s " - "is already accepting WebRTC connections.", - service_id.c_str()); - return false; - } - - // We'll track our state here, so that we're separated from the other services - // who may be also using WebRTC. - AcceptingConnectionsInfo info = AcceptingConnectionsInfo(); - info.self_peer_id = self_peer_id; - info.accepted_connection_callback = callback; - - // Create a new SignalingMessenger so that we can communicate w/ Tachyon. - info.signaling_messenger = - medium_.GetSignalingMessenger(self_peer_id.GetId(), location_hint); - if (!info.signaling_messenger->IsValid()) { - return false; - } - - // This registers ourselves w/ Tachyon, creating a room from the PeerId. - // This allows a remote device to message us over Tachyon. - if (!info.signaling_messenger->StartReceivingMessages( - absl::bind_front(&WebRtc::OnSignalingMessage, this, service_id), - absl::bind_front(&WebRtc::OnSignalingComplete, this, service_id))) { - info.signaling_messenger.reset(); - return false; - } - - // We'll automatically disconnect from Tachyon after 60sec. When this alarm - // fires, we'll recreate our room so we continue to receive messages. - info.restart_tachyon_receive_messages_alarm = CancelableAlarm( - "restart_receiving_messages_webrtc", - std::bind(&WebRtc::ProcessRestartTachyonReceiveMessages, this, - service_id), - kRestartReceiveMessagesDuration, &single_thread_executor_); - - // Now that we're set up to receive messages, we'll save our state and return - // a successful result. - accepting_connections_info_.emplace(service_id, std::move(info)); - NEARBY_LOG(INFO, - "Started listening for WebRTC connections as %s on service %s", - self_peer_id.GetId().c_str(), service_id.c_str()); - return true; -} - -void WebRtc::StopAcceptingConnections(const std::string& service_id) { - MutexLock lock(&mutex_); - if (!IsAcceptingConnectionsLocked(service_id)) { - NEARBY_LOG(WARNING, - "Cannot stop accepting WebRTC connections because service %s " - "is not accepting WebRTC connections.", - service_id.c_str()); - return; - } - - // Grab our info from the map. - auto& info = accepting_connections_info_.find(service_id)->second; - - // Stop receiving messages from Tachyon. - info.signaling_messenger->StopReceivingMessages(); - info.signaling_messenger.reset(); - - // Cancel the scheduled alarm. - if (info.restart_tachyon_receive_messages_alarm.IsValid()) { - info.restart_tachyon_receive_messages_alarm.Cancel(); - info.restart_tachyon_receive_messages_alarm = CancelableAlarm(); - } - - // If we had any in-progress connections that haven't materialized into full - // DataChannels yet, it's time to shut them down since they can't reach us - // anymore. - absl::flat_hash_set<std::string> peer_ids; - for (auto& item : connection_flows_) { - peer_ids.emplace(item.first); - } - for (const auto& peer_id : peer_ids) { - const auto& entry = connection_flows_.find(peer_id); - // Skip outgoing connections in this step. Start/StopAcceptingConnections - // only deals with incoming connections. - if (requesting_connections_info_.contains(peer_id)) { - continue; - } - - // 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->CloseIfNotConnected()) { - continue; - } - - connection_flows_.erase(peer_id); - } - - // Clean up our state. We're now no longer listening for connections. - accepting_connections_info_.erase(service_id); - NEARBY_LOG(INFO, "Stopped listening for WebRTC connections for service %s", - service_id.c_str()); -} - -WebRtcSocketWrapper WebRtc::Connect(const std::string& service_id, - const WebrtcPeerId& remote_peer_id, - const LocationHint& location_hint, - CancellationFlag* cancellation_flag) { - for (int attempts_count = 0; attempts_count < kConnectAttemptsLimit; - attempts_count++) { - auto wrapper_result = AttemptToConnect(service_id, remote_peer_id, - location_hint, cancellation_flag); - if (wrapper_result.IsValid()) { - return wrapper_result; - } - } - return WebRtcSocketWrapper(); -} - -WebRtcSocketWrapper WebRtc::AttemptToConnect( - const std::string& service_id, const WebrtcPeerId& remote_peer_id, - const LocationHint& location_hint, CancellationFlag* cancellation_flag) { - ConnectionRequestInfo info = ConnectionRequestInfo(); - info.self_peer_id = WebrtcPeerId::FromRandom(); - Future<WebRtcSocketWrapper> socket_future = info.socket_future; - - { - MutexLock lock(&mutex_); - if (!IsAvailable()) { - NEARBY_LOG( - WARNING, - "Cannot connect to WebRTC peer %s because WebRTC is not available.", - remote_peer_id.GetId().c_str()); - return WebRtcSocketWrapper(); - } - - if (cancellation_flag->Cancelled()) { - NEARBY_LOGS(INFO) << "Cannot connect with WebRtc due to cancel."; - return WebRtcSocketWrapper(); - } - - // Create a new ConnectionFlow for this connection attempt. - std::unique_ptr<ConnectionFlow> connection_flow = - CreateConnectionFlow(service_id, remote_peer_id); - if (!connection_flow) { - NEARBY_LOG( - INFO, - "Cannot connect to WebRTC peer %s because we failed to create a " - "ConnectionFlow.", - remote_peer_id.GetId().c_str()); - return WebRtcSocketWrapper(); - } - - // Create a new SignalingMessenger so that we can communicate over Tachyon. - info.signaling_messenger = - medium_.GetSignalingMessenger(info.self_peer_id.GetId(), location_hint); - if (!info.signaling_messenger->IsValid()) { - NEARBY_LOG( - INFO, - "Cannot connect to WebRTC peer %s because we failed to create a " - "SignalingMessenger.", - remote_peer_id.GetId().c_str()); - 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 = [socket_future](bool success) mutable { - if (!success) { - socket_future.SetException({Exception::kFailed}); - } - }; - if (!info.signaling_messenger->StartReceivingMessages( - absl::bind_front(&WebRtc::OnSignalingMessage, this, service_id), - signaling_complete_callback)) { - NEARBY_LOG(INFO, - "Cannot connect to WebRTC peer %s because we failed to start " - "receiving messages over Tachyon.", - remote_peer_id.GetId().c_str()); - info.signaling_messenger.reset(); - return WebRtcSocketWrapper(); - } - - // Poke the remote device. This will cause them to send us an Offer. - if (!info.signaling_messenger->SendMessage( - remote_peer_id.GetId(), - webrtc_frames::EncodeReadyForSignalingPoke(info.self_peer_id))) { - NEARBY_LOG(INFO, - "Cannot connect to WebRTC peer %s because we failed to poke " - "the peer over Tachyon.", - remote_peer_id.GetId().c_str()); - info.signaling_messenger.reset(); - return WebRtcSocketWrapper(); - } - - // Create a new ConnectionRequest entry. This map will be used later to look - // up state as we negotiate the connection over Tachyon. - requesting_connections_info_.emplace(remote_peer_id.GetId(), - std::move(info)); - connection_flows_.emplace(remote_peer_id.GetId(), - std::move(connection_flow)); - } - - // Wait for the connection to go through. Don't hold the mutex here so that - // we're not blocking necessary operations. - ExceptionOr<WebRtcSocketWrapper> socket_result = - socket_future.Get(kDataChannelTimeout); - - { - MutexLock lock(&mutex_); - - // Reclaim our info, since we had released ownership while talking to - // Tachyon. - auto& info = - requesting_connections_info_.find(remote_peer_id.GetId())->second; - - // Verify that the connection went through. - if (!socket_result.ok()) { - NEARBY_LOG(INFO, "Failed to connect to WebRTC peer %s.", - remote_peer_id.GetId().c_str()); - RemoveConnectionFlow(remote_peer_id); - info.signaling_messenger.reset(); - requesting_connections_info_.erase(remote_peer_id.GetId()); - return WebRtcSocketWrapper(); - } - - // Clean up our ConnectionRequest. - info.signaling_messenger.reset(); - requesting_connections_info_.erase(remote_peer_id.GetId()); - - // Return the result. - return socket_result.GetResult(); - } -} - -void WebRtc::ProcessLocalIceCandidate( - const std::string& service_id, const WebrtcPeerId& remote_peer_id, - const ::location::nearby::mediums::IceCandidate ice_candidate) { - MutexLock lock(&mutex_); - - // Check first if we have an outgoing request w/ this peer. As this request is - // tied to a specific peer, it takes precedence. - const auto& connection_request_entry = - requesting_connections_info_.find(remote_peer_id.GetId()); - if (connection_request_entry != requesting_connections_info_.end()) { - // Pass the ice candidate to the remote side. - if (!connection_request_entry->second.signaling_messenger->SendMessage( - remote_peer_id.GetId(), - webrtc_frames::EncodeIceCandidates( - connection_request_entry->second.self_peer_id, - {ice_candidate}))) { - NEARBY_LOG(INFO, "Failed to send ice candidate to %s.", - remote_peer_id.GetId().c_str()); - } - - NEARBY_LOG(INFO, "Sent ice candidate to %s.", - remote_peer_id.GetId().c_str()); - return; - } - - // Check next if we're expecting incoming connection requests. - const auto& accepting_connection_entry = - accepting_connections_info_.find(service_id); - if (accepting_connection_entry != accepting_connections_info_.end()) { - // Pass the ice candidate to the remote side. - // TODO(xlythe) Consider not blocking here, since this can eat into the - // connection time - if (!accepting_connection_entry->second.signaling_messenger->SendMessage( - remote_peer_id.GetId(), - webrtc_frames::EncodeIceCandidates( - accepting_connection_entry->second.self_peer_id, - {ice_candidate}))) { - NEARBY_LOG(INFO, "Failed to send ice candidate to %s.", - remote_peer_id.GetId().c_str()); - } - - NEARBY_LOG(INFO, "Sent ice candidate to %s.", - remote_peer_id.GetId().c_str()); - return; - } - - NEARBY_LOG(INFO, - "Skipping restart listening for tachyon inbox messages since we " - "are not accepting connections for service %s.", - service_id.c_str()); -} - -void WebRtc::OnSignalingMessage(const std::string& service_id, - const ByteArray& message) { - OffloadFromThread("rtc-on-signaling-message", [this, service_id, message]() { - ProcessTachyonInboxMessage(service_id, message); - }); -} - -void WebRtc::OnSignalingComplete(const std::string& service_id, bool success) { - NEARBY_LOG(INFO, "Signaling completed with status: %d.", success); - if (success) { - return; - } - - 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()) { - return; - } - - if (info_entry->second.restart_accept_connections_count < - kRestartAcceptConnectionsLimit) { - ++info_entry->second.restart_accept_connections_count; - } else { - return; - } - - RestartTachyonReceiveMessages(service_id); - }); -} - -void WebRtc::ProcessTachyonInboxMessage(const std::string& service_id, - const ByteArray& message) { - MutexLock lock(&mutex_); - - // Attempt to parse the incoming message as a WebRtcSignalingFrame. - location::nearby::mediums::WebRtcSignalingFrame frame; - if (!frame.ParseFromString(std::string(message))) { - NEARBY_LOG(WARNING, "Failed to parse signaling message."); - return; - } - - // Ensure that the frame is valid (no missing fields). - if (!frame.has_sender_id()) { - NEARBY_LOG(WARNING, "Invalid WebRTC frame: Sender ID is missing."); - return; - } - WebrtcPeerId remote_peer_id = WebrtcPeerId(frame.sender_id().id()); - - // Depending on the message type, we'll respond as appropriate. - if (requesting_connections_info_.contains(remote_peer_id.GetId())) { - // This is from a peer we have an outgoing connection request with, so we'll - // only process the Answer path. - if (frame.has_offer()) { - ReceiveOffer(remote_peer_id, - SessionDescriptionWrapper( - webrtc_frames::DecodeOffer(frame).release())); - SendAnswer(remote_peer_id); - } else if (frame.has_ice_candidates()) { - ReceiveIceCandidates(remote_peer_id, - webrtc_frames::DecodeIceCandidates(frame)); - } else { - NEARBY_LOG(INFO, "Received unknown WebRTC frame: ignoring."); - } - } else if (IsAcceptingConnectionsLocked(service_id)) { - // We don't have an outgoing connection request with this peer, but we are - // accepting incoming requests so we'll only process the Offer path. - if (frame.has_ready_for_signaling_poke()) { - SendOffer(service_id, remote_peer_id); - } else if (frame.has_answer()) { - ReceiveAnswer(remote_peer_id, - SessionDescriptionWrapper( - webrtc_frames::DecodeAnswer(frame).release())); - } else if (frame.has_ice_candidates()) { - ReceiveIceCandidates(remote_peer_id, - webrtc_frames::DecodeIceCandidates(frame)); - } else { - NEARBY_LOG(INFO, "Received unknown WebRTC frame: ignoring."); - } - } else { - NEARBY_LOG( - INFO, - "Ignoring Tachyon message since we are not accepting connections."); - } -} - -void WebRtc::SendOffer(const std::string& service_id, - const WebrtcPeerId& remote_peer_id) { - std::unique_ptr<ConnectionFlow> connection_flow = - CreateConnectionFlow(service_id, remote_peer_id); - if (!connection_flow) { - NEARBY_LOG(INFO, - "Unable to send offer. Failed to create a ConnectionFlow."); - return; - } - - SessionDescriptionWrapper offer = connection_flow->CreateOffer(); - if (!offer.IsValid()) { - NEARBY_LOG(INFO, - "Unable to send offer. Failed to create our offer locally."); - RemoveConnectionFlow(remote_peer_id); - return; - } - - const webrtc::SessionDescriptionInterface& sdp = offer.GetSdp(); - if (!connection_flow->SetLocalSessionDescription(offer)) { - NEARBY_LOG(INFO, - "Unable to send offer. Failed to register our offer locally."); - RemoveConnectionFlow(remote_peer_id); - return; - } - - // Grab our info from the map. - auto& info = accepting_connections_info_.find(service_id)->second; - - // Pass the offer to the remote side. - if (!info.signaling_messenger->SendMessage( - remote_peer_id.GetId(), - webrtc_frames::EncodeOffer(info.self_peer_id, sdp))) { - NEARBY_LOG(INFO, - "Unable to send offer. Failed to write the offer to the remote " - "peer %s.", - remote_peer_id.GetId().c_str()); - RemoveConnectionFlow(remote_peer_id); - return; - } - - // Store the ConnectionFlow so that other methods can use it later. - connection_flows_.emplace(remote_peer_id.GetId(), std::move(connection_flow)); - NEARBY_LOG(INFO, "Sent offer to %s.", remote_peer_id.GetId().c_str()); -} - -void WebRtc::ReceiveOffer(const WebrtcPeerId& remote_peer_id, - SessionDescriptionWrapper offer) { - const auto& entry = connection_flows_.find(remote_peer_id.GetId()); - if (entry == connection_flows_.end()) { - NEARBY_LOG(INFO, - "Unable to receive offer. Failed to create a ConnectionFlow."); - return; - } - - if (!entry->second->OnOfferReceived(offer)) { - NEARBY_LOG(INFO, "Unable to receive offer. Failed to process the offer."); - RemoveConnectionFlow(remote_peer_id); - } -} - -void WebRtc::SendAnswer(const WebrtcPeerId& remote_peer_id) { - const auto& entry = connection_flows_.find(remote_peer_id.GetId()); - if (entry == connection_flows_.end()) { - NEARBY_LOG(INFO, - "Unable to send answer. Failed to create a ConnectionFlow."); - return; - } - - SessionDescriptionWrapper answer = entry->second->CreateAnswer(); - if (!answer.IsValid()) { - NEARBY_LOG(INFO, - "Unable to send answer. Failed to create our answer locally."); - RemoveConnectionFlow(remote_peer_id); - return; - } - - const webrtc::SessionDescriptionInterface& sdp = answer.GetSdp(); - if (!entry->second->SetLocalSessionDescription(answer)) { - NEARBY_LOG(INFO, - "Unable to send answer. Failed to register our answer locally."); - RemoveConnectionFlow(remote_peer_id); - return; - } - - // Grab our info from the map. - const auto& connection_request_entry = - requesting_connections_info_.find(remote_peer_id.GetId()); - if (connection_request_entry == requesting_connections_info_.end()) { - NEARBY_LOG(INFO, - "Unable to send answer. Failed to find an outgoing connection " - "request."); - RemoveConnectionFlow(remote_peer_id); - return; - } - - // Pass the answer to the remote side. - if (!connection_request_entry->second.signaling_messenger->SendMessage( - remote_peer_id.GetId(), - webrtc_frames::EncodeAnswer( - connection_request_entry->second.self_peer_id, sdp))) { - NEARBY_LOG( - INFO, - "Unable to send answer. Failed to write the answer to the remote " - "peer %s.", - remote_peer_id.GetId().c_str()); - RemoveConnectionFlow(remote_peer_id); - return; - } - - NEARBY_LOG(INFO, "Sent answer to %s.", remote_peer_id.GetId().c_str()); -} - -void WebRtc::ReceiveAnswer(const WebrtcPeerId& remote_peer_id, - SessionDescriptionWrapper answer) { - const auto& entry = connection_flows_.find(remote_peer_id.GetId()); - if (entry == connection_flows_.end()) { - NEARBY_LOG(INFO, - "Unable to receive answer. Failed to create a ConnectionFlow."); - return; - } - - if (!entry->second->OnAnswerReceived(answer)) { - NEARBY_LOG(INFO, "Unable to receive answer. Failed to process the answer."); - RemoveConnectionFlow(remote_peer_id); - } -} - -void WebRtc::ReceiveIceCandidates( - const WebrtcPeerId& remote_peer_id, - std::vector<std::unique_ptr<webrtc::IceCandidateInterface>> - ice_candidates) { - const auto& entry = connection_flows_.find(remote_peer_id.GetId()); - if (entry == connection_flows_.end()) { - NEARBY_LOG( - INFO, - "Unable to receive ice candidates. Failed to create a ConnectionFlow."); - return; - } - - entry->second->OnRemoteIceCandidatesReceived(std::move(ice_candidates)); -} - -void WebRtc::ProcessRestartTachyonReceiveMessages( - const std::string& service_id) { - MutexLock lock(&mutex_); - RestartTachyonReceiveMessages(service_id); -} - -void WebRtc::RestartTachyonReceiveMessages(const std::string& service_id) { - if (!IsAcceptingConnectionsLocked(service_id)) { - NEARBY_LOG(INFO, - "Skipping restart listening for tachyon inbox messages since we " - "are not accepting connections for service %s.", - service_id.c_str()); - return; - } - - // Grab our info from the map. - auto& info = accepting_connections_info_.find(service_id)->second; - - // Ensure we've disconnected from Tachyon. - info.signaling_messenger->StopReceivingMessages(); - - // Attempt to re-register. - if (!info.signaling_messenger->StartReceivingMessages( - absl::bind_front(&WebRtc::OnSignalingMessage, this, service_id), - absl::bind_front(&WebRtc::OnSignalingComplete, this, service_id))) { - NEARBY_LOG(WARNING, - "Failed to restart listening for tachyon inbox messages for " - "service %s since we failed to reach Tachyon.", - service_id.c_str()); - return; - } - - NEARBY_LOG(INFO, - "Successfully restarted listening for tachyon inbox messages on " - "service %s.", - service_id.c_str()); -} - -void WebRtc::ProcessDataChannelOpen(const std::string& service_id, - const WebrtcPeerId& remote_peer_id, - WebRtcSocketWrapper socket_wrapper) { - MutexLock lock(&mutex_); - - // 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(socket_wrapper); - return; - } - - const auto& accepting_connection_entry = - accepting_connections_info_.find(service_id); - if (accepting_connection_entry != accepting_connections_info_.end()) { - accepting_connection_entry->second.accepted_connection_callback.accepted_cb( - socket_wrapper); - return; - } - - // No one to handle the newly created DataChannel, so we'll just close it. - socket_wrapper.Close(); - NEARBY_LOG(INFO, - "Ignoring new DataChannel because we " - "are not accepting connections for service %s.", - service_id.c_str()); -} - -void WebRtc::ProcessDataChannelClosed(const WebrtcPeerId& remote_peer_id) { - MutexLock lock(&mutex_); - NEARBY_LOG(INFO, - "Data channel has closed, removing connection flow for peer %s.", - remote_peer_id.GetId().c_str()); - - RemoveConnectionFlow(remote_peer_id); -} - -std::unique_ptr<ConnectionFlow> WebRtc::CreateConnectionFlow( - const std::string& service_id, const WebrtcPeerId& remote_peer_id) { - RemoveConnectionFlow(remote_peer_id); - - return ConnectionFlow::Create( - {.local_ice_candidate_found_cb = - {[this, service_id, remote_peer_id]( - const webrtc::IceCandidateInterface* ice_candidate) { - // Note: We need to encode the ice candidate here, before we jump - // off the thread. Otherwise, it gets destroyed and we can't read - // it later. - ::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_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("rtc-channel-closed", [this, remote_peer_id]() { - ProcessDataChannelClosed(remote_peer_id); - }); - }}, - }, - medium_); -} - -void WebRtc::RemoveConnectionFlow(const WebrtcPeerId& remote_peer_id) { - if (!connection_flows_.erase(remote_peer_id.GetId())) { - return; - } - - // 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 = - requesting_connections_info_.find(remote_peer_id.GetId()); - if (connection_request_entry != requesting_connections_info_.end()) { - connection_request_entry->second.socket_future.SetException( - {Exception::kFailed}); - } -} - -void WebRtc::OffloadFromThread(const std::string& name, Runnable runnable) { - single_thread_executor_.Execute(name, std::move(runnable)); -} - -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location 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 deleted file mode 100644 index b5fb959af11..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc.h +++ /dev/null @@ -1,265 +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_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_H_ - -#include <cstddef> -#include <functional> -#include <memory> -#include <string> - -#include "absl/container/flat_hash_map.h" -#include "absl/container/flat_hash_set.h" -#include "core/internal/mediums/webrtc/connection_flow.h" -#include "core/internal/mediums/webrtc/data_channel_listener.h" -#include "core/internal/mediums/webrtc/local_ice_candidate_listener.h" -#include "core/internal/mediums/webrtc/webrtc_socket.h" -#include "core/internal/mediums/webrtc_peer_id.h" -#include "core/internal/mediums/webrtc_socket_wrapper.h" -#include "platform/base/byte_array.h" -#include "platform/base/cancellation_flag.h" -#include "platform/base/listeners.h" -#include "platform/base/runnable.h" -#include "platform/public/atomic_boolean.h" -#include "platform/public/cancelable_alarm.h" -#include "platform/public/future.h" -#include "platform/public/mutex.h" -#include "platform/public/scheduled_executor.h" -#include "platform/public/single_thread_executor.h" -#include "platform/public/webrtc.h" -#include "proto/connections/offline_wire_formats.pb.h" -#include "proto/mediums/web_rtc_signaling_frames.pb.h" -#include "webrtc/api/jsep.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -// Callback that is invoked when a new connection is accepted. -struct AcceptedConnectionCallback { - std::function<void(WebRtcSocketWrapper socket)> accepted_cb = - DefaultCallback<WebRtcSocketWrapper>(); -}; - -// Entry point for connecting a data channel between two devices via WebRtc. -class WebRtc { - public: - WebRtc(); - ~WebRtc(); - - // Gets the default two-letter country code associated with current locale. - // For example, en_US locale resolves to "US". - const std::string GetDefaultCountryCode(); - - // Returns if WebRtc is available as a medium for nearby to transport data. - // Runs on @MainThread. - bool IsAvailable(); - - // Returns if the device is accepting connection with specific service id. - // Runs on @MainThread. - bool IsAcceptingConnections(const std::string& service_id) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Prepares the device to accept incoming WebRtc connections. Returns a - // boolean value indicating if the device has started accepting connections. - // Runs on @MainThread. - bool StartAcceptingConnections(const std::string& service_id, - const WebrtcPeerId& self_peer_id, - const LocationHint& location_hint, - AcceptedConnectionCallback callback) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Try to stop (accepting) the specific connection with provided service id. - // Runs on @MainThread - void StopAcceptingConnections(const std::string& service_id) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Initiates a WebRtc connection with peer device identified by |peer_id| - // with internal retry for maximum attempts of kConnectAttemptsLimit. - // Runs on @MainThread. - WebRtcSocketWrapper Connect(const std::string& service_id, - const WebrtcPeerId& peer_id, - const LocationHint& location_hint, - CancellationFlag* cancellation_flag) - ABSL_LOCKS_EXCLUDED(mutex_); - - private: - static constexpr int kConnectAttemptsLimit = 3; - static constexpr int kRestartAcceptConnectionsLimit = 3; - - enum class Role { - kNone = 0, - kOfferer = 1, - kAnswerer = 2, - }; - - struct AcceptingConnectionsInfo { - // The self_peer_id is generated from the BT/WiFi advertisements and allows - // the scanner to message us over Tachyon. - WebrtcPeerId self_peer_id; - - // The registered callback. When there's an incoming connection, this - // callback is notified. - AcceptedConnectionCallback accepted_connection_callback; - - // Allows us to communicate with the Tachyon web server. - std::unique_ptr<WebRtcSignalingMessenger> signaling_messenger; - - // Restarts the tachyon inbox receives messages streaming rpc if the - // streaming rpc times out. The streaming rpc times out after 60s while - // advertising. Non-null when listening for WebRTC connections as an - // offerer. - CancelableAlarm restart_tachyon_receive_messages_alarm; - - // Tracks the number of times we've restarted receiving messages after a - // failure. We limit the number to prevent endless restarts if we are - // repeatedly unable to communicate with Tachyon. - int restart_accept_connections_count = 0; - }; - - struct ConnectionRequestInfo { - // The self_peer_id is randomly generated and allows the advertiser to - // message us over Tachyon. - WebrtcPeerId self_peer_id; - - // Allows us to communicate with the Tachyon web server. - std::unique_ptr<WebRtcSignalingMessenger> signaling_messenger; - - // The pending DataChannel future. Our client will be blocked on this while - // they wait for us to set up the channel over Tachyon. - Future<WebRtcSocketWrapper> socket_future; - }; - - // Attempt to initiates a WebRtc connection with peer device identified by - // |peer_id|. - // Runs on @MainThread. - WebRtcSocketWrapper AttemptToConnect(const std::string& service_id, - const WebrtcPeerId& peer_id, - const LocationHint& location_hint, - CancellationFlag* cancellation_flag) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Returns if the device is accepting connection with specific service id. - // Runs on @MainThread. - bool IsAcceptingConnectionsLocked(const std::string& service_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Receives a message from the signaling messenger. - void OnSignalingMessage(const std::string& service_id, - const ByteArray& message); - - // Decides whether to restart receiving messages. - void OnSignalingComplete(const std::string& service_id, bool success); - - // Runs on |single_thread_executor_|. - void ProcessTachyonInboxMessage(const std::string& service_id, - const ByteArray& message) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Runs on |single_thread_executor_|. - void SendOffer(const std::string& service_id, - const WebrtcPeerId& remote_peer_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - void ReceiveOffer(const WebrtcPeerId& remote_peer_id, - SessionDescriptionWrapper offer) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - void SendAnswer(const WebrtcPeerId& remote_peer_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - void ReceiveAnswer(const WebrtcPeerId& remote_peer_id, - SessionDescriptionWrapper answer) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - void ReceiveIceCandidates( - const WebrtcPeerId& remote_peer_id, - std::vector<std::unique_ptr<webrtc::IceCandidateInterface>> - ice_candidates) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - std::unique_ptr<ConnectionFlow> CreateConnectionFlow( - const std::string& service_id, const WebrtcPeerId& remote_peer_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - std::unique_ptr<ConnectionFlow> GetConnectionFlow( - const WebrtcPeerId& remote_peer_id) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - void RemoveConnectionFlow(const WebrtcPeerId& remote_peer_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Runs on |single_thread_executor_|. - void ProcessDataChannelOpen(const std::string& service_id, - const WebrtcPeerId& remote_peer_id, - WebRtcSocketWrapper socket_wrapper) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Runs on |single_thread_executor_|. - void ProcessDataChannelClosed(const WebrtcPeerId& remote_peer_id) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Runs on |single_thread_executor_|. - void ProcessLocalIceCandidate( - const std::string& service_id, const WebrtcPeerId& remote_peer_id, - const ::location::nearby::mediums::IceCandidate ice_candidate) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Runs on |single_thread_executor_|. - void ProcessRestartTachyonReceiveMessages(const std::string& service_id) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Runs on |single_thread_executor_|. - void RestartTachyonReceiveMessages(const std::string& service_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - void OffloadFromThread(const std::string& name, Runnable runnable); - - Mutex mutex_; - - WebRtcMedium medium_; - - // The single thread we throw the potentially blocking work on to. - ScheduledExecutor single_thread_executor_; - - // A map of ServiceID -> State for all services that are listening for - // incoming connections. - absl::flat_hash_map<std::string, AcceptingConnectionsInfo> - accepting_connections_info_ ABSL_GUARDED_BY(mutex_); - - // A map of a remote PeerId -> State for pending connection requests. As - // messages from Tachyon come in, this lets us look up the connection request - // info to handle the interaction. - absl::flat_hash_map<std::string, ConnectionRequestInfo> - requesting_connections_info_ ABSL_GUARDED_BY(mutex_); - - // A map of a remote PeerId -> ConnectionFlow. For each connection, we create - // a unique ConnectionFlow. - absl::flat_hash_map<std::string, std::unique_ptr<ConnectionFlow>> - connection_flows_ ABSL_GUARDED_BY(mutex_); -}; - -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_H_ 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 deleted file mode 100644 index 9e13e8b8359..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/BUILD +++ /dev/null @@ -1,99 +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. -licenses(["notice"]) - -cc_library( - name = "webrtc", - srcs = [ - "connection_flow.cc", - "signaling_frames.cc", - ], - hdrs = [ - "connection_flow.h", - "data_channel_listener.h", - "local_ice_candidate_listener.h", - "session_description_wrapper.h", - "signaling_frames.h", - ], - compatible_with = ["//buildenv/target:non_prod"], - copts = ["-DCORE_ADAPTER_DLL"], - visibility = [ - "//core/internal:__subpackages__", - ], - deps = [ - ":data_types", - "//absl/memory", - "//absl/time", - "//core:core_types", - "//core/internal/mediums:utils", - "//platform/base", - "//platform/public:comm", - "//platform/public:logging", - "//platform/public:types", - "//proto/mediums:web_rtc_signaling_frames_cc_proto", - "//webrtc/api:libjingle_peerconnection_api", - "//third_party/webrtc/files/stable/webrtc/pc:peerconnection", - ], -) - -cc_library( - name = "data_types", - srcs = [ - "webrtc_socket.cc", - ], - hdrs = [ - "webrtc_socket.h", - ], - compatible_with = ["//buildenv/target:non_prod"], - copts = ["-DCORE_ADAPTER_DLL"], - visibility = [ - "//core/internal:__subpackages__", - ], - deps = [ - "//core:core_types", - "//platform/base", - "//platform/public:types", - "//webrtc/api:libjingle_peerconnection_api", - ], -) - -cc_test( - name = "webrtc_test", - timeout = "short", - srcs = [ - "connection_flow_test.cc", - "signaling_frames_test.cc", - "webrtc_socket_test.cc", - ], - tags = [ - "notsan", # NOTE(b/139734036): known data race in usrsctplib. - "requires-net:external", - ], - deps = [ - ":data_types", - ":webrtc", - "//net/proto2/compat/public:proto2", - "//testing/base/public:gunit_main", - "//absl/time", - "//core/internal/mediums:utils", - "//platform/base", - "//platform/base:test_util", - "//platform/impl/g3", # buildcleaner: keep - "//platform/public:comm", - "//platform/public:types", - "//webrtc/api:libjingle_peerconnection_api", - "//webrtc/api:rtc_error", - "//webrtc/api:scoped_refptr", - ], -) 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 deleted file mode 100644 index 2906645348f..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/connection_flow.cc +++ /dev/null @@ -1,556 +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/connection_flow.h" - -#include <iterator> -#include <memory> - -#include "absl/memory/memory.h" -#include "absl/time/time.h" -#include "core/internal/mediums/webrtc/session_description_wrapper.h" -#include "core/internal/mediums/webrtc/webrtc_socket.h" -#include "core/internal/mediums/webrtc_socket_wrapper.h" -#include "platform/public/logging.h" -#include "platform/public/mutex_lock.h" -#include "platform/public/webrtc.h" -#include "webrtc/api/data_channel_interface.h" -#include "webrtc/api/jsep.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -constexpr absl::Duration ConnectionFlow::kTimeout; -constexpr absl::Duration ConnectionFlow::kPeerConnectionTimeout; - -// This is the same as the nearby data channel name. -constexpr char kDataChannelName[] = "dataChannel"; - -class CreateSessionDescriptionObserverImpl - : public webrtc::CreateSessionDescriptionObserver { - public: - 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 { - 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}); - } - - private: - ConnectionFlow* connection_flow_; - Future<SessionDescriptionWrapper> settable_future_; - ConnectionFlow::State expected_entry_state_; - ConnectionFlow::State exit_state_; -}; - -class SetDescriptionObserverBase { - public: - ExceptionOr<bool> GetResult(absl::Duration timeout) { - return settable_future_.Get(timeout); - } - - 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: - 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; - -std::unique_ptr<ConnectionFlow> ConnectionFlow::Create( - LocalIceCandidateListener local_ice_candidate_listener, - DataChannelListener data_channel_listener, WebRtcMedium& webrtc_medium) { - auto connection_flow = absl::WrapUnique( - new ConnectionFlow(std::move(local_ice_candidate_listener), - std::move(data_channel_listener))); - if (connection_flow->InitPeerConnection(webrtc_medium)) { - return connection_flow; - } - - return nullptr; -} - -ConnectionFlow::ConnectionFlow( - LocalIceCandidateListener local_ice_candidate_listener, - DataChannelListener data_channel_listener) - : data_channel_listener_(std::move(data_channel_listener)), - local_ice_candidate_listener_(std::move(local_ice_candidate_listener)) {} - -ConnectionFlow::~ConnectionFlow() { - NEARBY_LOG(INFO, "~ConnectionFlow"); - RunOnSignalingThread([this] { CloseOnSignalingThread(); }); - shutdown_latch_.Await(); - NEARBY_LOG(INFO, "~ConnectionFlow done"); -} - -SessionDescriptionWrapper ConnectionFlow::CreateOffer() { - 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; - auto pc = GetPeerConnection(); - CreateSocketFromDataChannel( - pc->CreateDataChannel(kDataChannelName, &data_channel_init)); - - webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options; - rtc::scoped_refptr<CreateSessionDescriptionObserverImpl> observer = - new rtc::RefCountedObject<CreateSessionDescriptionObserverImpl>( - this, success_future, State::kCreatingOffer, - State::kWaitingForAnswer); - pc->CreateOffer(observer, options); -} - -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(); -} - -void ConnectionFlow::CreateAnswerOnSignalingThread( - Future<SessionDescriptionWrapper> success_future) { - if (!TransitionState(State::kReceivedOffer, State::kCreatingAnswer)) { - success_future.SetException({Exception::kFailed}); - return; - } - webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options; - rtc::scoped_refptr<CreateSessionDescriptionObserverImpl> observer = - new rtc::RefCountedObject<CreateSessionDescriptionObserverImpl>( - this, success_future, State::kCreatingAnswer, - State::kWaitingToConnect); - auto pc = GetPeerConnection(); - pc->CreateAnswer(observer, options); -} - -bool ConnectionFlow::SetLocalSessionDescription(SessionDescriptionWrapper sdp) { - CHECK(!IsRunningOnSignalingThread()); - if (!sdp.IsValid()) return false; - - rtc::scoped_refptr<SetLocalDescriptionObserver> observer = - new rtc::RefCountedObject<SetLocalDescriptionObserver>(); - - 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(); - - 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, - State expected_entry_state, - State exit_state) { - if (!sdp.IsValid()) return false; - - rtc::scoped_refptr<SetRemoteDescriptionObserver> observer = - new rtc::RefCountedObject<SetRemoteDescriptionObserver>(); - - 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(); - - 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) { - CHECK(!IsRunningOnSignalingThread()); - return SetRemoteSessionDescription(std::move(offer), State::kInitialized, - State::kReceivedOffer); -} - -bool ConnectionFlow::OnAnswerReceived(SessionDescriptionWrapper answer) { - 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 (!pc) { - return false; - } - 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; -} - -void ConnectionFlow::AddIceCandidatesOnSignalingThread( - std::vector<std::unique_ptr<webrtc::IceCandidateInterface>> - ice_candidates) { - CHECK(IsRunningOnSignalingThread()); - if (state_ == State::kEnded) { - NEARBY_LOG(WARNING, - "You cannot add ice candidates to a disconnected session."); - 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; - } - auto pc = GetPeerConnection(); - for (auto&& ice_candidate : ice_candidates) { - if (!pc->AddIceCandidate(ice_candidate.get())) { - NEARBY_LOG(WARNING, "Unable to add remote ice candidate."); - } - } -} - -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) { - Future<bool> success_future; - // CreatePeerConnection callback may be invoked after ConnectionFlow lifetime - // has ended, in case of a timeout. Future is captured by value, and is safe - // to access, but it is not safe to access ConnectionFlow member variables - // unless the Future::Set() returns true. - webrtc_medium.CreatePeerConnection( - this, - [this, success_future](rtc::scoped_refptr<webrtc::PeerConnectionInterface> - peer_connection) mutable { - if (!peer_connection) { - success_future.Set(false); - return; - } - - // If this fails, means we have already assigned something to - // success_future; it is either: - // 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(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() { - if (state_ != State::kWaitingToConnect && state_ != State::kConnected) return; - auto pc = GetPeerConnection(); - for (auto&& ice_candidate : cached_remote_ice_candidates_) { - if (!pc->AddIceCandidate(ice_candidate.get())) { - NEARBY_LOG(WARNING, "Unable to add remote ice candidate."); - } - } - cached_remote_ice_candidates_.clear(); -} - -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::OnDataChannel( - rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel) { - NEARBY_LOG(INFO, "OnDataChannel"); - CHECK(IsRunningOnSignalingThread()); - CreateSocketFromDataChannel(std::move(data_channel)); -} - -void ConnectionFlow::OnIceGatheringChange( - webrtc::PeerConnectionInterface::IceGatheringState new_state) { - NEARBY_LOG(INFO, "OnIceGatheringChange: %d", new_state); - CHECK(IsRunningOnSignalingThread()); -} - -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(); - } -} - -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, - "Invalid state transition to %d: current state is %d but expected %d.", - new_state, state_, current_state); - return false; - } - NEARBY_LOG(INFO, "Transition: %d -> %d", state_, new_state); - state_ = new_state; - return true; -} - -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; -} - -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; -} - -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 -} // namespace location 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 deleted file mode 100644 index 474a1829bda..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/connection_flow.h +++ /dev/null @@ -1,233 +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_CONNECTION_FLOW_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_CONNECTION_FLOW_H_ - -#include <memory> - -#include "core/internal/mediums/webrtc/data_channel_listener.h" -#include "core/internal/mediums/webrtc/local_ice_candidate_listener.h" -#include "core/internal/mediums/webrtc/session_description_wrapper.h" -#include "core/internal/mediums/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" -#include "webrtc/api/peer_connection_interface.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -/** - * Flow for an offerer: - * - * <ul> - * <li>INITIALIZED: After construction. - * <li>CREATING_OFFER: After CreateOffer(). Local ice candidate collection - * begins. - * <li>WAITING_FOR_ANSWER: Until the remote peer sends their answer. - * <li>WAITING_TO_CONNECT: Until the data channel actually connects. Remote - * ice candidates should be added with OnRemoteIceCandidatesReceived as they are - * gathered. - * <li>CONNECTED: We successfully connected to the remote data - * channel. - * <li>ENDED: The final state that can occur from any of the previous - * states if we disconnect at any point in the flow. - * </ul> - * - * <p>Flow for an answerer: - * - * <ul> - * <li>INITIALIZED: After construction. - * <li>RECEIVED_OFFER: After onOfferReceived(). - * <li>CREATING_ANSWER: After CreateAnswer(). Local ice candidate collection - * begins. - * <li>WAITING_TO_CONNECT: Until the data channel actually connects. - * Remote ice candidates should be added with OnRemoteIceCandidatesReceived as - * they are gathered. - * <li>CONNECTED: We successfully connected to the remote - * data channel. - * <li>ENDED: The final state that can occur from any of the - * previous states if we disconnect at any point in the flow. - * </ul> - */ -class ConnectionFlow : public webrtc::PeerConnectionObserver { - public: - enum class State { - kInitialized, - kCreatingOffer, - kWaitingForAnswer, - kReceivedOffer, - kCreatingAnswer, - kWaitingToConnect, - kConnected, - kEnded, - }; - - // 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() 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 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); - - bool SetRemoteSessionDescription(SessionDescriptionWrapper sdp, - State expected_entry_state, - State exit_state); - - bool CloseOnSignalingThread() ABSL_LOCKS_EXCLUDED(mutex_); - - 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 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_; - - 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_; - // 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 -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_CONNECTION_FLOW_H_ 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 deleted file mode 100644 index dfc98d71f6e..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/connection_flow_test.cc +++ /dev/null @@ -1,407 +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/connection_flow.h" - -#include <memory> -#include <vector> - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "absl/time/time.h" -#include "core/internal/mediums/webrtc/session_description_wrapper.h" -#include "core/internal/mediums/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 "webrtc/api/data_channel_interface.h" -#include "webrtc/api/jsep.h" -#include "webrtc/api/rtc_error.h" -#include "webrtc/api/scoped_refptr.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { -namespace { - -class ConnectionFlowTest : public ::testing::Test { - protected: - ConnectionFlowTest() { - MediumEnvironment::Instance().Stop(); - MediumEnvironment::Instance().Start({.webrtc_enabled = true}); - } -}; - -std::unique_ptr<webrtc::IceCandidateInterface> CopyCandidate( - const webrtc::IceCandidateInterface* candidate) { - return webrtc::CreateIceCandidate(candidate->sdp_mid(), - candidate->sdp_mline_index(), - candidate->candidate()); -} - -// TODO(bfranz) - Add test that deterministically sends answerer_ice_candidates -// before answer is sent. -TEST_F(ConnectionFlowTest, SuccessfulOfferAnswerFlow) { - 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 socket) { - answerer_socket_future.Set(std::move(socket)); - }}, - webrtc_medium_answerer); - ASSERT_NE(answerer, nullptr); - - // Create and send offer - SessionDescriptionWrapper offer = offerer->CreateOffer(); - ASSERT_TRUE(offer.IsValid()); - 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(); - ASSERT_TRUE(answer.IsValid()); - 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(answerer_socket.ok()); - - // Send message on data channel - const char message[] = "Test"; - offerer_socket.result().GetImpl().GetOutputStream().Write( - ByteArray(message, 4)); - ExceptionOr<ByteArray> received_message = - answerer_socket.result().GetImpl().GetInputStream().Read(4); - EXPECT_TRUE(received_message.ok()); - EXPECT_EQ(received_message.result(), ByteArray{message}); -} - -TEST_F(ConnectionFlowTest, CreateAnswerBeforeOfferReceived) { - WebRtcMedium webrtc_medium; - - std::unique_ptr<ConnectionFlow> answerer = ConnectionFlow::Create( - LocalIceCandidateListener(), DataChannelListener(), webrtc_medium); - ASSERT_NE(answerer, nullptr); - - SessionDescriptionWrapper answer = answerer->CreateAnswer(); - EXPECT_FALSE(answer.IsValid()); -} - -TEST_F(ConnectionFlowTest, SetAnswerBeforeOffer) { - WebRtcMedium webrtc_medium_offerer, webrtc_medium_answerer; - - std::unique_ptr<ConnectionFlow> offerer = - ConnectionFlow::Create(LocalIceCandidateListener(), DataChannelListener(), - webrtc_medium_offerer); - ASSERT_NE(offerer, nullptr); - std::unique_ptr<ConnectionFlow> answerer = - ConnectionFlow::Create(LocalIceCandidateListener(), DataChannelListener(), - webrtc_medium_answerer); - ASSERT_NE(answerer, nullptr); - - SessionDescriptionWrapper offer = offerer->CreateOffer(); - ASSERT_TRUE(offer.IsValid()); - EXPECT_EQ(offer.GetType(), webrtc::SdpType::kOffer); - // Did not set offer as local session description - EXPECT_TRUE(answerer->OnOfferReceived(offer)); - - SessionDescriptionWrapper answer = answerer->CreateAnswer(); - ASSERT_TRUE(answer.IsValid()); - EXPECT_EQ(answer.GetType(), webrtc::SdpType::kAnswer); - EXPECT_FALSE(offerer->OnAnswerReceived(answer)); -} - -TEST_F(ConnectionFlowTest, CannotCreateOfferAfterClose) { - WebRtcMedium webrtc_medium; - - std::unique_ptr<ConnectionFlow> offerer = ConnectionFlow::Create( - LocalIceCandidateListener(), DataChannelListener(), webrtc_medium); - ASSERT_NE(offerer, nullptr); - - EXPECT_TRUE(offerer->CloseIfNotConnected()); - - EXPECT_FALSE(offerer->CreateOffer().IsValid()); -} - -TEST_F(ConnectionFlowTest, CannotSetSessionDescriptionAfterClose) { - WebRtcMedium webrtc_medium; - - std::unique_ptr<ConnectionFlow> offerer = ConnectionFlow::Create( - LocalIceCandidateListener(), DataChannelListener(), webrtc_medium); - ASSERT_NE(offerer, nullptr); - - SessionDescriptionWrapper offer = offerer->CreateOffer(); - ASSERT_TRUE(offer.IsValid()); - EXPECT_EQ(offer.GetType(), webrtc::SdpType::kOffer); - - EXPECT_TRUE(offerer->CloseIfNotConnected()); - - EXPECT_FALSE(offerer->SetLocalSessionDescription(offer)); -} - -TEST_F(ConnectionFlowTest, CannotReceiveOfferAfterClose) { - WebRtcMedium webrtc_medium_offerer, webrtc_medium_answerer; - - std::unique_ptr<ConnectionFlow> offerer = - ConnectionFlow::Create(LocalIceCandidateListener(), DataChannelListener(), - webrtc_medium_offerer); - ASSERT_NE(offerer, nullptr); - std::unique_ptr<ConnectionFlow> answerer = - ConnectionFlow::Create(LocalIceCandidateListener(), DataChannelListener(), - webrtc_medium_answerer); - ASSERT_NE(answerer, nullptr); - - EXPECT_TRUE(answerer->CloseIfNotConnected()); - - SessionDescriptionWrapper offer = offerer->CreateOffer(); - ASSERT_TRUE(offer.IsValid()); - EXPECT_EQ(offer.GetType(), webrtc::SdpType::kOffer); - - EXPECT_FALSE(answerer->OnOfferReceived(offer)); -} - -TEST_F(ConnectionFlowTest, NullPeerConnection) { - MediumEnvironment::Instance().SetUseValidPeerConnection( - /*use_valid_peer_connection=*/false); - - WebRtcMedium medium; - std::unique_ptr<ConnectionFlow> answerer = ConnectionFlow::Create( - LocalIceCandidateListener(), DataChannelListener(), medium); - 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(); - ASSERT_TRUE(offer.IsValid()); - 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(); - ASSERT_TRUE(answer.IsValid()); - 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(); - ASSERT_TRUE(offer.IsValid()); - 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(); - ASSERT_TRUE(answer.IsValid()); - 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 -} // namespace nearby -} // namespace location 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 deleted file mode 100644 index 13e6bb5a02e..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/data_channel_listener.h +++ /dev/null @@ -1,43 +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_LISTENER_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_DATA_CHANNEL_LISTENER_H_ - -#include "core/internal/mediums/webrtc_socket_wrapper.h" -#include "core/listeners.h" -#include "platform/base/byte_array.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -// Callbacks from the data channel. -struct DataChannelListener { - // 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<>(); -}; - -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_DATA_CHANNEL_LISTENER_H_ diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/local_ice_candidate_listener.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/local_ice_candidate_listener.h deleted file mode 100644 index 24085193e39..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/local_ice_candidate_listener.h +++ /dev/null @@ -1,39 +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_LOCAL_ICE_CANDIDATE_LISTENER_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_LOCAL_ICE_CANDIDATE_LISTENER_H_ - -#include "core/listeners.h" -#include "webrtc/api/peer_connection_interface.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -// Callbacks from local ice candidate collection. -struct LocalIceCandidateListener { - // Called when a new local ice candidate has been found. - std::function<void(const webrtc::IceCandidateInterface*)> - local_ice_candidate_found_cb = location::nearby::DefaultCallback< - const webrtc::IceCandidateInterface*>(); -}; - -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_LOCAL_ICE_CANDIDATE_LISTENER_H_ diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/session_description_wrapper.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/session_description_wrapper.h deleted file mode 100644 index dd594917348..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/session_description_wrapper.h +++ /dev/null @@ -1,64 +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_SESSION_DESCRIPTION_WRAPPER_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_SESSION_DESCRIPTION_WRAPPER_H_ - -#include "webrtc/api/peer_connection_interface.h" - -// Wrapper object around SessionDescriptionInterface*. -// This object owns the SessionDescriptionInterface* unless Release() has been -// called. -class SessionDescriptionWrapper { - public: - SessionDescriptionWrapper() = default; - explicit SessionDescriptionWrapper(webrtc::SessionDescriptionInterface* sdp) - : impl_(sdp) {} - - // Copy constructor that performs a deep copy, i.e. creates a new - // SessionDescriptionInterface. - SessionDescriptionWrapper(const SessionDescriptionWrapper& sdp) { - if (sdp.IsValid()) { - impl_ = webrtc::CreateSessionDescription(sdp.GetType(), sdp.ToString()); - } - } - - SessionDescriptionWrapper(SessionDescriptionWrapper&&) = default; - SessionDescriptionWrapper& operator=(SessionDescriptionWrapper&&) = default; - - // Release the ownership of the SessionDescriptionInterface*. - webrtc::SessionDescriptionInterface* Release() { return impl_.release(); } - - // Returns a string representation of the sdp. Only call this, if IsValid() is - // true. - std::string ToString() const { - std::string str; - impl_->ToString(&str); - return str; - } - - // Returns the SdpType of the SessionDescriptionInterface. Only call this, if - // IsValid() is true. - webrtc::SdpType GetType() const { return impl_->GetType(); } - - const webrtc::SessionDescriptionInterface& GetSdp() { return *impl_; } - - // Return whether this object currently holds a SessionDescriptionInterface. - bool IsValid() const { return impl_ != nullptr; } - - private: - std::unique_ptr<webrtc::SessionDescriptionInterface> impl_; -}; - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_SESSION_DESCRIPTION_WRAPPER_H_ diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/signaling_frames.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/signaling_frames.cc deleted file mode 100644 index 033c2fac17f..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/signaling_frames.cc +++ /dev/null @@ -1,134 +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/signaling_frames.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { -namespace webrtc_frames { -using WebRtcSignalingFrame = location::nearby::mediums::WebRtcSignalingFrame; - -namespace { - -ByteArray FrameToByteArray(const WebRtcSignalingFrame& signaling_frame) { - std::string message; - signaling_frame.SerializeToString(&message); - return ByteArray(message.c_str(), message.size()); -} - -void SetSenderId(const WebrtcPeerId& sender_id, WebRtcSignalingFrame& frame) { - frame.mutable_sender_id()->set_id(sender_id.GetId()); -} - -std::unique_ptr<webrtc::IceCandidateInterface> DecodeIceCandidate( - location::nearby::mediums::IceCandidate ice_candidate_proto) { - webrtc::SdpParseError error; - return std::unique_ptr<webrtc::IceCandidateInterface>( - webrtc::CreateIceCandidate(ice_candidate_proto.sdp_mid(), - ice_candidate_proto.sdp_m_line_index(), - ice_candidate_proto.sdp(), &error)); -} - -} // namespace - -ByteArray EncodeReadyForSignalingPoke(const WebrtcPeerId& sender_id) { - WebRtcSignalingFrame signaling_frame; - signaling_frame.set_type(WebRtcSignalingFrame::READY_FOR_SIGNALING_POKE_TYPE); - SetSenderId(sender_id, signaling_frame); - signaling_frame.set_allocated_ready_for_signaling_poke( - new location::nearby::mediums::ReadyForSignalingPoke()); - return FrameToByteArray(std::move(signaling_frame)); -} - -ByteArray EncodeOffer(const WebrtcPeerId& sender_id, - const webrtc::SessionDescriptionInterface& offer) { - WebRtcSignalingFrame signaling_frame; - signaling_frame.set_type(WebRtcSignalingFrame::OFFER_TYPE); - SetSenderId(sender_id, signaling_frame); - std::string offer_str; - offer.ToString(&offer_str); - signaling_frame.mutable_offer() - ->mutable_session_description() - ->set_description(offer_str); - return FrameToByteArray(std::move(signaling_frame)); -} - -ByteArray EncodeAnswer(const WebrtcPeerId& sender_id, - const webrtc::SessionDescriptionInterface& answer) { - WebRtcSignalingFrame signaling_frame; - signaling_frame.set_type(WebRtcSignalingFrame::ANSWER_TYPE); - SetSenderId(sender_id, signaling_frame); - std::string answer_str; - answer.ToString(&answer_str); - signaling_frame.mutable_answer() - ->mutable_session_description() - ->set_description(answer_str); - return FrameToByteArray(std::move(signaling_frame)); -} - -ByteArray EncodeIceCandidates( - const WebrtcPeerId& sender_id, - const std::vector<location::nearby::mediums::IceCandidate>& - ice_candidates) { - WebRtcSignalingFrame signaling_frame; - signaling_frame.set_type(WebRtcSignalingFrame::ICE_CANDIDATES_TYPE); - SetSenderId(sender_id, signaling_frame); - for (const auto& ice_candidate : ice_candidates) { - *signaling_frame.mutable_ice_candidates()->add_ice_candidates() = - ice_candidate; - } - return FrameToByteArray(std::move(signaling_frame)); -} - -std::unique_ptr<webrtc::SessionDescriptionInterface> DecodeOffer( - const WebRtcSignalingFrame& frame) { - return webrtc::CreateSessionDescription( - webrtc::SdpType::kOffer, - frame.offer().session_description().description()); -} - -std::unique_ptr<webrtc::SessionDescriptionInterface> DecodeAnswer( - const WebRtcSignalingFrame& frame) { - return webrtc::CreateSessionDescription( - webrtc::SdpType::kAnswer, - frame.answer().session_description().description()); -} - -std::vector<std::unique_ptr<webrtc::IceCandidateInterface>> DecodeIceCandidates( - const WebRtcSignalingFrame& frame) { - std::vector<std::unique_ptr<webrtc::IceCandidateInterface>> ice_candidates; - for (const auto& candidate : frame.ice_candidates().ice_candidates()) { - ice_candidates.push_back(DecodeIceCandidate(candidate)); - } - return ice_candidates; -} - -location::nearby::mediums::IceCandidate EncodeIceCandidate( - const webrtc::IceCandidateInterface& ice_candidate) { - std::string sdp; - ice_candidate.ToString(&sdp); - location::nearby::mediums::IceCandidate ice_candidate_proto; - ice_candidate_proto.set_sdp(sdp); - ice_candidate_proto.set_sdp_mid(ice_candidate.sdp_mid()); - ice_candidate_proto.set_sdp_m_line_index(ice_candidate.sdp_mline_index()); - return ice_candidate_proto; -} - -} // namespace webrtc_frames -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/signaling_frames.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/signaling_frames.h deleted file mode 100644 index 8be6a97b325..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/signaling_frames.h +++ /dev/null @@ -1,58 +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_SIGNALING_FRAMES_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_SIGNALING_FRAMES_H_ - -#include <vector> - -#include "core/internal/mediums/webrtc_peer_id.h" -#include "platform/base/byte_array.h" -#include "proto/mediums/web_rtc_signaling_frames.pb.h" -#include "webrtc/api/peer_connection_interface.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { -namespace webrtc_frames { - -ByteArray EncodeReadyForSignalingPoke(const WebrtcPeerId& sender_id); - -ByteArray EncodeOffer(const WebrtcPeerId& sender_id, - const webrtc::SessionDescriptionInterface& offer); -ByteArray EncodeAnswer(const WebrtcPeerId& sender_id, - const webrtc::SessionDescriptionInterface& answer); - -ByteArray EncodeIceCandidates( - const WebrtcPeerId& sender_id, - const std::vector<location::nearby::mediums::IceCandidate>& ice_candidates); -location::nearby::mediums::IceCandidate EncodeIceCandidate( - const webrtc::IceCandidateInterface& ice_candidate); - -std::unique_ptr<webrtc::SessionDescriptionInterface> DecodeOffer( - const location::nearby::mediums::WebRtcSignalingFrame& frame); -std::unique_ptr<webrtc::SessionDescriptionInterface> DecodeAnswer( - const location::nearby::mediums::WebRtcSignalingFrame& frame); - -std::vector<std::unique_ptr<webrtc::IceCandidateInterface>> DecodeIceCandidates( - const location::nearby::mediums::WebRtcSignalingFrame& frame); - -} // namespace webrtc_frames -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_SIGNALING_FRAMES_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 deleted file mode 100644 index 4105c7b78f3..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/signaling_frames_test.cc +++ /dev/null @@ -1,196 +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/signaling_frames.h" - -#include <memory> - -#include "google/protobuf/text_format.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "core/internal/mediums/webrtc_peer_id.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { -namespace webrtc_frames { - -namespace { - -const char kSampleSdp[] = - "v=0\r\no=- 7859371131 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 " - "0\r\na=msid-semantic: WMS\r\n"; - -const char kIceCandidateSdp1[] = - "a=candidate:1 1 UDP 2130706431 10.0.1.1 8998 typ host"; -const char kIceCandidateSdp2[] = - "a=candidate:2 1 UDP 1694498815 192.0.2.3 45664 typ srflx raddr"; - -const char kIceSdpMid[] = "data"; -const int kIceSdpMLineIndex = 0; - -const char kOfferProto[] = R"( - sender_id { id: "abc" } - type: OFFER_TYPE - offer { - session_description { - description: "v=0\r\no=- 7859371131 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=msid-semantic: WMS\r\n" - } - } - )"; - -const char kAnswerProto[] = R"( - sender_id { id: "abc" } - type: ANSWER_TYPE - answer { - session_description { - description: "v=0\r\no=- 7859371131 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=msid-semantic: WMS\r\n" - } - } - )"; - -const char kIceCandidatesProto[] = R"( - sender_id { id: "abc" } - type: ICE_CANDIDATES_TYPE - ice_candidates { - ice_candidates { - sdp: "candidate:1 1 udp 2130706431 10.0.1.1 8998 typ host generation 0" - sdp_mid: "data" - sdp_m_line_index: 0 - } - ice_candidates { - sdp: "candidate:2 1 udp 1694498815 192.0.2.3 45664 typ srflx generation 0" - sdp_mid: "data" - sdp_m_line_index: 0 - } - } - )"; -} // namespace - -TEST(SignalingFramesTest, SignalingPoke) { - WebrtcPeerId sender_id("abc"); - ByteArray encoded_poke = EncodeReadyForSignalingPoke(sender_id); - - location::nearby::mediums::WebRtcSignalingFrame frame; - frame.ParseFromString(std::string(encoded_poke.data(), encoded_poke.size())); - - 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) { - WebrtcPeerId sender_id("abc"); - std::unique_ptr<webrtc::SessionDescriptionInterface> offer = - webrtc::CreateSessionDescription(webrtc::SdpType::kOffer, kSampleSdp); - ByteArray encoded_offer = EncodeOffer(sender_id, *offer); - - location::nearby::mediums::WebRtcSignalingFrame frame; - frame.ParseFromString( - std::string(encoded_offer.data(), encoded_offer.size())); - - EXPECT_THAT(frame, testing::EqualsProto(kOfferProto)); -} - -TEST(SignaingFramesTest, DecodeValidOffer) { - location::nearby::mediums::WebRtcSignalingFrame frame; - proto2::TextFormat::ParseFromString(kOfferProto, &frame); - std::unique_ptr<webrtc::SessionDescriptionInterface> decoded_offer = - DecodeOffer(frame); - - EXPECT_EQ(webrtc::SdpType::kOffer, decoded_offer->GetType()); - std::string description; - decoded_offer->ToString(&description); - EXPECT_EQ(kSampleSdp, description); -} - -TEST(SignalingFramesTest, EncodeValidAnswer) { - WebrtcPeerId sender_id("abc"); - std::unique_ptr<webrtc::SessionDescriptionInterface> answer( - webrtc::CreateSessionDescription(webrtc::SdpType::kAnswer, kSampleSdp)); - ByteArray encoded_answer = EncodeAnswer(sender_id, *answer); - - location::nearby::mediums::WebRtcSignalingFrame frame; - frame.ParseFromString( - std::string(encoded_answer.data(), encoded_answer.size())); - - EXPECT_THAT(frame, testing::EqualsProto(kAnswerProto)); -} - -TEST(SignalingFramesTest, DecodeValidAnswer) { - location::nearby::mediums::WebRtcSignalingFrame frame; - proto2::TextFormat::ParseFromString(kAnswerProto, &frame); - std::unique_ptr<webrtc::SessionDescriptionInterface> decoded_answer = - DecodeAnswer(frame); - - EXPECT_EQ(webrtc::SdpType::kAnswer, decoded_answer->GetType()); - std::string description; - decoded_answer->ToString(&description); - EXPECT_EQ(kSampleSdp, description); -} - -TEST(SignalingFramesTest, EncodeValidIceCandidates) { - WebrtcPeerId sender_id("abc"); - webrtc::SdpParseError error; - - std::vector<std::unique_ptr<webrtc::IceCandidateInterface>> ice_candidates; - ice_candidates.emplace_back(webrtc::CreateIceCandidate( - kIceSdpMid, kIceSdpMLineIndex, kIceCandidateSdp1, &error)); - ice_candidates.emplace_back(webrtc::CreateIceCandidate( - kIceSdpMid, kIceSdpMLineIndex, kIceCandidateSdp2, &error)); - std::vector<location::nearby::mediums::IceCandidate> encoded_candidates_vec; - for (const auto& ice_candidate : ice_candidates) { - encoded_candidates_vec.push_back(EncodeIceCandidate(*ice_candidate)); - } - ByteArray encoded_candidates = - EncodeIceCandidates(sender_id, encoded_candidates_vec); - - location::nearby::mediums::WebRtcSignalingFrame frame; - frame.ParseFromString( - std::string(encoded_candidates.data(), encoded_candidates.size())); - - EXPECT_THAT(frame, testing::EqualsProto(kIceCandidatesProto)); -} - -TEST(SignalingFramesTest, DecodeValidIceCandidates) { - webrtc::SdpParseError error; - std::vector<std::unique_ptr<webrtc::IceCandidateInterface>> ice_candidates; - ice_candidates.emplace_back(webrtc::CreateIceCandidate( - kIceSdpMid, kIceSdpMLineIndex, kIceCandidateSdp1, &error)); - ice_candidates.emplace_back(webrtc::CreateIceCandidate( - kIceSdpMid, kIceSdpMLineIndex, kIceCandidateSdp2, &error)); - - location::nearby::mediums::WebRtcSignalingFrame frame; - proto2::TextFormat::ParseFromString(kIceCandidatesProto, &frame); - std::vector<std::unique_ptr<webrtc::IceCandidateInterface>> - decoded_candidates = DecodeIceCandidates(frame); - - ASSERT_EQ(2u, decoded_candidates.size()); - for (int i = 0; i < static_cast<int>(decoded_candidates.size()); i++) { - EXPECT_TRUE(ice_candidates[i]->candidate().IsEquivalent( - decoded_candidates[i]->candidate())); - EXPECT_EQ(ice_candidates[i]->sdp_mid(), decoded_candidates[i]->sdp_mid()); - EXPECT_EQ(ice_candidates[i]->sdp_mline_index(), - decoded_candidates[i]->sdp_mline_index()); - } -} - -} // namespace webrtc_frames -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location 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 deleted file mode 100644 index 0e4f34babab..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket.cc +++ /dev/null @@ -1,190 +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/webrtc_socket.h" - -#include "platform/public/logging.h" -#include "platform/public/mutex_lock.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -// OutputStreamImpl -Exception WebRtcSocket::OutputStreamImpl::Write(const ByteArray& data) { - if (data.size() > kMaxDataSize) { - NEARBY_LOG(WARNING, "Sending data larger than 1MB"); - return {Exception::kIo}; - } - - socket_->BlockUntilSufficientSpaceInBuffer(data.size()); - - if (socket_->IsClosed()) { - NEARBY_LOG(WARNING, "Tried sending message while socket is closed"); - return {Exception::kIo}; - } - - if (!socket_->SendMessage(data)) { - NEARBY_LOG(INFO, "Unable to write data to socket."); - return {Exception::kIo}; - } - return {Exception::kSuccess}; -} - -Exception WebRtcSocket::OutputStreamImpl::Flush() { - // Java implementation is empty. - return {Exception::kSuccess}; -} - -Exception WebRtcSocket::OutputStreamImpl::Close() { - socket_->Close(); - return {Exception::kSuccess}; -} - -// WebRtcSocket -WebRtcSocket::WebRtcSocket( - const std::string& name, - rtc::scoped_refptr<webrtc::DataChannelInterface> 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; - - 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(); - NEARBY_LOGS(INFO) << "WebRtcSocket::Close(" << name_ << ") this: " << this - << " done"; -} - -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)) { - OffloadFromSignalingThread([this] { ClosePipe(); }); - } - break; - } -} -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::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( - webrtc::DataBuffer(std::string(data.data(), data.size()))); -} - -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"; -} - -// Must not be called on signalling thread. -void WebRtcSocket::WakeUpWriter() { - MutexLock lock(&backpressure_mutex_); - buffer_variable_.Notify(); -} - -void WebRtcSocket::SetSocketListener(SocketListener&& listener) { - socket_listener_ = std::move(listener); -} - -void WebRtcSocket::BlockUntilSufficientSpaceInBuffer(int length) { - MutexLock lock(&backpressure_mutex_); - while (!IsClosed() && - (data_channel_->buffered_amount() + length > kMaxDataSize)) { - // TODO(himanshujaju): Add wait with timeout. - buffer_variable_.Wait(); - } -} - -void WebRtcSocket::OffloadFromSignalingThread(Runnable runnable) { - single_thread_executor_.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/webrtc_socket.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket.h deleted file mode 100644 index a65f2d5d9ed..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket.h +++ /dev/null @@ -1,123 +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_WEBRTC_SOCKET_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_SOCKET_H_ - -#include <memory> - -#include "core/listeners.h" -#include "platform/base/input_stream.h" -#include "platform/base/output_stream.h" -#include "platform/base/socket.h" -#include "platform/public/atomic_boolean.h" -#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 { -namespace mediums { - -// Maximum data size: 1 MB -constexpr int kMaxDataSize = 1 * 1024 * 1024; - -// Defines the Socket implementation specific to WebRTC, which uses the WebRTC -// data channel to send and receive messages. -// -// Messages are buffered here to prevent the data channel from overflowing, -// which could lead to data loss. -class WebRtcSocket : public Socket, public webrtc::DataChannelObserver { - public: - WebRtcSocket(const std::string& name, - rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel); - ~WebRtcSocket() override; - - WebRtcSocket(const WebRtcSocket& other) = delete; - WebRtcSocket& operator=(const WebRtcSocket& other) = delete; - - // Overrides for location::nearby::Socket: - InputStream& GetInputStream() override; - OutputStream& GetOutputStream() override; - void Close() override; - - // 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 SetSocketListener(SocketListener&& listener); - - private: - class OutputStreamImpl : public OutputStream { - public: - explicit OutputStreamImpl(WebRtcSocket* const socket) : socket_(socket) {} - ~OutputStreamImpl() override = default; - - OutputStreamImpl(const OutputStreamImpl& other) = delete; - OutputStreamImpl& operator=(const OutputStreamImpl& other) = delete; - - // OutputStream: - Exception Write(const ByteArray& data) override; - Exception Flush() override; - Exception Close() override; - - private: - // |this| OutputStreamImpl is owned by |socket_|. - WebRtcSocket* const 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_; - - Pipe pipe_; - - OutputStreamImpl output_stream_{this}; - - AtomicBoolean closed_{false}; - - 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 -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_SOCKET_H_ 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 deleted file mode 100644 index 135a63345db..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc/webrtc_socket_test.cc +++ /dev/null @@ -1,234 +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/webrtc_socket.h" - -#include <memory> - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "platform/base/byte_array.h" -#include "webrtc/api/data_channel_interface.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -namespace { - -// using TestPlatform = platform::ImplementationPlatform; - -const char kSocketName[] = "TestSocket"; - -class MockDataChannel - : public rtc::RefCountedObject<webrtc::DataChannelInterface> { - public: - MOCK_METHOD(void, RegisterObserver, (webrtc::DataChannelObserver*)); - MOCK_METHOD(void, UnregisterObserver, ()); - - MOCK_METHOD(std::string, label, (), (const)); - - MOCK_METHOD(bool, reliable, (), (const)); - MOCK_METHOD(int, id, (), (const)); - MOCK_METHOD(DataState, state, (), (const)); - MOCK_METHOD(uint32_t, messages_sent, (), (const)); - MOCK_METHOD(uint64_t, bytes_sent, (), (const)); - MOCK_METHOD(uint32_t, messages_received, (), (const)); - MOCK_METHOD(uint64_t, bytes_received, (), (const)); - - MOCK_METHOD(uint64_t, buffered_amount, (), (const)); - - MOCK_METHOD(void, Close, ()); - - MOCK_METHOD(bool, Send, (const webrtc::DataBuffer&)); -}; - -} // namespace - -TEST(WebRtcSocketTest, ReadFromSocket) { - const char* message = "message"; - rtc::scoped_refptr<MockDataChannel> mock_data_channel = new MockDataChannel(); - WebRtcSocket webrtc_socket(kSocketName, mock_data_channel); - - webrtc_socket.OnMessage(webrtc::DataBuffer{message}); - ExceptionOr<ByteArray> result = webrtc_socket.GetInputStream().Read(7); - EXPECT_TRUE(result.ok()); - 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.OnMessage(webrtc::DataBuffer{"Me"}); - webrtc_socket.OnMessage(webrtc::DataBuffer{"ssa"}); - webrtc_socket.OnMessage(webrtc::DataBuffer{"ge"}); - - ExceptionOr<ByteArray> result; - - // This behaviour is different from the Java code - result = webrtc_socket.GetInputStream().Read(7); - EXPECT_TRUE(result.ok()); - EXPECT_EQ(result.result(), ByteArray{"Me"}); - - result = webrtc_socket.GetInputStream().Read(7); - EXPECT_TRUE(result.ok()); - EXPECT_EQ(result.result(), ByteArray{"ssa"}); - - result = webrtc_socket.GetInputStream().Read(7); - EXPECT_TRUE(result.ok()); - EXPECT_EQ(result.result(), ByteArray{"ge"}); -} - -TEST(WebRtcSocketTest, WriteToSocket) { - const ByteArray kMessage{"Message"}; - rtc::scoped_refptr<MockDataChannel> mock_data_channel = new MockDataChannel(); - WebRtcSocket webrtc_socket(kSocketName, mock_data_channel); - - EXPECT_CALL(*mock_data_channel, Send(testing::_)) - .WillRepeatedly(testing::Return(true)); - EXPECT_TRUE(webrtc_socket.GetOutputStream().Write(kMessage).Ok()); -} - -TEST(WebRtcSocketTest, SendDataBiggerThanMax) { - const ByteArray kMessage{kMaxDataSize + 1}; - rtc::scoped_refptr<MockDataChannel> mock_data_channel = new MockDataChannel(); - WebRtcSocket webrtc_socket(kSocketName, mock_data_channel); - - EXPECT_CALL(*mock_data_channel, Send(testing::_)).Times(0); - EXPECT_EQ(webrtc_socket.GetOutputStream().Write(kMessage), - Exception{Exception::kIo}); -} - -TEST(WebRtcSocketTest, WriteToDataChannelFails) { - ByteArray kMessage{"Message"}; - rtc::scoped_refptr<MockDataChannel> mock_data_channel = new MockDataChannel(); - WebRtcSocket webrtc_socket(kSocketName, mock_data_channel); - - ON_CALL(*mock_data_channel, Send(testing::_)) - .WillByDefault(testing::Return(false)); - EXPECT_EQ(webrtc_socket.GetOutputStream().Write(kMessage), - Exception{Exception::kIo}); -} - -TEST(WebRtcSocketTest, Close) { - rtc::scoped_refptr<MockDataChannel> mock_data_channel = new MockDataChannel(); - WebRtcSocket webrtc_socket(kSocketName, mock_data_channel); - - EXPECT_CALL(*mock_data_channel, Close()); - - int socket_closed_cb_called = 0; - - 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); -} - -TEST(WebRtcSocketTest, WriteOnClosedChannel) { - ByteArray kMessage{"Message"}; - rtc::scoped_refptr<MockDataChannel> mock_data_channel = new MockDataChannel(); - WebRtcSocket webrtc_socket(kSocketName, mock_data_channel); - webrtc_socket.Close(); - - EXPECT_CALL(*mock_data_channel, Send(testing::_)).Times(0); - EXPECT_EQ(webrtc_socket.GetOutputStream().Write(kMessage), - Exception{Exception::kIo}); -} - -TEST(WebRtcSocketTest, ReadFromClosedChannel) { - ByteArray kMessage{"Message"}; - rtc::scoped_refptr<MockDataChannel> mock_data_channel = new MockDataChannel(); - WebRtcSocket webrtc_socket(kSocketName, mock_data_channel); - ON_CALL(*mock_data_channel, Send(testing::_)) - .WillByDefault(testing::Return(true)); - - webrtc_socket.GetOutputStream().Write(kMessage); - webrtc_socket.Close(); - - 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 -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc_peer_id.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc_peer_id.cc deleted file mode 100644 index 9360357c2e2..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc_peer_id.cc +++ /dev/null @@ -1,54 +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_id.h" - -#include <sstream> - -#include "absl/strings/ascii.h" -#include "absl/strings/escaping.h" -#include "core/internal/mediums/utils.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -namespace { -constexpr int kPeerIdLength = 64; - -std::string BytesToStringUppercase(const ByteArray& bytes) { - std::string hex_string( - absl::BytesToHexString(std::string(bytes.data(), bytes.size()))); - absl::AsciiStrToUpper(&hex_string); - return hex_string; -} -} // namespace - -WebrtcPeerId WebrtcPeerId::FromRandom() { - return FromSeed(Utils::GenerateRandomBytes(kPeerIdLength)); -} - -WebrtcPeerId WebrtcPeerId::FromSeed(const ByteArray& seed) { - ByteArray full_hash(Utils::Sha256Hash(seed, kPeerIdLength)); - ByteArray hashed_seed(full_hash.data(), kPeerIdLength / 2); - return WebrtcPeerId(BytesToStringUppercase(hashed_seed)); -} - -bool WebrtcPeerId::IsValid() const { return !id_.empty(); } - -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc_peer_id.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc_peer_id.h deleted file mode 100644 index d2331b5a0d9..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc_peer_id.h +++ /dev/null @@ -1,52 +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_ID_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_PEER_ID_H_ - -#include <memory> -#include <string> - -#include "platform/base/byte_array.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -// WebrtcPeerId is used as an identifier to exchange SDP messages to establish -// WebRTC p2p connection. An empty WebrtcPeerId is considered to be invalid. -class WebrtcPeerId { - public: - WebrtcPeerId() = default; - explicit WebrtcPeerId(const std::string& id) : id_(id) {} - ~WebrtcPeerId() = default; - - static WebrtcPeerId FromRandom(); - static WebrtcPeerId FromSeed(const ByteArray& seed); - - bool IsValid() const; - - const std::string& GetId() const { return id_; } - - private: - std::string id_; -}; - -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_PEER_ID_H_ diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc_peer_id_test.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc_peer_id_test.cc deleted file mode 100644 index 612d213c023..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc_peer_id_test.cc +++ /dev/null @@ -1,56 +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_id.h" - -#include <memory> - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "platform/base/byte_array.h" -#include "platform/public/crypto.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -TEST(WebrtcPeerIdTest, GenerateRandomPeerId) { - WebrtcPeerId peer_id = WebrtcPeerId::FromRandom(); - EXPECT_EQ(64, peer_id.GetId().size()); -} - -TEST(WebrtcPeerIdTest, GenerateFromSeed) { - // Values calculated by running actual SHA-256 hash on |seed|. - std::string seed = "seed"; - std::string expected_peer_id = - "19B25856E1C150CA834CFFC8B59B23ADBD0EC0389E58EB22B3B64768098D002B"; - - ByteArray seed_bytes(seed); - WebrtcPeerId peer_id = WebrtcPeerId::FromSeed(seed_bytes); - - EXPECT_EQ(64, peer_id.GetId().size()); - EXPECT_EQ(expected_peer_id, peer_id.GetId()); -} - -TEST(WebrtcPeerIdTest, GetId) { - const std::string id = "this_is_a_test"; - WebrtcPeerId peer_id(id); - EXPECT_EQ(id, peer_id.GetId()); -} - -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc_socket_wrapper.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc_socket_wrapper.h deleted file mode 100644 index bc4671136b5..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc_socket_wrapper.h +++ /dev/null @@ -1,55 +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_SOCKET_WRAPPER_H_ -#define CORE_INTERNAL_MEDIUMS_WEBRTC_SOCKET_WRAPPER_H_ - -#include <memory> - -#include "core/internal/mediums/webrtc/webrtc_socket.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -class WebRtcSocketWrapper final { - public: - WebRtcSocketWrapper() = default; - WebRtcSocketWrapper(const WebRtcSocketWrapper&) = default; - WebRtcSocketWrapper& operator=(const WebRtcSocketWrapper&) = default; - explicit WebRtcSocketWrapper(std::unique_ptr<WebRtcSocket> socket) - : impl_(socket.release()) {} - ~WebRtcSocketWrapper() = default; - - InputStream& GetInputStream() { return impl_->GetInputStream(); } - - OutputStream& GetOutputStream() { return impl_->GetOutputStream(); } - - void Close() { return impl_->Close(); } - - bool IsValid() const { return impl_ != nullptr; } - - WebRtcSocket& GetImpl() { return *impl_; } - - private: - std::shared_ptr<WebRtcSocket> impl_; -}; - -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_SOCKET_WRAPPER_H_ 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 deleted file mode 100644 index 863e6ef7310..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/webrtc_test.cc +++ /dev/null @@ -1,405 +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.h" - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "core/internal/mediums/webrtc_socket_wrapper.h" -#include "platform/base/listeners.h" -#include "platform/base/medium_environment.h" -#include "platform/public/mutex_lock.h" - -namespace location { -namespace nearby { -namespace connections { -namespace mediums { - -namespace { - -using FeatureFlags = FeatureFlags::Flags; - -constexpr FeatureFlags kTestCases[] = { - FeatureFlags{ - .enable_cancellation_flag = true, - }, - FeatureFlags{ - .enable_cancellation_flag = false, - }, -}; - -class WebRtcTest : public ::testing::TestWithParam<FeatureFlags> { - protected: - using MockAcceptedCallback = - testing::MockFunction<void(WebRtcSocketWrapper socket)>; - - WebRtcTest() { env_.Stop(); } - - MediumEnvironment& env_{MediumEnvironment::Instance()}; -}; - -// Tests the flow when the two devices exchange SDP messages and connect to each -// other but the signaling channel is closed before sending the data. -TEST_P(WebRtcTest, ConnectBothDevices_ShutdownSignaling_SendData) { - env_.Start({.webrtc_enabled = true}); - FeatureFlags feature_flags = GetParam(); - env_.SetFeatureFlags(feature_flags); - WebRtc receiver, sender; - WebRtcSocketWrapper receiver_socket, sender_socket; - const WebrtcPeerId self_id("self_id"); - const std::string service_id("NearbySharing"); - LocationHint location_hint; - Future<bool> connected; - ByteArray message("message xyz"); - - receiver.StartAcceptingConnections( - service_id, self_id, location_hint, - {[&receiver_socket, connected](WebRtcSocketWrapper wrapper) mutable { - receiver_socket = wrapper; - connected.Set(receiver_socket.IsValid()); - }}); - - CancellationFlag flag; - sender_socket = sender.Connect(service_id, self_id, location_hint, &flag); - EXPECT_TRUE(sender_socket.IsValid()); - - ExceptionOr<bool> devices_connected = connected.Get(); - ASSERT_TRUE(devices_connected.ok()); - EXPECT_TRUE(devices_connected.result()); - - // Only shuts down signaling channel. - receiver.StopAcceptingConnections(service_id); - - sender_socket.GetOutputStream().Write(message); - ExceptionOr<ByteArray> received_msg = - receiver_socket.GetInputStream().Read(/*size=*/32); - ASSERT_TRUE(received_msg.ok()); - EXPECT_EQ(message, received_msg.result()); - env_.Stop(); -} - -TEST_P(WebRtcTest, CanCancelConnect) { - env_.Start({.webrtc_enabled = true}); - FeatureFlags feature_flags = GetParam(); - env_.SetFeatureFlags(feature_flags); - WebRtc receiver, sender; - WebRtcSocketWrapper receiver_socket, sender_socket; - const WebrtcPeerId self_id("self_id"); - const std::string service_id("NearbySharing"); - LocationHint location_hint; - Future<bool> connected; - ByteArray message("message"); - - receiver.StartAcceptingConnections( - service_id, self_id, location_hint, - {[&receiver_socket, connected](WebRtcSocketWrapper wrapper) mutable { - receiver_socket = wrapper; - connected.Set(receiver_socket.IsValid()); - }}); - - CancellationFlag flag(true); - sender_socket = sender.Connect(service_id, self_id, location_hint, &flag); - // If FeatureFlag is disabled, Cancelled is false as no-op. - if (!feature_flags.enable_cancellation_flag) { - EXPECT_TRUE(sender_socket.IsValid()); - - ExceptionOr<bool> devices_connected = connected.Get(); - ASSERT_TRUE(devices_connected.ok()); - EXPECT_TRUE(devices_connected.result()); - - sender_socket.GetOutputStream().Write(message); - ExceptionOr<ByteArray> received_msg = - receiver_socket.GetInputStream().Read(/*size=*/32); - ASSERT_TRUE(received_msg.ok()); - EXPECT_EQ(message, received_msg.result()); - - receiver_socket.Close(); - } else { - EXPECT_FALSE(sender_socket.IsValid()); - } - env_.Stop(); -} - -INSTANTIATE_TEST_SUITE_P(ParametrisedWebRtcTest, WebRtcTest, - ::testing::ValuesIn(kTestCases)); - -// Basic test to check that device is accepting connections when initialized. -TEST_F(WebRtcTest, NotAcceptingConnections) { - env_.Start({.webrtc_enabled = true}); - WebRtc webrtc; - ASSERT_TRUE(webrtc.IsAvailable()); - EXPECT_FALSE(webrtc.IsAcceptingConnections(std::string{})); - env_.Stop(); -} - -// Tests the flow when the device tries to accept connections twice. In this -// case, only the first call is successful and subsequent calls fail. -TEST_F(WebRtcTest, StartAcceptingConnectionTwice) { - env_.Start({.webrtc_enabled = true}); - testing::StrictMock<MockAcceptedCallback> mock_accepted_callback_; - WebRtc webrtc; - WebrtcPeerId self_id("peer_id"); - const std::string service_id("NearbySharing"); - LocationHint location_hint{}; - - ASSERT_TRUE(webrtc.IsAvailable()); - ASSERT_TRUE(webrtc.StartAcceptingConnections( - service_id, self_id, location_hint, - {mock_accepted_callback_.AsStdFunction()})); - EXPECT_FALSE(webrtc.StartAcceptingConnections( - service_id, self_id, location_hint, - {mock_accepted_callback_.AsStdFunction()})); - EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id)); - EXPECT_FALSE(webrtc.IsAcceptingConnections(std::string{})); - env_.Stop(); -} - -// Tests the flow when the device tries to connect but there is no peer -// accepting connections at the given peer ID. -TEST_F(WebRtcTest, Connect_NoPeer) { - env_.Start({.webrtc_enabled = true}); - WebRtc webrtc; - WebrtcPeerId peer_id("peer_id"); - const std::string service_id("NearbySharing"); - LocationHint location_hint; - - ASSERT_TRUE(webrtc.IsAvailable()); - CancellationFlag flag; - WebRtcSocketWrapper wrapper_1 = - webrtc.Connect(service_id, peer_id, location_hint, &flag); - EXPECT_FALSE(wrapper_1.IsValid()); - - EXPECT_TRUE(webrtc.StartAcceptingConnections( - service_id, peer_id, location_hint, AcceptedConnectionCallback())); - env_.Stop(); -} - -// Tests the flow when the device calls Connect() after calling -// StartAcceptingConnections() without StopAcceptingConnections(). -TEST_F(WebRtcTest, StartAcceptingConnection_ThenConnect) { - env_.Start({.webrtc_enabled = true}); - testing::StrictMock<MockAcceptedCallback> mock_accepted_callback_; - WebRtc webrtc; - WebrtcPeerId self_id("peer_id"); - const std::string service_id("NearbySharing"); - LocationHint location_hint; - - ASSERT_TRUE(webrtc.IsAvailable()); - ASSERT_TRUE(webrtc.StartAcceptingConnections( - service_id, self_id, location_hint, - {mock_accepted_callback_.AsStdFunction()})); - CancellationFlag flag; - WebRtcSocketWrapper wrapper = webrtc.Connect( - service_id, WebrtcPeerId("random_peer_id"), location_hint, &flag); - EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id)); - EXPECT_FALSE(wrapper.IsValid()); - EXPECT_FALSE(webrtc.StartAcceptingConnections( - service_id, self_id, location_hint, - {mock_accepted_callback_.AsStdFunction()})); - env_.Stop(); -} - -// Tests the flow when the device calls StartAcceptingConnections but the medium -// is closed before a peer device can connect to it. -TEST_F(WebRtcTest, StartAndStopAcceptingConnections) { - env_.Start({.webrtc_enabled = true}); - testing::StrictMock<MockAcceptedCallback> mock_accepted_callback_; - WebRtc webrtc; - WebrtcPeerId self_id("peer_id"); - const std::string service_id("NearbySharing"); - LocationHint location_hint; - - ASSERT_TRUE(webrtc.IsAvailable()); - ASSERT_TRUE(webrtc.StartAcceptingConnections( - service_id, self_id, location_hint, - {mock_accepted_callback_.AsStdFunction()})); - EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id)); - webrtc.StopAcceptingConnections(service_id); - EXPECT_FALSE(webrtc.IsAcceptingConnections(service_id)); - env_.Stop(); -} - -// Tests the flow when the device tries to connect to two different peers -// without disconnecting in between. -TEST_F(WebRtcTest, ConnectTwice) { - env_.Start({.webrtc_enabled = true}); - WebRtc receiver, sender, device_c; - WebRtcSocketWrapper receiver_socket, sender_socket; - const WebrtcPeerId self_id("self_id"), other_id("other_id"); - const std::string service_id("NearbySharing"); - LocationHint location_hint; - Future<bool> connected; - ByteArray message("message xyz"); - - receiver.StartAcceptingConnections( - service_id, self_id, location_hint, - {[&receiver_socket, connected](WebRtcSocketWrapper wrapper) mutable { - receiver_socket = wrapper; - connected.Set(receiver_socket.IsValid()); - }}); - - device_c.StartAcceptingConnections(service_id, other_id, location_hint, - {[](WebRtcSocketWrapper wrapper) {}}); - - CancellationFlag flag; - sender_socket = sender.Connect(service_id, self_id, location_hint, &flag); - EXPECT_TRUE(sender_socket.IsValid()); - - ExceptionOr<bool> devices_connected = connected.Get(); - ASSERT_TRUE(devices_connected.ok()); - EXPECT_TRUE(devices_connected.result()); - - WebRtcSocketWrapper socket = - sender.Connect(service_id, other_id, location_hint, &flag); - EXPECT_TRUE(socket.IsValid()); - socket.Close(); - - EXPECT_TRUE(receiver_socket.IsValid()); - EXPECT_TRUE(sender_socket.IsValid()); - - sender_socket.GetOutputStream().Write(message); - ExceptionOr<ByteArray> received_msg = - receiver_socket.GetInputStream().Read(/*size=*/32); - ASSERT_TRUE(received_msg.ok()); - EXPECT_EQ(message, received_msg.result()); - - receiver_socket.Close(); - env_.Stop(); -} - -// Tests the flow when the two devices exchange SDP messages and connect to each -// other but disconnect before being able to send/receive the actual data. -TEST_F(WebRtcTest, ConnectBothDevicesAndAbort) { - env_.Start({.webrtc_enabled = true}); - WebRtc receiver, sender; - WebRtcSocketWrapper receiver_socket, sender_socket; - const WebrtcPeerId self_id("self_id"); - const std::string service_id("NearbySharing"); - LocationHint location_hint; - Future<bool> connected; - ByteArray message("message xyz"); - - receiver.StartAcceptingConnections( - service_id, self_id, location_hint, - {[&receiver_socket, connected](WebRtcSocketWrapper wrapper) mutable { - receiver_socket = wrapper; - connected.Set(receiver_socket.IsValid()); - }}); - - CancellationFlag flag; - sender_socket = sender.Connect(service_id, self_id, location_hint, &flag); - EXPECT_TRUE(sender_socket.IsValid()); - - ExceptionOr<bool> devices_connected = connected.Get(); - ASSERT_TRUE(devices_connected.ok()); - EXPECT_TRUE(devices_connected.result()); - - receiver_socket.Close(); - env_.Stop(); -} - -// Tests the flow when the two devices exchange SDP messages and connect to each -// other and the actual data is exchanged successfully between the devices. -TEST_F(WebRtcTest, ConnectBothDevicesAndSendData) { - env_.Start({.webrtc_enabled = true}); - WebRtc receiver, sender; - WebRtcSocketWrapper receiver_socket, sender_socket; - const WebrtcPeerId self_id("self_id"); - const std::string service_id("NearbySharing"); - LocationHint location_hint; - Future<bool> connected; - ByteArray message("message"); - - receiver.StartAcceptingConnections( - service_id, self_id, location_hint, - {[&receiver_socket, connected](WebRtcSocketWrapper wrapper) mutable { - receiver_socket = wrapper; - connected.Set(receiver_socket.IsValid()); - }}); - - CancellationFlag flag; - sender_socket = sender.Connect(service_id, self_id, location_hint, &flag); - EXPECT_TRUE(sender_socket.IsValid()); - - ExceptionOr<bool> devices_connected = connected.Get(); - ASSERT_TRUE(devices_connected.ok()); - EXPECT_TRUE(devices_connected.result()); - - sender_socket.GetOutputStream().Write(message); - ExceptionOr<ByteArray> received_msg = - receiver_socket.GetInputStream().Read(/*size=*/32); - ASSERT_TRUE(received_msg.ok()); - EXPECT_EQ(message, received_msg.result()); - - receiver_socket.Close(); - env_.Stop(); -} - -TEST_F(WebRtcTest, Connect_NullPeerConnection) { - env_.Start({.webrtc_enabled = true}); - testing::StrictMock<MockAcceptedCallback> mock_accepted_callback_; - env_.SetUseValidPeerConnection( - /*use_valid_peer_connection=*/false); - - WebRtc webrtc; - const std::string service_id("NearbySharing"); - WebrtcPeerId self_id("peer_id"); - LocationHint location_hint; - - ASSERT_TRUE(webrtc.IsAvailable()); - CancellationFlag flag; - WebRtcSocketWrapper wrapper = webrtc.Connect( - service_id, WebrtcPeerId("random_peer_id"), location_hint, &flag); - EXPECT_FALSE(wrapper.IsValid()); - env_.Stop(); -} - -// Tests the flow when the device calls StartAcceptingConnections and the -// receive messages stream fails. -TEST_F(WebRtcTest, ContinueAcceptingConnectionsOnComplete) { - env_.Start({.webrtc_enabled = true}); - testing::StrictMock<MockAcceptedCallback> mock_accepted_callback_; - WebRtc webrtc; - WebrtcPeerId self_id("peer_id"); - const std::string service_id("NearbySharing"); - LocationHint location_hint; - - ASSERT_TRUE(webrtc.IsAvailable()); - ASSERT_TRUE(webrtc.StartAcceptingConnections( - service_id, self_id, location_hint, - {mock_accepted_callback_.AsStdFunction()})); - EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id)); - - // Simulate a failure in receiving messages stream, WebRtc should restart - // accepting connections. - env_.SendWebRtcSignalingComplete(self_id.GetId(), - /*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); - EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id)); - - webrtc.StopAcceptingConnections(service_id); - EXPECT_FALSE(webrtc.IsAcceptingConnections(service_id)); - env_.Stop(); -} - -} // namespace - -} // namespace mediums -} // namespace connections -} // namespace nearby -} // namespace location 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 deleted file mode 100644 index 9e24c5fe2e3..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/wifi_lan.cc +++ /dev/null @@ -1,409 +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/wifi_lan.h" - -#include <memory> -#include <string> -#include <utility> - -#include "absl/strings/str_format.h" -#include "core/internal/mediums/utils.h" -#include "platform/public/logging.h" -#include "platform/public/mutex_lock.h" - -namespace location { -namespace nearby { -namespace connections { - -WifiLan::~WifiLan() { - // Destructor is not taking locks, but methods it is calling are. - while (!discovering_info_.service_ids.empty()) { - StopDiscovery(*discovering_info_.service_ids.begin()); - } - while (!server_sockets_.empty()) { - StopAcceptingConnections(server_sockets_.begin()->first); - } - while (!advertising_info_.nsd_service_infos.empty()) { - StopAdvertising(advertising_info_.nsd_service_infos.begin()->first); - } - - // All the AcceptLoopRunnable objects in here should already have gotten an - // opportunity to shut themselves down cleanly in the calls to - // StopAcceptingConnections() above. - accept_loops_runner_.Shutdown(); -} - -bool WifiLan::IsAvailable() const { - MutexLock lock(&mutex_); - - return IsAvailableLocked(); -} - -bool WifiLan::IsAvailableLocked() const { return medium_.IsValid(); } - -bool WifiLan::StartAdvertising(const std::string& service_id, - NsdServiceInfo& nsd_service_info) { - MutexLock lock(&mutex_); - - if (!IsAvailableLocked()) { - NEARBY_LOGS(INFO) - << "Can't turn on WifiLan advertising. WifiLan is not available."; - return false; - } - - if (!nsd_service_info.IsValid()) { - NEARBY_LOGS(INFO) - << "Refusing to turn on WifiLan advertising. nsd_service_info is not " - "valid."; - return false; - } - - if (IsAdvertisingLocked(service_id)) { - NEARBY_LOGS(INFO) - << "Failed to WifiLan advertise because we're already advertising."; - return false; - } - - if (!IsAcceptingConnectionsLocked(service_id)) { - NEARBY_LOGS(INFO) - << "Failed to turn on WifiLan advertising with nsd_service_info=" - << &nsd_service_info - << ", service_name=" << nsd_service_info.GetServiceName() - << ", service_id=" << service_id - << ". Should accept connections before advertising."; - return false; - } - - nsd_service_info.SetServiceType(GenerateServiceType(service_id)); - const auto& it = server_sockets_.find(service_id); - if (it != server_sockets_.end()) { - nsd_service_info.SetIPAddress(it->second.GetIPAddress()); - nsd_service_info.SetPort(it->second.GetPort()); - } - if (!medium_.StartAdvertising(nsd_service_info)) { - NEARBY_LOGS(INFO) - << "Failed to turn on WifiLan advertising with nsd_service_info=" - << &nsd_service_info - << ", service_name=" << nsd_service_info.GetServiceName() - << ", service_id=" << service_id; - return false; - } - - NEARBY_LOGS(INFO) << "Turned on WifiLan advertising with nsd_service_info=" - << &nsd_service_info - << ", service_name=" << nsd_service_info.GetServiceName() - << ", service_id=" << service_id; - advertising_info_.Add(service_id, std::move(nsd_service_info)); - return true; -} - -bool WifiLan::StopAdvertising(const std::string& service_id) { - MutexLock lock(&mutex_); - - if (!IsAdvertisingLocked(service_id)) { - NEARBY_LOGS(INFO) - << "Can't turn off WifiLan advertising; it is already off"; - return false; - } - - NEARBY_LOGS(INFO) << "Turned off WifiLan advertising with service_id=" - << service_id; - bool ret = - medium_.StopAdvertising(*advertising_info_.GetServiceInfo(service_id)); - // Reset our bundle of advertising state to mark that we're no longer - // advertising for specific service_id. - advertising_info_.Remove(service_id); - return ret; -} - -bool WifiLan::IsAdvertising(const std::string& service_id) { - MutexLock lock(&mutex_); - - return IsAdvertisingLocked(service_id); -} - -bool WifiLan::IsAdvertisingLocked(const std::string& service_id) { - return advertising_info_.Existed(service_id); -} - -bool WifiLan::StartDiscovery(const std::string& service_id, - DiscoveredServiceCallback callback) { - MutexLock lock(&mutex_); - - if (service_id.empty()) { - NEARBY_LOGS(INFO) - << "Refusing to start WifiLan discovering with empty service_id."; - return false; - } - - if (!IsAvailableLocked()) { - NEARBY_LOGS(INFO) - << "Can't discover WifiLan services because WifiLan isn't available."; - return false; - } - - if (IsDiscoveringLocked(service_id)) { - NEARBY_LOGS(INFO) - << "Refusing to start discovery of WifiLan services because another " - "discovery is already in-progress."; - return false; - } - - std::string service_type = GenerateServiceType(service_id); - bool ret = medium_.StartDiscovery(service_id, service_type, callback); - if (!ret) { - NEARBY_LOGS(INFO) << "Failed to start discovery of WifiLan services."; - return false; - } - - NEARBY_LOGS(INFO) << "Turned on WifiLan discovering with service_id=" - << service_id; - // Mark the fact that we're currently performing a WifiLan discovering. - discovering_info_.Add(service_id); - return true; -} - -bool WifiLan::StopDiscovery(const std::string& service_id) { - MutexLock lock(&mutex_); - - if (!IsDiscoveringLocked(service_id)) { - NEARBY_LOGS(INFO) - << "Can't turn off WifiLan discovering because we never started " - "discovering."; - return false; - } - - std::string service_type = GenerateServiceType(service_id); - NEARBY_LOGS(INFO) << "Turned off WifiLan discovering with service_id=" - << service_id << ", service_type=" << service_type; - bool ret = medium_.StopDiscovery(service_type); - discovering_info_.Remove(service_id); - return ret; -} - -bool WifiLan::IsDiscovering(const std::string& service_id) { - MutexLock lock(&mutex_); - return IsDiscoveringLocked(service_id); -} - -bool WifiLan::IsDiscoveringLocked(const std::string& service_id) { - return discovering_info_.Existed(service_id); -} - -bool WifiLan::StartAcceptingConnections(const std::string& service_id, - AcceptedConnectionCallback callback) { - MutexLock lock(&mutex_); - - if (service_id.empty()) { - NEARBY_LOGS(INFO) << "Refusing to start accepting WifiLan connections; " - "service_id is empty."; - return false; - } - - if (!IsAvailableLocked()) { - NEARBY_LOGS(INFO) - << "Can't start accepting WifiLan connections [service_id=" - << service_id << "]; WifiLan not available."; - return false; - } - - if (IsAcceptingConnectionsLocked(service_id)) { - NEARBY_LOGS(INFO) - << "Refusing to start accepting WifiLan connections [service=" - << service_id - << "]; WifiLan server is already in-progress with the same name."; - return false; - } - - // We can generate an exact port here on server socket; now we just assign 0 - // to let platform medium decide it. - int port = 0; - WifiLanServerSocket server_socket = medium_.ListenForService(port); - if (!server_socket.IsValid()) { - NEARBY_LOGS(INFO) - << "Failed to start accepting WifiLan connections for service_id=" - << service_id; - return false; - } - - // Mark the fact that there's an in-progress WifiLan server accepting - // connections. - auto owned_server_socket = - server_sockets_.insert({service_id, std::move(server_socket)}) - .first->second; - - // 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( - "wifi-lan-accept", - [callback = std::move(callback), - server_socket = std::move(owned_server_socket)]() mutable { - while (true) { - WifiLanSocket client_socket = server_socket.Accept(); - if (!client_socket.IsValid()) { - server_socket.Close(); - break; - } - callback.accepted_cb(std::move(client_socket)); - } - }); - - return true; -} - -bool WifiLan::StopAcceptingConnections(const std::string& service_id) { - MutexLock lock(&mutex_); - - if (service_id.empty()) { - NEARBY_LOGS(INFO) << "Unable to stop accepting WifiLan connections because " - "the service_id is empty."; - return false; - } - - const auto& it = server_sockets_.find(service_id); - if (it == server_sockets_.end()) { - NEARBY_LOGS(INFO) << "Can't stop accepting WifiLan connections for " - << service_id << " because it was never started."; - return false; - } - - // Closing the WifiLanServerSocket will kick off the suicide of the thread - // in accept_loops_thread_pool_ that blocks on WifiLanServerSocket.accept(). - // That may take some time to complete, but there's no particular reason to - // wait around for it. - auto item = server_sockets_.extract(it); - - // Store a handle to the WifiLanServerSocket, so we can use it after - // removing the entry from server_sockets_; making it scoped - // is a bonus that takes care of deallocation before we leave this method. - WifiLanServerSocket& listening_socket = item.mapped(); - - // Regardless of whether or not we fail to close the existing - // WifiLanServerSocket, remove it from server_sockets_ so that it - // frees up this service for another round. - - // Finally, close the WifiLanServerSocket. - if (!listening_socket.Close().Ok()) { - NEARBY_LOGS(INFO) << "Failed to close WifiLan server socket for service_id=" - << service_id; - return false; - } - - return true; -} - -bool WifiLan::IsAcceptingConnections(const std::string& service_id) { - MutexLock lock(&mutex_); - return IsAcceptingConnectionsLocked(service_id); -} - -bool WifiLan::IsAcceptingConnectionsLocked(const std::string& service_id) { - return server_sockets_.find(service_id) != server_sockets_.end(); -} - -WifiLanSocket WifiLan::Connect(const std::string& service_id, - const NsdServiceInfo& service_info, - CancellationFlag* cancellation_flag) { - MutexLock lock(&mutex_); - // Socket to return. To allow for NRVO to work, it has to be a single object. - WifiLanSocket socket; - - if (service_id.empty()) { - NEARBY_LOGS(INFO) << "Refusing to create client WifiLan socket because " - "service_id is empty."; - return socket; - } - - if (!IsAvailableLocked()) { - NEARBY_LOGS(INFO) << "Can't create client WifiLan socket [service_id=" - << service_id << "]; WifiLan isn't available."; - return socket; - } - - if (cancellation_flag->Cancelled()) { - NEARBY_LOGS(INFO) << "Can't create client WifiLan socket due to cancel."; - return socket; - } - - socket = medium_.ConnectToService(service_info, cancellation_flag); - if (!socket.IsValid()) { - NEARBY_LOGS(INFO) << "Failed to Connect via WifiLan [service_id=" - << service_id << "]"; - } - - return socket; -} - -WifiLanSocket WifiLan::Connect(const std::string& service_id, - const std::string& ip_address, int port, - CancellationFlag* cancellation_flag) { - MutexLock lock(&mutex_); - // Socket to return. To allow for NRVO to work, it has to be a single object. - WifiLanSocket socket; - - if (service_id.empty()) { - NEARBY_LOGS(INFO) << "Refusing to create client WifiLan socket because " - "service_id is empty."; - return socket; - } - - if (!IsAvailableLocked()) { - NEARBY_LOGS(INFO) << "Can't create client WifiLan socket [service_id=" - << service_id << "]; WifiLan isn't available."; - return socket; - } - - if (cancellation_flag->Cancelled()) { - NEARBY_LOGS(INFO) << "Can't create client WifiLan socket due to cancel."; - return socket; - } - - socket = medium_.ConnectToService(ip_address, port, cancellation_flag); - if (!socket.IsValid()) { - NEARBY_LOGS(INFO) << "Failed to Connect via WifiLan [service_id=" - << service_id << "]"; - } - - return socket; -} - -std::pair<std::string, int> WifiLan::GetCredentials( - const std::string& service_id) { - MutexLock lock(&mutex_); - const auto& it = server_sockets_.find(service_id); - if (it == server_sockets_.end()) { - return std::pair<std::string, int>(); - } - return std::pair<std::string, int>(it->second.GetIPAddress(), - it->second.GetPort()); -} - -std::string WifiLan::GenerateServiceType(const std::string& service_id) { - std::string service_id_hash_string; - - const ByteArray service_id_hash = Utils::Sha256Hash( - service_id, NsdServiceInfo::kTypeFromServiceIdHashLength); - for (auto byte : std::string(service_id_hash)) { - absl::StrAppend(&service_id_hash_string, absl::StrFormat("%02X", byte)); - } - - return absl::StrFormat(NsdServiceInfo::kNsdTypeFormat, - service_id_hash_string); -} - -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/wifi_lan.h b/chromium/third_party/nearby/src/cpp/core/internal/mediums/wifi_lan.h deleted file mode 100644 index dc5300f7d1f..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/wifi_lan.h +++ /dev/null @@ -1,194 +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_WIFI_LAN_H_ -#define CORE_INTERNAL_MEDIUMS_WIFI_LAN_H_ - -#include <cstdint> -#include <string> - -#include "absl/container/flat_hash_map.h" -#include "absl/container/flat_hash_set.h" -#include "platform/base/byte_array.h" -#include "platform/base/cancellation_flag.h" -#include "platform/base/nsd_service_info.h" -#include "platform/public/multi_thread_executor.h" -#include "platform/public/mutex.h" -#include "platform/public/wifi_lan.h" - -namespace location { -namespace nearby { -namespace connections { - -class WifiLan { - public: - using DiscoveredServiceCallback = WifiLanMedium::DiscoveredServiceCallback; - - // Callback that is invoked when a new connection is accepted. - struct AcceptedConnectionCallback { - std::function<void(WifiLanSocket socket)> accepted_cb = - DefaultCallback<WifiLanSocket>(); - }; - - WifiLan() = default; - ~WifiLan(); - - // Returns true, if WifiLan communications are supported by a platform. - bool IsAvailable() const ABSL_LOCKS_EXCLUDED(mutex_); - - // Sets custom service info name, endpoint info name in NsdServiceInfo and - // then enables WifiLan advertising. - // Returns true, if NsdServiceInfo is successfully set, and false otherwise. - bool StartAdvertising(const std::string& service_id, - NsdServiceInfo& nsd_service_info) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Disables WifiLan advertising. - // Returns false if no successful call StartAdvertising() was previously - // made, otherwise returns true. - bool StopAdvertising(const std::string& service_id) - ABSL_LOCKS_EXCLUDED(mutex_); - - bool IsAdvertising(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_); - - // Enables WifiLan discovery. Will report any discoverable services - // through a callback. - // Returns true, if discovery was enabled, false otherwise. - bool StartDiscovery(const std::string& service_id, - DiscoveredServiceCallback callback) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Disables WifiLan discovery. - bool StopDiscovery(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_); - - bool IsDiscovering(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_); - - // Starts a worker thread, creates a WifiLan socket, associates it with a - // service id. - bool StartAcceptingConnections(const std::string& service_id, - AcceptedConnectionCallback callback) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Closes socket corresponding to a service id. - bool StopAcceptingConnections(const std::string& service_id) - ABSL_LOCKS_EXCLUDED(mutex_); - - bool IsAcceptingConnections(const std::string& service_id) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Establishes connection to WifiLan service that was might be started on - // another service with StartAcceptingConnections() using the same service_id. - // Blocks until connection is established, or server-side is terminated. - // Returns socket instance. On success, WifiLanSocket.IsValid() return true. - WifiLanSocket Connect(const std::string& service_id, - const NsdServiceInfo& service_info, - CancellationFlag* cancellation_flag) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Establishes connection to WifiLan service by ip address and port for - // bandwidth upgradation. - // Returns socket instance. On success, WifiLanSocket.IsValid() return true. - WifiLanSocket Connect(const std::string& service_id, - const std::string& ip_address, int port, - CancellationFlag* cancellation_flag) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Gets ip address + port for remote services on the network to identify and - // connect to this service. - // - // Credential is for the currently-hosted Wifi ServerSocket (if any). - std::pair<std::string, int> GetCredentials(const std::string& service_id) - ABSL_LOCKS_EXCLUDED(mutex_); - - private: - struct AdvertisingInfo { - bool Empty() const { return nsd_service_infos.empty(); } - void Clear() { nsd_service_infos.clear(); } - void Add(const std::string& service_id, - const NsdServiceInfo& nsd_service_info) { - nsd_service_infos.insert({service_id, nsd_service_info}); - } - void Remove(const std::string& service_id) { - nsd_service_infos.erase(service_id); - } - bool Existed(const std::string& service_id) const { - return nsd_service_infos.contains(service_id); - } - NsdServiceInfo* GetServiceInfo(const std::string& service_id) { - const auto& it = nsd_service_infos.find(service_id); - if (it == nsd_service_infos.end()) { - return nullptr; - } - return &it->second; - } - - absl::flat_hash_map<std::string, NsdServiceInfo> nsd_service_infos; - }; - - struct DiscoveringInfo { - bool Empty() const { return service_ids.empty(); } - void Clear() { service_ids.clear(); } - void Add(const std::string& service_id) { service_ids.insert(service_id); } - void Remove(const std::string& service_id) { - service_ids.erase(service_id); - } - bool Existed(const std::string& service_id) const { - return service_ids.contains(service_id); - } - - absl::flat_hash_set<std::string> service_ids; - }; - - static constexpr int kMaxConcurrentAcceptLoops = 5; - - // Same as IsAvailable(), but must be called with mutex_ held. - bool IsAvailableLocked() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Same as IsAdvertising(), but must be called with mutex_ held. - bool IsAdvertisingLocked(const std::string& service_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Same as IsDiscovering(), but must be called with mutex_ held. - bool IsDiscoveringLocked(const std::string& service_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Same as IsAcceptingConnections(), but must be called with mutex_ held. - bool IsAcceptingConnectionsLocked(const std::string& service_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Generates mDNS type. - std::string GenerateServiceType(const std::string& service_id); - - mutable Mutex mutex_; - WifiLanMedium medium_ ABSL_GUARDED_BY(mutex_); - AdvertisingInfo advertising_info_ ABSL_GUARDED_BY(mutex_); - DiscoveringInfo discovering_info_ ABSL_GUARDED_BY(mutex_); - - // A thread pool dedicated to running all the accept loops from - // StartAcceptingConnections(). - MultiThreadExecutor accept_loops_runner_{kMaxConcurrentAcceptLoops}; - - // A map of service_id -> ServerSocket. If map is non-empty, we - // are currently listening for incoming connections. - // WifiLanServerSocket instances are used from accept_loops_runner_, - // and thus require pointer stability. - absl::flat_hash_map<std::string, WifiLanServerSocket> server_sockets_ - ABSL_GUARDED_BY(mutex_); -}; - -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_WIFI_LAN_H_ diff --git a/chromium/third_party/nearby/src/cpp/core/internal/mediums/wifi_lan_test.cc b/chromium/third_party/nearby/src/cpp/core/internal/mediums/wifi_lan_test.cc deleted file mode 100644 index 4640363b98d..00000000000 --- a/chromium/third_party/nearby/src/cpp/core/internal/mediums/wifi_lan_test.cc +++ /dev/null @@ -1,347 +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/wifi_lan.h" - -#include <string> - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "absl/strings/string_view.h" -#include "platform/base/medium_environment.h" -#include "platform/base/nsd_service_info.h" -#include "platform/public/count_down_latch.h" -#include "platform/public/logging.h" -#include "platform/public/wifi_lan.h" - -namespace location { -namespace nearby { -namespace connections { -namespace { - -using FeatureFlags = FeatureFlags::Flags; - -constexpr FeatureFlags kTestCases[] = { - FeatureFlags{ - .enable_cancellation_flag = true, - }, - FeatureFlags{ - .enable_cancellation_flag = false, - }, -}; - -constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000); -constexpr absl::string_view kServiceID{"com.google.location.nearby.apps.test"}; -constexpr absl::string_view kServiceInfoName{"ServiceInfoName"}; -constexpr absl::string_view kEndpointName{"EndpointName"}; -constexpr absl::string_view kEndpointInfoKey{"n"}; - -class WifiLanTest : public ::testing::TestWithParam<FeatureFlags> { - protected: - using DiscoveredServiceCallback = WifiLanMedium::DiscoveredServiceCallback; - - WifiLanTest() { env_.Stop(); } - - MediumEnvironment& env_{MediumEnvironment::Instance()}; -}; - -TEST_P(WifiLanTest, CanConnect) { - FeatureFlags feature_flags = GetParam(); - env_.SetFeatureFlags(feature_flags); - env_.Start(); - WifiLan wifi_lan_client; - WifiLan wifi_lan_server; - std::string service_id(kServiceID); - std::string service_info_name(kServiceInfoName); - std::string endpoint_info_name(kEndpointName); - CountDownLatch discovered_latch(1); - CountDownLatch accept_latch(1); - - WifiLanSocket socket_for_server; - EXPECT_TRUE(wifi_lan_server.StartAcceptingConnections( - service_id, - { - .accepted_cb = - [&socket_for_server, &accept_latch](WifiLanSocket socket) { - socket_for_server = std::move(socket); - accept_latch.CountDown(); - }, - })); - - NsdServiceInfo nsd_service_info; - nsd_service_info.SetServiceName(service_info_name); - nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), - endpoint_info_name); - wifi_lan_server.StartAdvertising(service_id, nsd_service_info); - - NsdServiceInfo discovered_service_info; - wifi_lan_client.StartDiscovery( - service_id, - { - .service_discovered_cb = - [&discovered_latch, &discovered_service_info]( - NsdServiceInfo service_info, const std::string& service_id) { - NEARBY_LOGS(INFO) - << "Discovered service_info=" << &service_info; - discovered_service_info = service_info; - discovered_latch.CountDown(); - }, - }); - discovered_latch.Await(kWaitDuration).result(); - ASSERT_TRUE(discovered_service_info.IsValid()); - - CancellationFlag flag; - WifiLanSocket socket_for_client = - wifi_lan_client.Connect(service_id, discovered_service_info, &flag); - EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(wifi_lan_server.StopAcceptingConnections(service_id)); - EXPECT_TRUE(wifi_lan_server.StopAdvertising(service_id)); - EXPECT_TRUE(socket_for_server.IsValid()); - EXPECT_TRUE(socket_for_client.IsValid()); - env_.Stop(); -} - -TEST_P(WifiLanTest, CanCancelConnect) { - FeatureFlags feature_flags = GetParam(); - env_.SetFeatureFlags(feature_flags); - env_.Start(); - WifiLan wifi_lan_client; - WifiLan wifi_lan_server; - std::string service_id(kServiceID); - std::string service_info_name(kServiceInfoName); - std::string endpoint_info_name(kEndpointName); - CountDownLatch discovered_latch(1); - CountDownLatch accept_latch(1); - - WifiLanSocket socket_for_server; - EXPECT_TRUE(wifi_lan_server.StartAcceptingConnections( - service_id, - { - .accepted_cb = - [&socket_for_server, &accept_latch](WifiLanSocket socket) { - socket_for_server = std::move(socket); - accept_latch.CountDown(); - }, - })); - - NsdServiceInfo nsd_service_info; - nsd_service_info.SetServiceName(service_info_name); - nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), - endpoint_info_name); - wifi_lan_server.StartAdvertising(service_id, nsd_service_info); - - NsdServiceInfo discovered_service_info; - wifi_lan_client.StartDiscovery( - service_id, - { - .service_discovered_cb = - [&discovered_latch, &discovered_service_info]( - NsdServiceInfo service_info, const std::string& service_id) { - NEARBY_LOGS(INFO) - << "Discovered service_info=" << &service_info; - discovered_service_info = service_info; - discovered_latch.CountDown(); - }, - }); - EXPECT_TRUE(discovered_latch.Await(kWaitDuration).result()); - ASSERT_TRUE(discovered_service_info.IsValid()); - - CancellationFlag flag(true); - WifiLanSocket socket_for_client = - wifi_lan_client.Connect(service_id, discovered_service_info, &flag); - // If FeatureFlag is disabled, Cancelled is false as no-op. - if (!feature_flags.enable_cancellation_flag) { - EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(wifi_lan_server.StopAcceptingConnections(service_id)); - EXPECT_TRUE(wifi_lan_server.StopAdvertising(service_id)); - EXPECT_TRUE(socket_for_server.IsValid()); - EXPECT_TRUE(socket_for_client.IsValid()); - } else { - EXPECT_FALSE(accept_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(wifi_lan_server.StopAcceptingConnections(service_id)); - EXPECT_TRUE(wifi_lan_server.StopAdvertising(service_id)); - EXPECT_FALSE(socket_for_server.IsValid()); - EXPECT_FALSE(socket_for_client.IsValid()); - } - env_.Stop(); -} - -INSTANTIATE_TEST_SUITE_P(ParametrisedWifiLanTest, WifiLanTest, - ::testing::ValuesIn(kTestCases)); - -TEST_F(WifiLanTest, CanConstructValidObject) { - env_.Start(); - WifiLan wifi_lan_a; - WifiLan wifi_lan_b; - std::string service_id(kServiceID); - - EXPECT_TRUE(wifi_lan_a.IsAvailable()); - EXPECT_TRUE(wifi_lan_b.IsAvailable()); - env_.Stop(); -} - -TEST_F(WifiLanTest, CanStartAdvertising) { - env_.Start(); - WifiLan wifi_lan_a; - std::string service_id(kServiceID); - std::string service_info_name(kServiceInfoName); - std::string endpoint_info_name(kEndpointName); - - EXPECT_TRUE(wifi_lan_a.StartAcceptingConnections(service_id, {})); - - NsdServiceInfo nsd_service_info; - nsd_service_info.SetServiceName(service_info_name); - nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), - endpoint_info_name); - EXPECT_TRUE(wifi_lan_a.StartAdvertising(service_id, nsd_service_info)); - EXPECT_TRUE(wifi_lan_a.StopAdvertising(service_id)); - env_.Stop(); -} - -TEST_F(WifiLanTest, CanStartMultipleAdvertising) { - env_.Start(); - WifiLan wifi_lan_a; - std::string service_id_1(kServiceID); - std::string service_id_2("com.google.location.nearby.apps.test_1"); - std::string service_info_name_1(kServiceInfoName); - std::string service_info_name_2("ServiceInfoName_1"); - std::string endpoint_info_name(kEndpointName); - - EXPECT_TRUE(wifi_lan_a.StartAcceptingConnections(service_id_1, {})); - EXPECT_TRUE(wifi_lan_a.StartAcceptingConnections(service_id_2, {})); - - NsdServiceInfo nsd_service_info_1; - nsd_service_info_1.SetServiceName(service_info_name_1); - nsd_service_info_1.SetTxtRecord(std::string(kEndpointInfoKey), - endpoint_info_name); - NsdServiceInfo nsd_service_info_2; - nsd_service_info_2.SetServiceName(service_info_name_2); - nsd_service_info_2.SetTxtRecord(std::string(kEndpointInfoKey), - endpoint_info_name); - EXPECT_TRUE(wifi_lan_a.StartAdvertising(service_id_1, nsd_service_info_1)); - EXPECT_TRUE(wifi_lan_a.StartAdvertising(service_id_2, nsd_service_info_2)); - EXPECT_TRUE(wifi_lan_a.StopAdvertising(service_id_1)); - EXPECT_TRUE(wifi_lan_a.StopAdvertising(service_id_2)); - EXPECT_TRUE(wifi_lan_a.StopAcceptingConnections(service_id_1)); - EXPECT_TRUE(wifi_lan_a.StopAcceptingConnections(service_id_2)); - env_.Stop(); -} - -TEST_F(WifiLanTest, CanStartDiscovery) { - env_.Start(); - WifiLan wifi_lan_a; - std::string service_id(kServiceID); - - EXPECT_TRUE( - wifi_lan_a.StartDiscovery(service_id, DiscoveredServiceCallback{})); - EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_id)); - env_.Stop(); -} - -TEST_F(WifiLanTest, CanStartMultipleDiscovery) { - env_.Start(); - WifiLan wifi_lan_a; - std::string service_id_1(kServiceID); - std::string service_id_2("com.google.location.nearby.apps.test_1"); - - EXPECT_TRUE( - wifi_lan_a.StartDiscovery(service_id_1, DiscoveredServiceCallback{})); - - EXPECT_TRUE( - wifi_lan_a.StartDiscovery(service_id_2, DiscoveredServiceCallback{})); - EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_id_1)); - EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_id_2)); - env_.Stop(); -} - -TEST_F(WifiLanTest, CanAdvertiseThatOtherMediumDiscover) { - env_.Start(); - WifiLan wifi_lan_a; - WifiLan wifi_lan_b; - std::string service_id(kServiceID); - std::string service_info_name(kServiceInfoName); - std::string endpoint_info_name(kEndpointName); - CountDownLatch discovered_latch(1); - CountDownLatch lost_latch(1); - - wifi_lan_b.StartDiscovery( - service_id, DiscoveredServiceCallback{ - .service_discovered_cb = - [&discovered_latch](NsdServiceInfo service_info, - const std::string& service_id) { - discovered_latch.CountDown(); - }, - .service_lost_cb = - [&lost_latch](NsdServiceInfo service_info, - const std::string& service_id) { - lost_latch.CountDown(); - }, - }); - - EXPECT_TRUE(wifi_lan_a.StartAcceptingConnections(service_id, {})); - - NsdServiceInfo nsd_service_info; - nsd_service_info.SetServiceName(service_info_name); - nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), - endpoint_info_name); - EXPECT_TRUE(wifi_lan_a.StartAdvertising(service_id, nsd_service_info)); - EXPECT_TRUE(discovered_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(wifi_lan_a.StopAdvertising(service_id)); - EXPECT_TRUE(lost_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(wifi_lan_b.StopDiscovery(service_id)); - env_.Stop(); -} - -TEST_F(WifiLanTest, CanDiscoverThatOtherMediumAdvertise) { - env_.Start(); - WifiLan wifi_lan_a; - WifiLan wifi_lan_b; - std::string service_id(kServiceID); - std::string service_info_name(kServiceInfoName); - std::string endpoint_info_name(kEndpointName); - CountDownLatch discovered_latch(1); - CountDownLatch lost_latch(1); - - EXPECT_TRUE(wifi_lan_b.StartAcceptingConnections(service_id, {})); - - NsdServiceInfo nsd_service_info; - nsd_service_info.SetServiceName(service_info_name); - nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), - endpoint_info_name); - wifi_lan_b.StartAdvertising(service_id, nsd_service_info); - - EXPECT_TRUE(wifi_lan_a.StartDiscovery( - service_id, DiscoveredServiceCallback{ - .service_discovered_cb = - [&discovered_latch](NsdServiceInfo service_info, - const std::string& service_id) { - discovered_latch.CountDown(); - }, - .service_lost_cb = - [&lost_latch](NsdServiceInfo service_info, - const std::string& service_id) { - lost_latch.CountDown(); - }, - })); - EXPECT_TRUE(discovered_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(wifi_lan_b.StopAdvertising(service_id)); - EXPECT_TRUE(lost_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_id)); - env_.Stop(); -} - -} // namespace -} // namespace connections -} // namespace nearby -} // namespace location |