diff --git a/cpp/cal/api/BUILD b/cpp/cal/api/BUILD index 895cb796..aeca0029 100644 --- a/cpp/cal/api/BUILD +++ b/cpp/cal/api/BUILD @@ -22,12 +22,12 @@ cc_library( compatible_with = ["//buildenv/target:non_prod"], visibility = [ "//googlemac/iPhone/Shared/Nearby/Connections:__subpackages__", - "//third_party/nearby_connections/cpp:__subpackages__", + "//third_party/nearby/cpp:__subpackages__", ], deps = [ "//absl/strings", "//absl/time", "//absl/types:optional", - "//third_party/nearby_connections/cpp/cal/base:types", + "//third_party/nearby/cpp/cal/base:types", ], ) diff --git a/cpp/cal/api/ble.h b/cpp/cal/api/ble.h index 80682b4e..29879059 100644 --- a/cpp/cal/api/ble.h +++ b/cpp/cal/api/ble.h @@ -22,7 +22,7 @@ #include "absl/strings/string_view.h" #include "absl/time/time.h" #include "absl/types/optional.h" -#include "third_party/nearby_connections/cpp/cal/base/ble_types.h" +#include "third_party/nearby/cpp/cal/base/ble_types.h" namespace nearby { namespace cal { namespace api { diff --git a/cpp/cal/base/BUILD b/cpp/cal/base/BUILD index aa9e115e..cd3220ad 100644 --- a/cpp/cal/base/BUILD +++ b/cpp/cal/base/BUILD @@ -22,7 +22,7 @@ cc_library( compatible_with = ["//buildenv/target:non_prod"], visibility = [ "//googlemac/iPhone/Shared/Nearby/Connections:__subpackages__", - "//third_party/nearby_connections/cpp:__subpackages__", + "//third_party/nearby/cpp:__subpackages__", ], deps = [ "//platform/base", diff --git a/cpp/cal/public/BUILD b/cpp/cal/public/BUILD index ab5ecaaf..cf6c3d62 100644 --- a/cpp/cal/public/BUILD +++ b/cpp/cal/public/BUILD @@ -25,11 +25,11 @@ cc_library( compatible_with = ["//buildenv/target:non_prod"], visibility = [ "//googlemac/iPhone/Shared/Nearby/Connections:__subpackages__", - "//third_party/nearby_connections/cpp:__subpackages__", + "//third_party/nearby/cpp:__subpackages__", ], deps = [ - "//third_party/nearby_connections/cpp/cal/api:ble", - "//third_party/nearby_connections/cpp/cal/base:types", + "//third_party/nearby/cpp/cal/api:ble", + "//third_party/nearby/cpp/cal/base:types", ], ) @@ -44,7 +44,7 @@ cc_test( ":ble", "//testing/base/public:gunit", "//testing/base/public:gunit_main", - "//third_party/nearby_connections/cpp/cal/api:ble", - "//third_party/nearby_connections/cpp/cal/base:types", + "//third_party/nearby/cpp/cal/api:ble", + "//third_party/nearby/cpp/cal/base:types", ], ) diff --git a/cpp/cal/public/ble.cc b/cpp/cal/public/ble.cc index f460b447..15c7e6f8 100644 --- a/cpp/cal/public/ble.cc +++ b/cpp/cal/public/ble.cc @@ -12,12 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "third_party/nearby_connections/cpp/cal/public/ble.h" +#include "third_party/nearby/cpp/cal/public/ble.h" #include -#include "third_party/nearby_connections/cpp/cal/api/ble.h" -#include "third_party/nearby_connections/cpp/cal/base/ble_types.h" +#include "third_party/nearby/cpp/cal/api/ble.h" +#include "third_party/nearby/cpp/cal/base/ble_types.h" namespace nearby { namespace cal { diff --git a/cpp/cal/public/ble.h b/cpp/cal/public/ble.h index dab6d239..5d0352de 100644 --- a/cpp/cal/public/ble.h +++ b/cpp/cal/public/ble.h @@ -17,8 +17,8 @@ #include -#include "third_party/nearby_connections/cpp/cal/api/ble.h" -#include "third_party/nearby_connections/cpp/cal/base/ble_types.h" +#include "third_party/nearby/cpp/cal/api/ble.h" +#include "third_party/nearby/cpp/cal/base/ble_types.h" namespace nearby { namespace cal { diff --git a/cpp/cal/public/ble_test.cc b/cpp/cal/public/ble_test.cc index 81ecdc47..104eff11 100644 --- a/cpp/cal/public/ble_test.cc +++ b/cpp/cal/public/ble_test.cc @@ -16,9 +16,9 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "third_party/nearby_connections/cpp/cal/api/ble.h" -#include "third_party/nearby_connections/cpp/cal/base/ble_types.h" -#include "third_party/nearby_connections/cpp/cal/public/ble.h" +#include "third_party/nearby/cpp/cal/api/ble.h" +#include "third_party/nearby/cpp/cal/base/ble_types.h" +#include "third_party/nearby/cpp/cal/public/ble.h" namespace nearby { namespace cal { diff --git a/cpp/core/BUILD b/cpp/core/BUILD index f91ef6b1..4588a291 100644 --- a/cpp/core/BUILD +++ b/cpp/core/BUILD @@ -25,7 +25,7 @@ cc_library( copts = ["-DCORE_ADAPTER_DLL"], visibility = [ "//platform/impl/ios:__subpackages__", - "//third_party/nearby_connections/windows:__subpackages__", + "//third_party/nearby/windows:__subpackages__", ], deps = [ ":core_types", diff --git a/cpp/core/internal/BUILD.bazel b/cpp/core/internal/BUILD.bazel index 2e9b6119..5472229d 100644 --- a/cpp/core/internal/BUILD.bazel +++ b/cpp/core/internal/BUILD.bazel @@ -87,8 +87,8 @@ cc_library( copts = ["-DCORE_ADAPTER_DLL"], defines = ["NO_WEBRTC"], visibility = [ - "//third_party/nearby_connections/cpp/core:__pkg__", - "//third_party/nearby_connections/cpp/core/internal/fuzzers:__pkg__", + "//third_party/nearby/cpp/core:__pkg__", + "//third_party/nearby/cpp/core/internal/fuzzers:__pkg__", ], deps = [ ":message_lite", @@ -101,20 +101,20 @@ cc_library( "//third_party/absl/strings", "//third_party/absl/time", "//third_party/absl/types:span", - "//third_party/nearby_connections/cpp/analytics", - "//third_party/nearby_connections/cpp/core:core_types", - "//third_party/nearby_connections/cpp/core/internal/mediums", - "//third_party/nearby_connections/cpp/core/internal/mediums:utils", - "//third_party/nearby_connections/cpp/platform/api:comm", - "//third_party/nearby_connections/cpp/platform/base", - "//third_party/nearby_connections/cpp/platform/base:cancellation_flag", - "//third_party/nearby_connections/cpp/platform/base:error_code_recorder", - "//third_party/nearby_connections/cpp/platform/base:util", - "//third_party/nearby_connections/cpp/platform/public:comm", - "//third_party/nearby_connections/cpp/platform/public:logging", - "//third_party/nearby_connections/cpp/platform/public:types", - "//third_party/nearby_connections/proto:connections_enums_portable_proto", - "//third_party/nearby_connections/proto/connections:offline_wire_formats_portable_proto", + "//third_party/nearby/cpp/analytics", + "//third_party/nearby/cpp/core:core_types", + "//third_party/nearby/cpp/core/internal/mediums", + "//third_party/nearby/cpp/core/internal/mediums:utils", + "//third_party/nearby/cpp/platform/api:comm", + "//third_party/nearby/cpp/platform/base", + "//third_party/nearby/cpp/platform/base:cancellation_flag", + "//third_party/nearby/cpp/platform/base:error_code_recorder", + "//third_party/nearby/cpp/platform/base:util", + "//third_party/nearby/cpp/platform/public:comm", + "//third_party/nearby/cpp/platform/public:logging", + "//third_party/nearby/cpp/platform/public:types", + "//third_party/nearby/proto:connections_enums_portable_proto", + "//third_party/nearby/proto/connections:offline_wire_formats_portable_proto", "//third_party/ukey2", ], ) @@ -126,7 +126,7 @@ cc_library( ], compatible_with = ["//buildenv/target:non_prod"], visibility = [ - "//third_party/nearby_connections/cpp/core:__subpackages__", + "//third_party/nearby/cpp/core:__subpackages__", ], deps = [ "//net/proto2/public:proto2_lite", @@ -148,17 +148,17 @@ cc_library( ], defines = ["NO_WEBRTC"], visibility = [ - "//third_party/nearby_connections/cpp/core:__subpackages__", + "//third_party/nearby/cpp/core:__subpackages__", ], deps = [ ":internal", "//testing/base/public:gunit_for_library_testonly", "//third_party/absl/functional:bind_front", "//third_party/absl/strings", - "//third_party/nearby_connections/cpp/core:core_types", - "//third_party/nearby_connections/cpp/platform/base", - "//third_party/nearby_connections/cpp/platform/base:test_util", - "//third_party/nearby_connections/cpp/platform/public:types", + "//third_party/nearby/cpp/core:core_types", + "//third_party/nearby/cpp/platform/base", + "//third_party/nearby/cpp/platform/base:test_util", + "//third_party/nearby/cpp/platform/public:types", ], ) @@ -199,18 +199,18 @@ cc_test( "//third_party/absl/synchronization", "//third_party/absl/time", "//third_party/absl/types:span", - "//third_party/nearby_connections/cpp/analytics", - "//third_party/nearby_connections/cpp/core:core_types", - "//third_party/nearby_connections/cpp/core/internal/mediums", - "//third_party/nearby_connections/cpp/core/internal/mediums:utils", - "//third_party/nearby_connections/cpp/platform/base", - "//third_party/nearby_connections/cpp/platform/base:test_util", - "//third_party/nearby_connections/cpp/platform/impl/g3", # build_cleaner: keep - "//third_party/nearby_connections/cpp/platform/public:comm", - "//third_party/nearby_connections/cpp/platform/public:logging", - "//third_party/nearby_connections/cpp/platform/public:types", - "//third_party/nearby_connections/proto:connections_enums_portable_proto", - "//third_party/nearby_connections/proto/connections:offline_wire_formats_portable_proto", + "//third_party/nearby/cpp/analytics", + "//third_party/nearby/cpp/core:core_types", + "//third_party/nearby/cpp/core/internal/mediums", + "//third_party/nearby/cpp/core/internal/mediums:utils", + "//third_party/nearby/cpp/platform/base", + "//third_party/nearby/cpp/platform/base:test_util", + "//third_party/nearby/cpp/platform/impl/g3", # build_cleaner: keep + "//third_party/nearby/cpp/platform/public:comm", + "//third_party/nearby/cpp/platform/public:logging", + "//third_party/nearby/cpp/platform/public:types", + "//third_party/nearby/proto:connections_enums_portable_proto", + "//third_party/nearby/proto/connections:offline_wire_formats_portable_proto", "//third_party/ukey2", ], ) diff --git a/cpp/core/internal/mediums/BUILD.bazel b/cpp/core/internal/mediums/BUILD.bazel index 797b3889..71059c38 100644 --- a/cpp/core/internal/mediums/BUILD.bazel +++ b/cpp/core/internal/mediums/BUILD.bazel @@ -39,7 +39,7 @@ cc_library( compatible_with = ["//buildenv/target:non_prod"], defines = ["NO_WEBRTC"], visibility = [ - "//third_party/nearby_connections/cpp/core/internal:__subpackages__", + "//third_party/nearby/cpp/core/internal:__subpackages__", ], deps = [ ":utils", @@ -50,15 +50,15 @@ cc_library( "//third_party/absl/strings", "//third_party/absl/strings:str_format", "//third_party/absl/time", - "//third_party/nearby_connections/cpp/core:core_types", - "//third_party/nearby_connections/cpp/core/internal/mediums/ble_v2", - "//third_party/nearby_connections/cpp/platform/base", - "//third_party/nearby_connections/cpp/platform/base:cancellation_flag", - "//third_party/nearby_connections/cpp/platform/public:comm", - "//third_party/nearby_connections/cpp/platform/public:logging", - "//third_party/nearby_connections/cpp/platform/public:types", - "//third_party/nearby_connections/proto/connections:offline_wire_formats_portable_proto", - "//third_party/nearby_connections/proto/mediums:web_rtc_signaling_frames_cc_proto", + "//third_party/nearby/cpp/core:core_types", + "//third_party/nearby/cpp/core/internal/mediums/ble_v2", + "//third_party/nearby/cpp/platform/base", + "//third_party/nearby/cpp/platform/base:cancellation_flag", + "//third_party/nearby/cpp/platform/public:comm", + "//third_party/nearby/cpp/platform/public:logging", + "//third_party/nearby/cpp/platform/public:types", + "//third_party/nearby/proto/connections:offline_wire_formats_portable_proto", + "//third_party/nearby/proto/mediums:web_rtc_signaling_frames_cc_proto", "//third_party/smhasher:libmurmur3", ], ) @@ -77,14 +77,14 @@ cc_library( compatible_with = ["//buildenv/target:non_prod"], defines = ["NO_WEBRTC"], visibility = [ - "//third_party/nearby_connections/cpp/core/internal:__pkg__", - "//third_party/nearby_connections/cpp/core/internal/mediums:__pkg__", + "//third_party/nearby/cpp/core/internal:__pkg__", + "//third_party/nearby/cpp/core/internal/mediums:__pkg__", ], deps = [ "//third_party/absl/strings", - "//third_party/nearby_connections/cpp/platform/base", - "//third_party/nearby_connections/cpp/platform/public:types", - "//third_party/nearby_connections/proto/connections:offline_wire_formats_portable_proto", + "//third_party/nearby/cpp/platform/base", + "//third_party/nearby/cpp/platform/public:types", + "//third_party/nearby/proto/connections:offline_wire_formats_portable_proto", ], ) @@ -109,10 +109,10 @@ cc_test( "//testing/base/public:gunit_main", "//third_party/absl/strings", "//third_party/absl/time", - "//third_party/nearby_connections/cpp/platform/base", - "//third_party/nearby_connections/cpp/platform/base:test_util", - "//third_party/nearby_connections/cpp/platform/impl/g3", # build_cleaner: keep - "//third_party/nearby_connections/cpp/platform/public:comm", - "//third_party/nearby_connections/cpp/platform/public:types", + "//third_party/nearby/cpp/platform/base", + "//third_party/nearby/cpp/platform/base:test_util", + "//third_party/nearby/cpp/platform/impl/g3", # build_cleaner: keep + "//third_party/nearby/cpp/platform/public:comm", + "//third_party/nearby/cpp/platform/public:types", ], ) diff --git a/cpp/core/medium_selector.h b/cpp/core/medium_selector.h index ff7fdba0..4c7907d8 100644 --- a/cpp/core/medium_selector.h +++ b/cpp/core/medium_selector.h @@ -1,78 +1,78 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#ifndef CORE_MEDIUM_SELECTOR_H_ -#define CORE_MEDIUM_SELECTOR_H_ - -#include "proto/connections_enums.pb.h" - -namespace location { -namespace nearby { -namespace connections { - -using Medium = location::nearby::proto::connections::Medium; - -// Generic type: allows definition of a feature T for every Medium. -template -struct MediumSelector { - T bluetooth; - T ble; - T web_rtc; - T wifi_lan; - - constexpr MediumSelector() = default; - constexpr MediumSelector(const MediumSelector&) = default; - constexpr MediumSelector& operator=(const MediumSelector&) = default; - constexpr bool Any(T value) const { - return bluetooth == value || ble == value || web_rtc == value || - wifi_lan == value; - } - - constexpr bool All(T value) const { - return bluetooth == value && ble == value && web_rtc == value && - wifi_lan == value; - } - - constexpr int Count(T value) const { - int count = 0; - if (bluetooth == value) count++; - if (ble == value) count++; - if (wifi_lan == value) count++; - if (web_rtc == value) count++; - return count; - } - - constexpr MediumSelector& SetAll(T value) { - bluetooth = value; - ble = value; - web_rtc = value; - wifi_lan = value; - return *this; - } - - std::vector GetMediums(T value) const { - std::vector mediums; - // Mediums are sorted in order of decreasing preference. - if (wifi_lan == value) mediums.push_back(Medium::WIFI_LAN); - if (web_rtc == value) mediums.push_back(Medium::WEB_RTC); - if (bluetooth == value) mediums.push_back(Medium::BLUETOOTH); - if (ble == value) mediums.push_back(Medium::BLE); - return mediums; - } -}; - -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_MEDIUM_SELECTOR_H_ +// 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_MEDIUM_SELECTOR_H_ +#define CORE_MEDIUM_SELECTOR_H_ + +#include "proto/connections_enums.pb.h" + +namespace location { +namespace nearby { +namespace connections { + +using Medium = location::nearby::proto::connections::Medium; + +// Generic type: allows definition of a feature T for every Medium. +template +struct MediumSelector { + T bluetooth; + T ble; + T web_rtc; + T wifi_lan; + + constexpr MediumSelector() = default; + constexpr MediumSelector(const MediumSelector&) = default; + constexpr MediumSelector& operator=(const MediumSelector&) = default; + constexpr bool Any(T value) const { + return bluetooth == value || ble == value || web_rtc == value || + wifi_lan == value; + } + + constexpr bool All(T value) const { + return bluetooth == value && ble == value && web_rtc == value && + wifi_lan == value; + } + + constexpr int Count(T value) const { + int count = 0; + if (bluetooth == value) count++; + if (ble == value) count++; + if (wifi_lan == value) count++; + if (web_rtc == value) count++; + return count; + } + + constexpr MediumSelector& SetAll(T value) { + bluetooth = value; + ble = value; + web_rtc = value; + wifi_lan = value; + return *this; + } + + std::vector GetMediums(T value) const { + std::vector mediums; + // Mediums are sorted in order of decreasing preference. + if (wifi_lan == value) mediums.push_back(Medium::WIFI_LAN); + if (web_rtc == value) mediums.push_back(Medium::WEB_RTC); + if (bluetooth == value) mediums.push_back(Medium::BLUETOOTH); + if (ble == value) mediums.push_back(Medium::BLE); + return mediums; + } +}; + +} // namespace connections +} // namespace nearby +} // namespace location + +#endif // CORE_MEDIUM_SELECTOR_H_ diff --git a/cpp/platform/base/BUILD b/cpp/platform/base/BUILD index 270bbffe..9fa908b8 100644 --- a/cpp/platform/base/BUILD +++ b/cpp/platform/base/BUILD @@ -45,7 +45,7 @@ cc_library( copts = ["-DCORE_ADAPTER_DLL"], visibility = [ "//analytics:__subpackages__", - "//third_party/nearby_connections/cpp/cal:__subpackages__", + "//third_party/nearby/cpp/cal:__subpackages__", "//core:__subpackages__", "//platform:__subpackages__", "//platform/api:__subpackages__", diff --git a/cpp/platform/impl/ios/Source/Internal/GNCAdvertiser.mm b/cpp/platform/impl/ios/Source/Internal/GNCAdvertiser.mm index bb9e2d92..a1a11943 100644 --- a/cpp/platform/impl/ios/Source/Internal/GNCAdvertiser.mm +++ b/cpp/platform/impl/ios/Source/Internal/GNCAdvertiser.mm @@ -12,23 +12,23 @@ // See the License for the specific language governing permissions and // limitations under the License. -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/GNCAdvertiser.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/GNCAdvertiser.h" #include #include "third_party/absl/functional/bind_front.h" -#include "third_party/nearby_connections/cpp/core/core.h" -#include "third_party/nearby_connections/cpp/core/listeners.h" -#include "third_party/nearby_connections/cpp/core/options.h" -#include "third_party/nearby_connections/cpp/core/params.h" -#include "third_party/nearby_connections/cpp/core/status.h" -#include "third_party/nearby_connections/cpp/platform/base/byte_array.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/GNCConnection.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Internal/GNCCore.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Internal/GNCCoreConnection.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Internal/GNCPayloadListener.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Internal/GNCUtils.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/utils.h" +#include "third_party/nearby/cpp/core/core.h" +#include "third_party/nearby/cpp/core/listeners.h" +#include "third_party/nearby/cpp/core/options.h" +#include "third_party/nearby/cpp/core/params.h" +#include "third_party/nearby/cpp/core/status.h" +#include "third_party/nearby/cpp/platform/base/byte_array.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/GNCConnection.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Internal/GNCCore.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Internal/GNCCoreConnection.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Internal/GNCPayloadListener.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Internal/GNCUtils.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Platform/utils.h" #import "third_party/objective_c/google_toolbox_for_mac/Foundation/GTMLogger.h" NS_ASSUME_NONNULL_BEGIN diff --git a/cpp/platform/impl/ios/Source/Internal/GNCCore.mm b/cpp/platform/impl/ios/Source/Internal/GNCCore.mm index edbae4db..3f84ec37 100644 --- a/cpp/platform/impl/ios/Source/Internal/GNCCore.mm +++ b/cpp/platform/impl/ios/Source/Internal/GNCCore.mm @@ -12,15 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Internal/GNCCore.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Internal/GNCCore.h" #include #include "third_party/absl/container/flat_hash_map.h" #include "third_party/absl/container/internal/common.h" -#include "third_party/nearby_connections/cpp/core/core.h" -#include "third_party/nearby_connections/cpp/core/internal/service_controller_router.h" -#include "third_party/nearby_connections/cpp/platform/base/payload_id.h" +#include "third_party/nearby/cpp/core/core.h" +#include "third_party/nearby/cpp/core/internal/service_controller_router.h" +#include "third_party/nearby/cpp/platform/base/payload_id.h" #import "third_party/objective_c/google_toolbox_for_mac/Foundation/GTMLogger.h" using ::location::nearby::connections::Core; diff --git a/cpp/platform/impl/ios/Source/Internal/GNCCoreConnection.h b/cpp/platform/impl/ios/Source/Internal/GNCCoreConnection.h index 78884f18..78e46602 100644 --- a/cpp/platform/impl/ios/Source/Internal/GNCCoreConnection.h +++ b/cpp/platform/impl/ios/Source/Internal/GNCCoreConnection.h @@ -14,8 +14,8 @@ #import -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/GNCConnection.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Internal/GNCCore.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/GNCConnection.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Internal/GNCCore.h" NS_ASSUME_NONNULL_BEGIN diff --git a/cpp/platform/impl/ios/Source/Internal/GNCCoreConnection.mm b/cpp/platform/impl/ios/Source/Internal/GNCCoreConnection.mm index 40d6a4ed..30daf0d2 100644 --- a/cpp/platform/impl/ios/Source/Internal/GNCCoreConnection.mm +++ b/cpp/platform/impl/ios/Source/Internal/GNCCoreConnection.mm @@ -12,19 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Internal/GNCCoreConnection.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Internal/GNCCoreConnection.h" -#include "third_party/nearby_connections/cpp/core/core.h" -#include "third_party/nearby_connections/cpp/core/payload.h" -#include "third_party/nearby_connections/cpp/platform/api/input_file.h" -#import "third_party/nearby_connections/cpp/platform/base/exception.h" -#include "third_party/nearby_connections/cpp/platform/base/input_stream.h" -#import "third_party/nearby_connections/cpp/platform/base/payload_id.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/GNCConnection.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/GNCPayload.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Internal/GNCCore.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/utils.h" -#include "third_party/nearby_connections/cpp/platform/public/file.h" +#include "third_party/nearby/cpp/core/core.h" +#include "third_party/nearby/cpp/core/payload.h" +#include "third_party/nearby/cpp/platform/api/input_file.h" +#import "third_party/nearby/cpp/platform/base/exception.h" +#include "third_party/nearby/cpp/platform/base/input_stream.h" +#import "third_party/nearby/cpp/platform/base/payload_id.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/GNCConnection.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/GNCPayload.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Internal/GNCCore.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Platform/utils.h" +#include "third_party/nearby/cpp/platform/public/file.h" using ::location::nearby::ByteArrayFromNSData; using ::location::nearby::CppStringFromObjCString; diff --git a/cpp/platform/impl/ios/Source/Internal/GNCDiscoverer.mm b/cpp/platform/impl/ios/Source/Internal/GNCDiscoverer.mm index db0517fd..057cefbe 100644 --- a/cpp/platform/impl/ios/Source/Internal/GNCDiscoverer.mm +++ b/cpp/platform/impl/ios/Source/Internal/GNCDiscoverer.mm @@ -12,23 +12,23 @@ // See the License for the specific language governing permissions and // limitations under the License. -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/GNCDiscoverer.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/GNCDiscoverer.h" #include #include #include "third_party/absl/functional/bind_front.h" -#include "third_party/nearby_connections/cpp/core/core.h" -#include "third_party/nearby_connections/cpp/core/listeners.h" -#include "third_party/nearby_connections/cpp/core/options.h" -#include "third_party/nearby_connections/cpp/core/status.h" -#include "third_party/nearby_connections/cpp/platform/base/byte_array.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/GNCConnection.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Internal/GNCCore.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Internal/GNCCoreConnection.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Internal/GNCPayloadListener.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Internal/GNCUtils.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/utils.h" +#include "third_party/nearby/cpp/core/core.h" +#include "third_party/nearby/cpp/core/listeners.h" +#include "third_party/nearby/cpp/core/options.h" +#include "third_party/nearby/cpp/core/status.h" +#include "third_party/nearby/cpp/platform/base/byte_array.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/GNCConnection.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Internal/GNCCore.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Internal/GNCCoreConnection.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Internal/GNCPayloadListener.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Internal/GNCUtils.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Platform/utils.h" #import "third_party/objective_c/google_toolbox_for_mac/Foundation/GTMLogger.h" NS_ASSUME_NONNULL_BEGIN diff --git a/cpp/platform/impl/ios/Source/Internal/GNCPayload+Internal.h b/cpp/platform/impl/ios/Source/Internal/GNCPayload+Internal.h index 3831230e..eec59066 100644 --- a/cpp/platform/impl/ios/Source/Internal/GNCPayload+Internal.h +++ b/cpp/platform/impl/ios/Source/Internal/GNCPayload+Internal.h @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/GNCPayload.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/GNCPayload.h" NS_ASSUME_NONNULL_BEGIN diff --git a/cpp/platform/impl/ios/Source/Internal/GNCPayload.m b/cpp/platform/impl/ios/Source/Internal/GNCPayload.m index b4ab2de8..0b975305 100644 --- a/cpp/platform/impl/ios/Source/Internal/GNCPayload.m +++ b/cpp/platform/impl/ios/Source/Internal/GNCPayload.m @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/GNCPayload.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/GNCPayload.h" #include diff --git a/cpp/platform/impl/ios/Source/Internal/GNCPayloadListener.h b/cpp/platform/impl/ios/Source/Internal/GNCPayloadListener.h index 17357c3a..65aed071 100644 --- a/cpp/platform/impl/ios/Source/Internal/GNCPayloadListener.h +++ b/cpp/platform/impl/ios/Source/Internal/GNCPayloadListener.h @@ -14,8 +14,8 @@ #import -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/GNCConnection.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Internal/GNCCore.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/GNCConnection.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Internal/GNCCore.h" NS_ASSUME_NONNULL_BEGIN diff --git a/cpp/platform/impl/ios/Source/Internal/GNCPayloadListener.mm b/cpp/platform/impl/ios/Source/Internal/GNCPayloadListener.mm index 1883d9ad..f7efb389 100644 --- a/cpp/platform/impl/ios/Source/Internal/GNCPayloadListener.mm +++ b/cpp/platform/impl/ios/Source/Internal/GNCPayloadListener.mm @@ -12,23 +12,23 @@ // See the License for the specific language governing permissions and // limitations under the License. -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Internal/GNCPayloadListener.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Internal/GNCPayloadListener.h" #include -#include "third_party/nearby_connections/cpp/core/core.h" -#include "third_party/nearby_connections/cpp/core/listeners.h" -#include "third_party/nearby_connections/cpp/core/payload.h" -#include "third_party/nearby_connections/cpp/platform/base/byte_array.h" -#include "third_party/nearby_connections/cpp/platform/base/exception.h" -#include "third_party/nearby_connections/cpp/platform/base/input_stream.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/GNCConnection.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/GNCPayload.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Internal/GNCCore.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Internal/GNCCoreConnection.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Internal/GNCPayload+Internal.h" -#include "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/utils.h" -#include "third_party/nearby_connections/cpp/platform/public/file.h" +#include "third_party/nearby/cpp/core/core.h" +#include "third_party/nearby/cpp/core/listeners.h" +#include "third_party/nearby/cpp/core/payload.h" +#include "third_party/nearby/cpp/platform/base/byte_array.h" +#include "third_party/nearby/cpp/platform/base/exception.h" +#include "third_party/nearby/cpp/platform/base/input_stream.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/GNCConnection.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/GNCPayload.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Internal/GNCCore.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Internal/GNCCoreConnection.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Internal/GNCPayload+Internal.h" +#include "third_party/nearby/cpp/platform/impl/ios/Source/Platform/utils.h" +#include "third_party/nearby/cpp/platform/public/file.h" NS_ASSUME_NONNULL_BEGIN diff --git a/cpp/platform/impl/ios/Source/Internal/GNCUtils.h b/cpp/platform/impl/ios/Source/Internal/GNCUtils.h index f0efbeef..7e37e5f0 100644 --- a/cpp/platform/impl/ios/Source/Internal/GNCUtils.h +++ b/cpp/platform/impl/ios/Source/Internal/GNCUtils.h @@ -18,8 +18,8 @@ #include "core/listeners.h" #include "core/options.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/GNCAdvertiser.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/GNCConnection.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/GNCAdvertiser.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/GNCConnection.h" NS_ASSUME_NONNULL_BEGIN diff --git a/cpp/platform/impl/ios/Source/Internal/GNCUtils.mm b/cpp/platform/impl/ios/Source/Internal/GNCUtils.mm index bec82bf8..d4223160 100644 --- a/cpp/platform/impl/ios/Source/Internal/GNCUtils.mm +++ b/cpp/platform/impl/ios/Source/Internal/GNCUtils.mm @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Internal/GNCUtils.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Internal/GNCUtils.h" -#include "third_party/nearby_connections/cpp/core/strategy.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/GNCAdvertiser.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/GNCConnection.h" +#include "third_party/nearby/cpp/core/strategy.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/GNCAdvertiser.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/GNCConnection.h" NS_ASSUME_NONNULL_BEGIN diff --git a/cpp/platform/impl/ios/Source/Internal/platform.mm b/cpp/platform/impl/ios/Source/Internal/platform.mm index 52198eef..d8669535 100644 --- a/cpp/platform/impl/ios/Source/Internal/platform.mm +++ b/cpp/platform/impl/ios/Source/Internal/platform.mm @@ -12,26 +12,26 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "third_party/nearby_connections/cpp/platform/api/platform.h" +#include "third_party/nearby/cpp/platform/api/platform.h" #include -#include "third_party/nearby_connections/cpp/platform/api/mutex.h" -#include "third_party/nearby_connections/cpp/platform/base/payload_id.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Internal/GNCCore.h" -#include "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/atomic_boolean.h" -#include "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/atomic_uint32.h" -#include "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/condition_variable.h" -#include "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/count_down_latch.h" -#include "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/input_file.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/log_message.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/multi_thread_executor.h" -#include "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/mutex.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/scheduled_executor.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/single_thread_executor.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/utils.h" -#include "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/wifi_lan.h" -#include "third_party/nearby_connections/cpp/platform/impl/shared/file.h" +#include "third_party/nearby/cpp/platform/api/mutex.h" +#include "third_party/nearby/cpp/platform/base/payload_id.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Internal/GNCCore.h" +#include "third_party/nearby/cpp/platform/impl/ios/Source/Platform/atomic_boolean.h" +#include "third_party/nearby/cpp/platform/impl/ios/Source/Platform/atomic_uint32.h" +#include "third_party/nearby/cpp/platform/impl/ios/Source/Platform/condition_variable.h" +#include "third_party/nearby/cpp/platform/impl/ios/Source/Platform/count_down_latch.h" +#include "third_party/nearby/cpp/platform/impl/ios/Source/Platform/input_file.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Platform/log_message.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Platform/multi_thread_executor.h" +#include "third_party/nearby/cpp/platform/impl/ios/Source/Platform/mutex.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Platform/scheduled_executor.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Platform/single_thread_executor.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Platform/utils.h" +#include "third_party/nearby/cpp/platform/impl/ios/Source/Platform/wifi_lan.h" +#include "third_party/nearby/cpp/platform/impl/shared/file.h" namespace location { namespace nearby { diff --git a/cpp/platform/impl/ios/Source/Mediums/GNCLeaks.m b/cpp/platform/impl/ios/Source/Mediums/GNCLeaks.m index 10ff26bf..9786b5dc 100644 --- a/cpp/platform/impl/ios/Source/Mediums/GNCLeaks.m +++ b/cpp/platform/impl/ios/Source/Mediums/GNCLeaks.m @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Mediums/GNCLeaks.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Mediums/GNCLeaks.h" void GNCVerifyDealloc(id object, NSTimeInterval timeInterval) { #if DEBUG diff --git a/cpp/platform/impl/ios/Source/Mediums/GNCMConnection.m b/cpp/platform/impl/ios/Source/Mediums/GNCMConnection.m index 9e14f9f9..220b6226 100644 --- a/cpp/platform/impl/ios/Source/Mediums/GNCMConnection.m +++ b/cpp/platform/impl/ios/Source/Mediums/GNCMConnection.m @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Mediums/GNCMConnection.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Mediums/GNCMConnection.h" NS_ASSUME_NONNULL_BEGIN diff --git a/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourBrowser.h b/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourBrowser.h index a8aef657..1d6a6e35 100644 --- a/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourBrowser.h +++ b/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourBrowser.h @@ -14,7 +14,7 @@ #import -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Mediums/GNCMConnection.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Mediums/GNCMConnection.h" NS_ASSUME_NONNULL_BEGIN diff --git a/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourBrowser.m b/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourBrowser.m index a4fffa6a..03b18d60 100644 --- a/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourBrowser.m +++ b/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourBrowser.m @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourBrowser.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourBrowser.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Mediums/GNCMConnection.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourConnection.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourUtils.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Mediums/GNCMConnection.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourConnection.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourUtils.h" #import "third_party/objective_c/google_toolbox_for_mac/Foundation/GTMLogger.h" typedef NSString *GNCEndpointId; diff --git a/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourConnection.h b/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourConnection.h index 13706c48..ed6c5921 100644 --- a/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourConnection.h +++ b/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourConnection.h @@ -14,7 +14,7 @@ #import -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Mediums/GNCMConnection.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Mediums/GNCMConnection.h" NS_ASSUME_NONNULL_BEGIN diff --git a/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourConnection.m b/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourConnection.m index 01d6bd68..13046b0e 100644 --- a/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourConnection.m +++ b/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourConnection.m @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourConnection.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourConnection.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Mediums/GNCMConnection.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Mediums/GNCMConnection.h" #import "third_party/objective_c/google_toolbox_for_mac/Foundation/GTMLogger.h" enum { kMaxPacketSize = 32 * 1024 }; diff --git a/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourService.h b/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourService.h index e1c5e4b2..9386e652 100644 --- a/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourService.h +++ b/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourService.h @@ -14,7 +14,7 @@ #import -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Mediums/GNCMConnection.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Mediums/GNCMConnection.h" NS_ASSUME_NONNULL_BEGIN diff --git a/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourService.m b/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourService.m index 73c07538..be9a6970 100644 --- a/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourService.m +++ b/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourService.m @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourService.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourService.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Mediums/GNCMConnection.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourConnection.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourUtils.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Mediums/GNCMConnection.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourConnection.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourUtils.h" #import "third_party/objective_c/google_toolbox_for_mac/Foundation/GTMLogger.h" @interface GNCMBonjourService () diff --git a/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourUtils.m b/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourUtils.m index d05af7e2..b508a582 100644 --- a/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourUtils.m +++ b/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourUtils.m @@ -12,6 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourUtils.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourUtils.h" NSString *const GNCMBonjourDomain = @"local"; diff --git a/cpp/platform/impl/ios/Source/Platform/crypto.mm b/cpp/platform/impl/ios/Source/Platform/crypto.mm index cc2dc344..cdb38d57 100644 --- a/cpp/platform/impl/ios/Source/Platform/crypto.mm +++ b/cpp/platform/impl/ios/Source/Platform/crypto.mm @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "third_party/nearby_connections/cpp/platform/api/crypto.h" +#include "third_party/nearby/cpp/platform/api/crypto.h" #import "third_party/absl/strings/string_view.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/utils.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Shared/GNCUtils.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Platform/utils.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Shared/GNCUtils.h" namespace location { namespace nearby { diff --git a/cpp/platform/impl/ios/Source/Platform/input_file.mm b/cpp/platform/impl/ios/Source/Platform/input_file.mm index b8addef8..ffaee79e 100644 --- a/cpp/platform/impl/ios/Source/Platform/input_file.mm +++ b/cpp/platform/impl/ios/Source/Platform/input_file.mm @@ -12,12 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/input_file.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Platform/input_file.h" #include -#import "third_party/nearby_connections/cpp/platform/base/exception.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/utils.h" +#import "third_party/nearby/cpp/platform/base/exception.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Platform/utils.h" namespace location { namespace nearby { diff --git a/cpp/platform/impl/ios/Source/Platform/log_message.mm b/cpp/platform/impl/ios/Source/Platform/log_message.mm index bb50868a..fec416f0 100644 --- a/cpp/platform/impl/ios/Source/Platform/log_message.mm +++ b/cpp/platform/impl/ios/Source/Platform/log_message.mm @@ -12,10 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/log_message.h" +#include "third_party/nearby/cpp/platform/impl/ios/Source/Platform/log_message.h" #include "base/logging.h" -#include "third_party/nearby_connections/cpp/platform/api/log_message.h" +#include "third_party/nearby/cpp/platform/api/log_message.h" #include "third_party/objective_c/google_toolbox_for_mac/Foundation/GTMLogger.h" namespace location { diff --git a/cpp/platform/impl/ios/Source/Platform/multi_thread_executor.h b/cpp/platform/impl/ios/Source/Platform/multi_thread_executor.h index e44e5b3e..38eb9926 100644 --- a/cpp/platform/impl/ios/Source/Platform/multi_thread_executor.h +++ b/cpp/platform/impl/ios/Source/Platform/multi_thread_executor.h @@ -16,8 +16,8 @@ #define PLATFORM_IMPL_IOS_MULTI_THREAD_EXECUTOR_H_ #include "platform/api/submittable_executor.h" -#import "third_party/nearby_connections/cpp/platform/base/runnable.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/scheduled_executor.h" +#import "third_party/nearby/cpp/platform/base/runnable.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Platform/scheduled_executor.h" namespace location { namespace nearby { diff --git a/cpp/platform/impl/ios/Source/Platform/multi_thread_executor.mm b/cpp/platform/impl/ios/Source/Platform/multi_thread_executor.mm index 5070e4e5..7d342531 100644 --- a/cpp/platform/impl/ios/Source/Platform/multi_thread_executor.mm +++ b/cpp/platform/impl/ios/Source/Platform/multi_thread_executor.mm @@ -12,10 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/multi_thread_executor.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Platform/multi_thread_executor.h" -#include "third_party/nearby_connections/cpp/platform/base/runnable.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/scheduled_executor.h" +#include "third_party/nearby/cpp/platform/base/runnable.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Platform/scheduled_executor.h" namespace location { namespace nearby { diff --git a/cpp/platform/impl/ios/Source/Platform/scheduled_executor.mm b/cpp/platform/impl/ios/Source/Platform/scheduled_executor.mm index 1713adea..d9b562c6 100644 --- a/cpp/platform/impl/ios/Source/Platform/scheduled_executor.mm +++ b/cpp/platform/impl/ios/Source/Platform/scheduled_executor.mm @@ -12,13 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/scheduled_executor.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Platform/scheduled_executor.h" #import #include "third_party/absl/time/time.h" -#include "third_party/nearby_connections/cpp/platform/base/runnable.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/atomic_boolean.h" +#include "third_party/nearby/cpp/platform/base/runnable.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Platform/atomic_boolean.h" // This wraps the C++ Runnable in an Obj-C object for memory management. It is retained by the // dispatch block below, and deleted when the block is released. diff --git a/cpp/platform/impl/ios/Source/Platform/single_thread_executor.h b/cpp/platform/impl/ios/Source/Platform/single_thread_executor.h index eafb254a..7162d075 100644 --- a/cpp/platform/impl/ios/Source/Platform/single_thread_executor.h +++ b/cpp/platform/impl/ios/Source/Platform/single_thread_executor.h @@ -15,7 +15,7 @@ #ifndef PLATFORM_IMPL_IOS_SINGLE_THREAD_EXECUTOR_H_ #define PLATFORM_IMPL_IOS_SINGLE_THREAD_EXECUTOR_H_ -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/multi_thread_executor.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Platform/multi_thread_executor.h" namespace location { namespace nearby { diff --git a/cpp/platform/impl/ios/Source/Platform/utils.mm b/cpp/platform/impl/ios/Source/Platform/utils.mm index 4a98fb74..3f79ecea 100644 --- a/cpp/platform/impl/ios/Source/Platform/utils.mm +++ b/cpp/platform/impl/ios/Source/Platform/utils.mm @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/utils.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Platform/utils.h" #import "third_party/absl/container/flat_hash_map.h" #include "third_party/absl/strings/string_view.h" -#include "third_party/nearby_connections/cpp/platform/base/byte_array.h" +#include "third_party/nearby/cpp/platform/base/byte_array.h" NS_ASSUME_NONNULL_BEGIN diff --git a/cpp/platform/impl/ios/Source/Platform/wifi_lan.h b/cpp/platform/impl/ios/Source/Platform/wifi_lan.h index de4416cd..9ed30d49 100644 --- a/cpp/platform/impl/ios/Source/Platform/wifi_lan.h +++ b/cpp/platform/impl/ios/Source/Platform/wifi_lan.h @@ -22,7 +22,7 @@ #include "absl/container/flat_hash_map.h" #include "platform/api/wifi_lan.h" #include "platform/base/nsd_service_info.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Mediums/GNCMConnection.h" // IWYU pragma: export +#import "third_party/nearby/cpp/platform/impl/ios/Source/Mediums/GNCMConnection.h" // IWYU pragma: export @class GNCMBonjourBrowser; @class GNCMBonjourService; diff --git a/cpp/platform/impl/ios/Source/Platform/wifi_lan.mm b/cpp/platform/impl/ios/Source/Platform/wifi_lan.mm index 476e2677..c46fe616 100644 --- a/cpp/platform/impl/ios/Source/Platform/wifi_lan.mm +++ b/cpp/platform/impl/ios/Source/Platform/wifi_lan.mm @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/wifi_lan.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Platform/wifi_lan.h" #include #include @@ -24,15 +24,15 @@ #include "third_party/absl/strings/str_cat.h" #include "third_party/absl/strings/str_format.h" #include "third_party/absl/synchronization/mutex.h" -#include "third_party/nearby_connections/cpp/platform/api/wifi_lan.h" -#include "third_party/nearby_connections/cpp/platform/base/cancellation_flag.h" -#include "third_party/nearby_connections/cpp/platform/base/exception.h" -#include "third_party/nearby_connections/cpp/platform/base/nsd_service_info.h" -#include "third_party/nearby_connections/cpp/platform/base/prng.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Mediums/GNCMConnection.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourBrowser.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourService.h" -#include "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/utils.h" +#include "third_party/nearby/cpp/platform/api/wifi_lan.h" +#include "third_party/nearby/cpp/platform/base/cancellation_flag.h" +#include "third_party/nearby/cpp/platform/base/exception.h" +#include "third_party/nearby/cpp/platform/base/nsd_service_info.h" +#include "third_party/nearby/cpp/platform/base/prng.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Mediums/GNCMConnection.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourBrowser.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Mediums/WifiLan/GNCMBonjourService.h" +#include "third_party/nearby/cpp/platform/impl/ios/Source/Platform/utils.h" #import "third_party/objective_c/google_toolbox_for_mac/Foundation/GTMLogger.h" namespace location { diff --git a/cpp/platform/impl/ios/Source/Shared/GNCUtils.m b/cpp/platform/impl/ios/Source/Shared/GNCUtils.m index cad4a664..e8a91a12 100644 --- a/cpp/platform/impl/ios/Source/Shared/GNCUtils.m +++ b/cpp/platform/impl/ios/Source/Shared/GNCUtils.m @@ -1,4 +1,4 @@ -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Shared/GNCUtils.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Shared/GNCUtils.h" #import diff --git a/cpp/platform/impl/ios/Tests/Platform/GNCCryptoTest.mm b/cpp/platform/impl/ios/Tests/Platform/GNCCryptoTest.mm index 884be705..d5ab389b 100644 --- a/cpp/platform/impl/ios/Tests/Platform/GNCCryptoTest.mm +++ b/cpp/platform/impl/ios/Tests/Platform/GNCCryptoTest.mm @@ -14,8 +14,8 @@ #import -#include "third_party/nearby_connections/cpp/platform/api/crypto.h" -#include "third_party/nearby_connections/cpp/platform/base/byte_array.h" +#include "third_party/nearby/cpp/platform/api/crypto.h" +#include "third_party/nearby/cpp/platform/base/byte_array.h" @interface GNCCryptoTest : XCTestCase @end diff --git a/cpp/platform/impl/ios/Tests/Platform/GNCInputFileTest.mm b/cpp/platform/impl/ios/Tests/Platform/GNCInputFileTest.mm index 4e038ae8..361b9055 100644 --- a/cpp/platform/impl/ios/Tests/Platform/GNCInputFileTest.mm +++ b/cpp/platform/impl/ios/Tests/Platform/GNCInputFileTest.mm @@ -14,9 +14,9 @@ #import -#import "third_party/nearby_connections/cpp/platform/base/byte_array.h" -#import "third_party/nearby_connections/cpp/platform/base/exception.h" -#import "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/input_file.h" +#import "third_party/nearby/cpp/platform/base/byte_array.h" +#import "third_party/nearby/cpp/platform/base/exception.h" +#import "third_party/nearby/cpp/platform/impl/ios/Source/Platform/input_file.h" using ::location::nearby::ios::InputFile; using ::location::nearby::ByteArray; diff --git a/cpp/platform/impl/ios/Tests/Platform/GNCMultiThreadExecutorTest.mm b/cpp/platform/impl/ios/Tests/Platform/GNCMultiThreadExecutorTest.mm index c9948c55..40d7b6f5 100644 --- a/cpp/platform/impl/ios/Tests/Platform/GNCMultiThreadExecutorTest.mm +++ b/cpp/platform/impl/ios/Tests/Platform/GNCMultiThreadExecutorTest.mm @@ -15,11 +15,11 @@ #import #include "third_party/absl/time/time.h" -#include "third_party/nearby_connections/cpp/platform/api/cancelable.h" -#include "third_party/nearby_connections/cpp/platform/api/executor.h" -#include "third_party/nearby_connections/cpp/platform/api/platform.h" -#include "third_party/nearby_connections/cpp/platform/api/submittable_executor.h" -#include "third_party/nearby_connections/cpp/platform/base/runnable.h" +#include "third_party/nearby/cpp/platform/api/cancelable.h" +#include "third_party/nearby/cpp/platform/api/executor.h" +#include "third_party/nearby/cpp/platform/api/platform.h" +#include "third_party/nearby/cpp/platform/api/submittable_executor.h" +#include "third_party/nearby/cpp/platform/base/runnable.h" using location::nearby::Runnable; using location::nearby::api::ImplementationPlatform; diff --git a/cpp/platform/impl/ios/Tests/Platform/GNCScheduledExecutorTest.mm b/cpp/platform/impl/ios/Tests/Platform/GNCScheduledExecutorTest.mm index 278c6ee7..27aa566a 100644 --- a/cpp/platform/impl/ios/Tests/Platform/GNCScheduledExecutorTest.mm +++ b/cpp/platform/impl/ios/Tests/Platform/GNCScheduledExecutorTest.mm @@ -15,11 +15,11 @@ #import #include "third_party/absl/time/time.h" -#include "third_party/nearby_connections/cpp/platform/api/cancelable.h" -#include "third_party/nearby_connections/cpp/platform/api/executor.h" -#include "third_party/nearby_connections/cpp/platform/api/platform.h" -#include "third_party/nearby_connections/cpp/platform/api/scheduled_executor.h" -#include "third_party/nearby_connections/cpp/platform/base/runnable.h" +#include "third_party/nearby/cpp/platform/api/cancelable.h" +#include "third_party/nearby/cpp/platform/api/executor.h" +#include "third_party/nearby/cpp/platform/api/platform.h" +#include "third_party/nearby/cpp/platform/api/scheduled_executor.h" +#include "third_party/nearby/cpp/platform/base/runnable.h" using location::nearby::Runnable; using location::nearby::api::ImplementationPlatform; diff --git a/cpp/platform/impl/ios/Tests/Platform/GNCSingleThreadExecutorTest.mm b/cpp/platform/impl/ios/Tests/Platform/GNCSingleThreadExecutorTest.mm index 85f18683..1be259b1 100644 --- a/cpp/platform/impl/ios/Tests/Platform/GNCSingleThreadExecutorTest.mm +++ b/cpp/platform/impl/ios/Tests/Platform/GNCSingleThreadExecutorTest.mm @@ -15,11 +15,11 @@ #import #include "third_party/absl/time/time.h" -#include "third_party/nearby_connections/cpp/platform/api/cancelable.h" -#include "third_party/nearby_connections/cpp/platform/api/executor.h" -#include "third_party/nearby_connections/cpp/platform/api/platform.h" -#include "third_party/nearby_connections/cpp/platform/api/submittable_executor.h" -#include "third_party/nearby_connections/cpp/platform/base/runnable.h" +#include "third_party/nearby/cpp/platform/api/cancelable.h" +#include "third_party/nearby/cpp/platform/api/executor.h" +#include "third_party/nearby/cpp/platform/api/platform.h" +#include "third_party/nearby/cpp/platform/api/submittable_executor.h" +#include "third_party/nearby/cpp/platform/base/runnable.h" using location::nearby::Runnable; using location::nearby::api::ImplementationPlatform; diff --git a/cpp/platform/impl/ios/Tests/Shared/GNCUtilsTest.mm b/cpp/platform/impl/ios/Tests/Shared/GNCUtilsTest.mm index cbb37df2..d631eae8 100644 --- a/cpp/platform/impl/ios/Tests/Shared/GNCUtilsTest.mm +++ b/cpp/platform/impl/ios/Tests/Shared/GNCUtilsTest.mm @@ -14,8 +14,8 @@ #import -#include "third_party/nearby_connections/cpp/platform/base/byte_array.h" -#include "third_party/nearby_connections/cpp/platform/impl/ios/Source/Platform/utils.h" +#include "third_party/nearby/cpp/platform/base/byte_array.h" +#include "third_party/nearby/cpp/platform/impl/ios/Source/Platform/utils.h" using location::nearby::ByteArray; using location::nearby::ByteArrayFromNSData; diff --git a/cpp/platform/impl/windows/BUILD b/cpp/platform/impl/windows/BUILD index 726067b4..1d436944 100644 --- a/cpp/platform/impl/windows/BUILD +++ b/cpp/platform/impl/windows/BUILD @@ -110,9 +110,9 @@ cc_library( "wifi_lan_socket.cc", ], compatible_with = ["//buildenv/target:non_prod"], - copts = ["-Ithird_party/nearby_connections/cpp/platform/impl/windows/generated"], + copts = ["-Ithird_party/nearby/cpp/platform/impl/windows/generated"], visibility = [ - "//third_party/nearby_connections/windows:__subpackages__", + "//third_party/nearby/windows:__subpackages__", ], deps = [ ":comm", @@ -138,7 +138,7 @@ cc_library( "test_utils.h", ], visibility = [ - "//third_party/nearby_connections/windows:__subpackages__", + "//third_party/nearby/windows:__subpackages__", ], deps = [ "//platform/base", diff --git a/cpp/platform/impl/windows/atomic_reference_test.cc b/cpp/platform/impl/windows/atomic_reference_test.cc index 9e6e5001..adb41801 100644 --- a/cpp/platform/impl/windows/atomic_reference_test.cc +++ b/cpp/platform/impl/windows/atomic_reference_test.cc @@ -1,72 +1,72 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "platform/impl/windows/atomic_reference.h" - -#include "gtest/gtest.h" - -TEST(atomic_reference, SuccessfulCreation) { - // Arrange - location::nearby::windows::AtomicUint32 atomicUint32; - uint32_t result = UINT32_MAX; - const uint32_t expected = 0; - - // Act - result = atomicUint32.Get(); - - // Assert - EXPECT_EQ(result, expected); -} - -TEST(atomic_reference, SuccessfulMaxSet) { - // Arrange - location::nearby::windows::AtomicUint32 atomicUint32; - uint32_t result = 0; - const uint32_t expected = UINT32_MAX; - - // Act - atomicUint32.Set(UINT32_MAX); - result = atomicUint32.Get(); - - // Assert - EXPECT_EQ(result, expected); -} - -TEST(atomic_reference, SuccessfulMinSet) { - // Arrange - location::nearby::windows::AtomicUint32 atomicUint32; - uint32_t result = UINT32_MAX; - const uint32_t expected = 0; - - // Act - atomicUint32.Set(0); - result = atomicUint32.Get(); - - // Assert - EXPECT_EQ(result, expected); -} - -TEST(atomic_reference, SetNegativeOneReturnsMAXUINT) { - // Arrange - location::nearby::windows::AtomicUint32 atomicUint32; - uint32_t result = 0; - const uint32_t expected = UINT32_MAX; - - // Act - atomicUint32.Set(-1); // Try Set -1, should actually store UINT32_MAX - result = atomicUint32.Get(); - - // Assert - EXPECT_EQ(result, expected); -} +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "platform/impl/windows/atomic_reference.h" + +#include "gtest/gtest.h" + +TEST(atomic_reference, SuccessfulCreation) { + // Arrange + location::nearby::windows::AtomicUint32 atomicUint32; + uint32_t result = UINT32_MAX; + const uint32_t expected = 0; + + // Act + result = atomicUint32.Get(); + + // Assert + EXPECT_EQ(result, expected); +} + +TEST(atomic_reference, SuccessfulMaxSet) { + // Arrange + location::nearby::windows::AtomicUint32 atomicUint32; + uint32_t result = 0; + const uint32_t expected = UINT32_MAX; + + // Act + atomicUint32.Set(UINT32_MAX); + result = atomicUint32.Get(); + + // Assert + EXPECT_EQ(result, expected); +} + +TEST(atomic_reference, SuccessfulMinSet) { + // Arrange + location::nearby::windows::AtomicUint32 atomicUint32; + uint32_t result = UINT32_MAX; + const uint32_t expected = 0; + + // Act + atomicUint32.Set(0); + result = atomicUint32.Get(); + + // Assert + EXPECT_EQ(result, expected); +} + +TEST(atomic_reference, SetNegativeOneReturnsMAXUINT) { + // Arrange + location::nearby::windows::AtomicUint32 atomicUint32; + uint32_t result = 0; + const uint32_t expected = UINT32_MAX; + + // Act + atomicUint32.Set(-1); // Try Set -1, should actually store UINT32_MAX + result = atomicUint32.Get(); + + // Assert + EXPECT_EQ(result, expected); +} diff --git a/cpp/platform/impl/windows/bluetooth_classic_device.cc b/cpp/platform/impl/windows/bluetooth_classic_device.cc index 1b88796f..49f47ee1 100644 --- a/cpp/platform/impl/windows/bluetooth_classic_device.cc +++ b/cpp/platform/impl/windows/bluetooth_classic_device.cc @@ -1,65 +1,65 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "platform/impl/windows/bluetooth_classic_device.h" - -#include - -#include -#include -#include - -#include "platform/impl/windows/generated/winrt/Windows.Devices.Bluetooth.h" - -#include "platform/impl/windows/utils.h" - -namespace location { -namespace nearby { -namespace windows { - -BluetoothDevice::~BluetoothDevice() {} - -BluetoothDevice::BluetoothDevice( - const winrt::Windows::Devices::Bluetooth::BluetoothDevice& bluetoothDevice) - : windows_bluetooth_device_(bluetoothDevice) { - id_ = winrt::to_string(bluetoothDevice.DeviceId()); - - // Get the device address. - auto bluetoothAddress = bluetoothDevice.BluetoothAddress(); - - mac_address_ = uint64_to_mac_address_string(bluetoothAddress); -} - -// https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#getName() -std::string BluetoothDevice::GetName() const { - return winrt::to_string(windows_bluetooth_device_.Name()); -} - -// Returns BT MAC address assigned to this device. -std::string BluetoothDevice::GetMacAddress() const { return mac_address_; } - -// We are using Uncached because: -// For the following APIs, Cached means only use values cached in the system -// cached (if not cached then don't fall back to querying the device). -// The device may be present, but not entered into the cache yet, so always -// check the actual device. -IAsyncOperation -BluetoothDevice::GetRfcommServicesForIdAsync(const RfcommServiceId serviceId) { - return windows_bluetooth_device_.GetRfcommServicesForIdAsync( - serviceId, BluetoothCacheMode::Uncached); -} - -} // namespace windows -} // namespace nearby -} // namespace location +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "platform/impl/windows/bluetooth_classic_device.h" + +#include + +#include +#include +#include + +#include "platform/impl/windows/generated/winrt/Windows.Devices.Bluetooth.h" + +#include "platform/impl/windows/utils.h" + +namespace location { +namespace nearby { +namespace windows { + +BluetoothDevice::~BluetoothDevice() {} + +BluetoothDevice::BluetoothDevice( + const winrt::Windows::Devices::Bluetooth::BluetoothDevice& bluetoothDevice) + : windows_bluetooth_device_(bluetoothDevice) { + id_ = winrt::to_string(bluetoothDevice.DeviceId()); + + // Get the device address. + auto bluetoothAddress = bluetoothDevice.BluetoothAddress(); + + mac_address_ = uint64_to_mac_address_string(bluetoothAddress); +} + +// https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#getName() +std::string BluetoothDevice::GetName() const { + return winrt::to_string(windows_bluetooth_device_.Name()); +} + +// Returns BT MAC address assigned to this device. +std::string BluetoothDevice::GetMacAddress() const { return mac_address_; } + +// We are using Uncached because: +// For the following APIs, Cached means only use values cached in the system +// cached (if not cached then don't fall back to querying the device). +// The device may be present, but not entered into the cache yet, so always +// check the actual device. +IAsyncOperation +BluetoothDevice::GetRfcommServicesForIdAsync(const RfcommServiceId serviceId) { + return windows_bluetooth_device_.GetRfcommServicesForIdAsync( + serviceId, BluetoothCacheMode::Uncached); +} + +} // namespace windows +} // namespace nearby +} // namespace location diff --git a/cpp/platform/impl/windows/bluetooth_classic_medium.cc b/cpp/platform/impl/windows/bluetooth_classic_medium.cc index 12cbcf93..4f8a7db4 100644 --- a/cpp/platform/impl/windows/bluetooth_classic_medium.cc +++ b/cpp/platform/impl/windows/bluetooth_classic_medium.cc @@ -1,443 +1,443 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "platform/impl/windows/bluetooth_classic_medium.h" - -#include -#include - -#include -#include -#include // NOLINT -#include - -#include "platform/base/cancellation_flag.h" -#include "platform/base/cancellation_flag_listener.h" -#include "platform/base/exception.h" -#include "platform/impl/windows/bluetooth_adapter.h" -#include "platform/impl/windows/bluetooth_classic_device.h" -#include "platform/impl/windows/bluetooth_classic_server_socket.h" -#include "platform/impl/windows/bluetooth_classic_socket.h" -#include "platform/impl/windows/generated/winrt/Windows.Devices.Bluetooth.Rfcomm.h" -#include "platform/impl/windows/generated/winrt/Windows.Devices.Bluetooth.h" -#include "platform/impl/windows/generated/winrt/Windows.Devices.Enumeration.h" -#include "platform/impl/windows/generated/winrt/Windows.Foundation.Collections.h" -#include "platform/impl/windows/generated/winrt/base.h" -#include "platform/impl/windows/utils.h" -#include "platform/public/logging.h" - -namespace location { -namespace nearby { -namespace windows { - -BluetoothClassicMedium::BluetoothClassicMedium( - api::BluetoothAdapter& bluetoothAdapter) - : bluetooth_adapter_(dynamic_cast(bluetoothAdapter)) { - InitializeCriticalSection(&critical_section_); - - InitializeDeviceWatcher(); - - bluetooth_adapter_.SetOnScanModeChanged(std::bind( - &BluetoothClassicMedium::OnScanModeChanged, this, std::placeholders::_1)); -} - -BluetoothClassicMedium::~BluetoothClassicMedium() {} - -void BluetoothClassicMedium::OnScanModeChanged( - BluetoothAdapter::ScanMode scanMode) { - scan_mode_ = scanMode; - bool radioDiscoverable = bluetooth_adapter_.GetScanMode() == - BluetoothAdapter::ScanMode::kConnectableDiscoverable; - - if (bluetooth_server_socket_ != nullptr) { - bluetooth_server_socket_->SetScanMode(radioDiscoverable); - } -} - -bool BluetoothClassicMedium::StartDiscovery( - BluetoothClassicMedium::DiscoveryCallback discovery_callback) { - EnterCriticalSection(&critical_section_); - - bool result = false; - discovery_callback_ = discovery_callback; - - if (!IsWatcherStarted()) { - result = StartScanning(); - } - - LeaveCriticalSection(&critical_section_); - - return result; -} - -bool BluetoothClassicMedium::StopDiscovery() { - EnterCriticalSection(&critical_section_); - - bool result = false; - - if (IsWatcherStarted()) { - result = StopScanning(); - } - - LeaveCriticalSection(&critical_section_); - - return result; -} - -void BluetoothClassicMedium::InitializeDeviceWatcher() { - // create watcher - device_watcher_ = DeviceInformation::CreateWatcher( - BLUETOOTH_SELECTOR, // aqsFilter - nullptr, // additionalProperties - DeviceInformationKind::AssociationEndpoint); // kind - - // An app must subscribe to all of the added, removed, and updated events to - // be notified when there are device additions, removals or updates. If an - // app handles only the added event, it will not receive an update if a - // device is added to the system after the initial device enumeration - // completes. register event handlers before starting the watcher - - // Event that is raised when a device is added to the collection enumerated - // by the DeviceWatcher. - // https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcher.added?view=winrt-20348 - device_watcher_.Added({this, &BluetoothClassicMedium::DeviceWatcher_Added}); - - // Event that is raised when a device is updated in the collection of - // enumerated devices. - // https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcher.updated?view=winrt-20348 - device_watcher_.Updated( - {this, &BluetoothClassicMedium::DeviceWatcher_Updated}); - - // Event that is raised when a device is removed from the collection of - // enumerated devices. - // https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcher.removed?view=winrt-20348 - device_watcher_.Removed( - {this, &BluetoothClassicMedium::DeviceWatcher_Removed}); -} - -std::unique_ptr BluetoothClassicMedium::ConnectToService( - api::BluetoothDevice& remote_device, const std::string& service_uuid, - CancellationFlag* cancellation_flag) { - if (service_uuid.empty()) { - NEARBY_LOGS(ERROR) << __func__ << ": service_uuid not specified."; - return nullptr; - } - - const std::regex pattern( - "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]" - "{12}$"); - - // Must check for valid pattern as the guid constructor will throw on an - // invalid format - if (!regex_match(service_uuid, pattern)) { - NEARBY_LOGS(ERROR) << __func__ - << ": invalid service_uuid: " << service_uuid; - return nullptr; - } - - winrt::guid service(service_uuid); - - if (cancellation_flag == nullptr) { - NEARBY_LOGS(ERROR) << __func__ << ": cancellation_flag not specified."; - return nullptr; - } - - BluetoothDevice* currentDevice = - dynamic_cast(&remote_device); - - if (currentDevice == nullptr) { - NEARBY_LOGS(ERROR) << __func__ << ": Failed to get current device."; - return nullptr; - } - - winrt::hstring deviceId = winrt::to_hstring(currentDevice->GetId()); - - if (!HaveAccess(deviceId)) { - NEARBY_LOGS(ERROR) << __func__ << ": Failed to gain access to device: " - << winrt::to_string(deviceId); - return nullptr; - } - - RfcommDeviceService requestedService( - GetRequestedService(currentDevice, service)); - - if (!CheckSdp(requestedService)) { - NEARBY_LOGS(ERROR) << __func__ << ": Invalid SDP."; - return nullptr; - } - - device_watcher_.Stop(); - - EnterCriticalSection(&critical_section_); - - std::unique_ptr rfcommSocket = - std::make_unique(); - - location::nearby::CancellationFlagListener cancellationFlagListener( - cancellation_flag, - [&rfcommSocket]() { rfcommSocket.get()->CancelIOAsync().get(); }); - - try { - rfcommSocket->Connect(requestedService.ConnectionHostName(), - requestedService.ConnectionServiceName()); - } catch (std::exception exception) { - // We will log and eat the exception since the caller - // expects nullptr if it fails - NEARBY_LOGS(ERROR) << __func__ << ": Exception connecting bluetooth async: " - << exception.what(); - - LeaveCriticalSection(&critical_section_); - - return nullptr; - } - - LeaveCriticalSection(&critical_section_); - - return rfcommSocket; -} - -bool BluetoothClassicMedium::HaveAccess(winrt::hstring deviceId) { - DeviceAccessStatus accessStatus = - DeviceAccessInformation::CreateFromId(deviceId).CurrentStatus(); - - if (accessStatus == DeviceAccessStatus::DeniedByUser || - // This status is most likely caused by app permissions (did not declare - // the device in the app's package.appxmanifest) - // This status does not cover the case where the device is already opened - // by another app. - accessStatus == DeviceAccessStatus::DeniedBySystem || - // Most likely the device is opened by another app, but cannot be sure - accessStatus == DeviceAccessStatus::Unspecified) { - return false; - } - - return true; -} - -RfcommDeviceService BluetoothClassicMedium::GetRequestedService( - BluetoothDevice* device, winrt::guid service) { - RfcommServiceId rfcommServiceId = RfcommServiceId::FromUuid(service); - - // Retrieves all Rfcomm Services on the Remote Bluetooth Device matching the - // specified RfcommServiceId. - // https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.bluetoothdevice.getrfcommservicesforidasync?view=winrt-20348 - IAsyncOperation rfcommServices = - device->GetRfcommServicesForIdAsync(rfcommServiceId); - - RfcommDeviceService requestedService(nullptr); - - if (rfcommServices.get().Services().Size() > 0) { - requestedService = rfcommServices.get().Services().GetAt(0); - } else { - NEARBY_LOGS(ERROR) << __func__ << ": No services found."; - return nullptr; - } - - return requestedService; -} - -bool BluetoothClassicMedium::CheckSdp(RfcommDeviceService requestedService) { - // Do various checks of the SDP record to make sure you are talking to a - // device that actually supports the Bluetooth Rfcomm Service - // https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.rfcomm.rfcommdeviceservice.getsdprawattributesasync?view=winrt-20348 - auto attributes = requestedService.GetSdpRawAttributesAsync().get(); - if (!attributes.HasKey(Constants::SdpServiceNameAttributeId)) { - NEARBY_LOGS(ERROR) << __func__ << ": Missing SdpServiceNameAttributeId."; - return false; - } - - auto attributeReader = DataReader::FromBuffer( - attributes.Lookup(Constants::SdpServiceNameAttributeId)); - - auto attributeType = attributeReader.ReadByte(); - - if (attributeType != Constants::SdpServiceNameAttributeType) { - NEARBY_LOGS(ERROR) << __func__ << ": Missing SdpServiceNameAttributeType."; - return false; - } - - return true; -} -// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#listenUsingInsecureRfcommWithServiceRecord -// -// service_uuid is the canonical textual representation -// (https://en.wikipedia.org/wiki/Universally_unique_identifier#Format) of a -// type 3 name-based -// (https://en.wikipedia.org/wiki/Universally_unique_identifier#Versions_3_and_5_(namespace_name-based)) -// UUID. -// -// Returns nullptr error. -std::unique_ptr -BluetoothClassicMedium::ListenForService(const std::string& service_name, - const std::string& service_uuid) { - if (service_uuid.empty()) { - NEARBY_LOGS(ERROR) << __func__ << ": service_uuid was empty."; - return nullptr; - } - - if (service_name.empty()) { - NEARBY_LOGS(ERROR) << __func__ << ": service_name was empty."; - return nullptr; - } - - auto bluetooth_server_socket = - std::make_unique( - service_name, service_uuid); - - if (bluetooth_server_socket == nullptr) { - NEARBY_LOGS(ERROR) << __func__ << ": Failed to create the server socket."; - return nullptr; - } - - bool radioDiscoverable = bluetooth_adapter_.GetScanMode() == - BluetoothAdapter::ScanMode::kConnectableDiscoverable; - - Exception result = bluetooth_server_socket->StartListening(radioDiscoverable); - - if (result.value != Exception::kSuccess) { - NEARBY_LOGS(ERROR) << __func__ << ": Failed to start listening."; - return nullptr; - } - - return std::move(bluetooth_server_socket); -} - -api::BluetoothDevice* BluetoothClassicMedium::GetRemoteDevice( - const std::string& mac_address) { - return new BluetoothDevice(mac_address); -} - -bool BluetoothClassicMedium::StartScanning() { - if (!IsWatcherStarted()) { - // The Start method can only be called when the DeviceWatcher is in the - // Created, Stopped or Aborted state. - auto status = device_watcher_.Status(); - - if (status == DeviceWatcherStatus::Created || - status == DeviceWatcherStatus::Stopped || - status == DeviceWatcherStatus::Aborted) { - device_watcher_.Start(); - - return true; - } - } - - NEARBY_LOGS(ERROR) - << __func__ - << ": Attempted to start scanning when watcher already started."; - return false; -} - -bool BluetoothClassicMedium::StopScanning() { - if (IsWatcherRunning()) { - device_watcher_.Stop(); - return true; - } - NEARBY_LOGS(ERROR) - << __func__ - << ": Attempted to stop scanning when watcher already stopped."; - return false; -} - -winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Added( - DeviceWatcher sender, DeviceInformation deviceInfo) { - if (IsWatcherStarted()) { - // Represents a Bluetooth device. - // https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.bluetoothdevice?view=winrt-20348 - std::unique_ptr - windowsBluetoothDevice; - - // Create an iterator for the internal list - std::map>::const_iterator - it = devices_by_id_.find(deviceInfo.Id()); - - // Add to our internal list if necessary - if (it == devices_by_id_.end()) { - // Create a bluetooth device out of this id - winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromIdAsync( - deviceInfo.Id()) - .Completed( - [this, deviceInfo, wbd = std::move(windowsBluetoothDevice)]( - auto&& async, - winrt::Windows::Foundation::AsyncStatus status) { - EnterCriticalSection(&critical_section_); - - std::unique_ptr bluetoothDevice = - std::make_unique(async.get()); - - devices_by_id_[deviceInfo.Id()] = std::move(bluetoothDevice); - - if (discovery_callback_.device_discovered_cb != nullptr) { - discovery_callback_.device_discovered_cb( - *devices_by_id_[deviceInfo.Id()]); - } - - LeaveCriticalSection(&critical_section_); - }); - } - } - - return winrt::fire_and_forget(); -} - -winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Updated( - DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate) { - if (IsWatcherStarted()) { - // TODO(jfcarroll): Check for device name change - } - - return winrt::fire_and_forget(); -} - -winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Removed( - DeviceWatcher sender, DeviceInformationUpdate deviceInfo) { - EnterCriticalSection(&critical_section_); - - if (IsWatcherStarted()) { - if (discovery_callback_.device_lost_cb != nullptr) { - discovery_callback_.device_lost_cb(*devices_by_id_[deviceInfo.Id()]); - } - - devices_by_id_.erase(deviceInfo.Id()); - } - - LeaveCriticalSection(&critical_section_); - - return winrt::fire_and_forget(); -} - -bool BluetoothClassicMedium::IsWatcherStarted() { - if (device_watcher_ == nullptr) { - return false; - } - - DeviceWatcherStatus status = device_watcher_.Status(); - return (status == DeviceWatcherStatus::Started) || - (status == DeviceWatcherStatus::EnumerationCompleted); -} - -bool BluetoothClassicMedium::IsWatcherRunning() { - if (device_watcher_ == nullptr) { - return false; - } - - DeviceWatcherStatus status = device_watcher_.Status(); - return (status == DeviceWatcherStatus::Started) || - (status == DeviceWatcherStatus::EnumerationCompleted) || - (status == DeviceWatcherStatus::Stopping); -} - -} // namespace windows -} // namespace nearby -} // namespace location +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "platform/impl/windows/bluetooth_classic_medium.h" + +#include +#include + +#include +#include +#include // NOLINT +#include + +#include "platform/base/cancellation_flag.h" +#include "platform/base/cancellation_flag_listener.h" +#include "platform/base/exception.h" +#include "platform/impl/windows/bluetooth_adapter.h" +#include "platform/impl/windows/bluetooth_classic_device.h" +#include "platform/impl/windows/bluetooth_classic_server_socket.h" +#include "platform/impl/windows/bluetooth_classic_socket.h" +#include "platform/impl/windows/generated/winrt/Windows.Devices.Bluetooth.Rfcomm.h" +#include "platform/impl/windows/generated/winrt/Windows.Devices.Bluetooth.h" +#include "platform/impl/windows/generated/winrt/Windows.Devices.Enumeration.h" +#include "platform/impl/windows/generated/winrt/Windows.Foundation.Collections.h" +#include "platform/impl/windows/generated/winrt/base.h" +#include "platform/impl/windows/utils.h" +#include "platform/public/logging.h" + +namespace location { +namespace nearby { +namespace windows { + +BluetoothClassicMedium::BluetoothClassicMedium( + api::BluetoothAdapter& bluetoothAdapter) + : bluetooth_adapter_(dynamic_cast(bluetoothAdapter)) { + InitializeCriticalSection(&critical_section_); + + InitializeDeviceWatcher(); + + bluetooth_adapter_.SetOnScanModeChanged(std::bind( + &BluetoothClassicMedium::OnScanModeChanged, this, std::placeholders::_1)); +} + +BluetoothClassicMedium::~BluetoothClassicMedium() {} + +void BluetoothClassicMedium::OnScanModeChanged( + BluetoothAdapter::ScanMode scanMode) { + scan_mode_ = scanMode; + bool radioDiscoverable = bluetooth_adapter_.GetScanMode() == + BluetoothAdapter::ScanMode::kConnectableDiscoverable; + + if (bluetooth_server_socket_ != nullptr) { + bluetooth_server_socket_->SetScanMode(radioDiscoverable); + } +} + +bool BluetoothClassicMedium::StartDiscovery( + BluetoothClassicMedium::DiscoveryCallback discovery_callback) { + EnterCriticalSection(&critical_section_); + + bool result = false; + discovery_callback_ = discovery_callback; + + if (!IsWatcherStarted()) { + result = StartScanning(); + } + + LeaveCriticalSection(&critical_section_); + + return result; +} + +bool BluetoothClassicMedium::StopDiscovery() { + EnterCriticalSection(&critical_section_); + + bool result = false; + + if (IsWatcherStarted()) { + result = StopScanning(); + } + + LeaveCriticalSection(&critical_section_); + + return result; +} + +void BluetoothClassicMedium::InitializeDeviceWatcher() { + // create watcher + device_watcher_ = DeviceInformation::CreateWatcher( + BLUETOOTH_SELECTOR, // aqsFilter + nullptr, // additionalProperties + DeviceInformationKind::AssociationEndpoint); // kind + + // An app must subscribe to all of the added, removed, and updated events to + // be notified when there are device additions, removals or updates. If an + // app handles only the added event, it will not receive an update if a + // device is added to the system after the initial device enumeration + // completes. register event handlers before starting the watcher + + // Event that is raised when a device is added to the collection enumerated + // by the DeviceWatcher. + // https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcher.added?view=winrt-20348 + device_watcher_.Added({this, &BluetoothClassicMedium::DeviceWatcher_Added}); + + // Event that is raised when a device is updated in the collection of + // enumerated devices. + // https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcher.updated?view=winrt-20348 + device_watcher_.Updated( + {this, &BluetoothClassicMedium::DeviceWatcher_Updated}); + + // Event that is raised when a device is removed from the collection of + // enumerated devices. + // https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcher.removed?view=winrt-20348 + device_watcher_.Removed( + {this, &BluetoothClassicMedium::DeviceWatcher_Removed}); +} + +std::unique_ptr BluetoothClassicMedium::ConnectToService( + api::BluetoothDevice& remote_device, const std::string& service_uuid, + CancellationFlag* cancellation_flag) { + if (service_uuid.empty()) { + NEARBY_LOGS(ERROR) << __func__ << ": service_uuid not specified."; + return nullptr; + } + + const std::regex pattern( + "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]" + "{12}$"); + + // Must check for valid pattern as the guid constructor will throw on an + // invalid format + if (!regex_match(service_uuid, pattern)) { + NEARBY_LOGS(ERROR) << __func__ + << ": invalid service_uuid: " << service_uuid; + return nullptr; + } + + winrt::guid service(service_uuid); + + if (cancellation_flag == nullptr) { + NEARBY_LOGS(ERROR) << __func__ << ": cancellation_flag not specified."; + return nullptr; + } + + BluetoothDevice* currentDevice = + dynamic_cast(&remote_device); + + if (currentDevice == nullptr) { + NEARBY_LOGS(ERROR) << __func__ << ": Failed to get current device."; + return nullptr; + } + + winrt::hstring deviceId = winrt::to_hstring(currentDevice->GetId()); + + if (!HaveAccess(deviceId)) { + NEARBY_LOGS(ERROR) << __func__ << ": Failed to gain access to device: " + << winrt::to_string(deviceId); + return nullptr; + } + + RfcommDeviceService requestedService( + GetRequestedService(currentDevice, service)); + + if (!CheckSdp(requestedService)) { + NEARBY_LOGS(ERROR) << __func__ << ": Invalid SDP."; + return nullptr; + } + + device_watcher_.Stop(); + + EnterCriticalSection(&critical_section_); + + std::unique_ptr rfcommSocket = + std::make_unique(); + + location::nearby::CancellationFlagListener cancellationFlagListener( + cancellation_flag, + [&rfcommSocket]() { rfcommSocket.get()->CancelIOAsync().get(); }); + + try { + rfcommSocket->Connect(requestedService.ConnectionHostName(), + requestedService.ConnectionServiceName()); + } catch (std::exception exception) { + // We will log and eat the exception since the caller + // expects nullptr if it fails + NEARBY_LOGS(ERROR) << __func__ << ": Exception connecting bluetooth async: " + << exception.what(); + + LeaveCriticalSection(&critical_section_); + + return nullptr; + } + + LeaveCriticalSection(&critical_section_); + + return rfcommSocket; +} + +bool BluetoothClassicMedium::HaveAccess(winrt::hstring deviceId) { + DeviceAccessStatus accessStatus = + DeviceAccessInformation::CreateFromId(deviceId).CurrentStatus(); + + if (accessStatus == DeviceAccessStatus::DeniedByUser || + // This status is most likely caused by app permissions (did not declare + // the device in the app's package.appxmanifest) + // This status does not cover the case where the device is already opened + // by another app. + accessStatus == DeviceAccessStatus::DeniedBySystem || + // Most likely the device is opened by another app, but cannot be sure + accessStatus == DeviceAccessStatus::Unspecified) { + return false; + } + + return true; +} + +RfcommDeviceService BluetoothClassicMedium::GetRequestedService( + BluetoothDevice* device, winrt::guid service) { + RfcommServiceId rfcommServiceId = RfcommServiceId::FromUuid(service); + + // Retrieves all Rfcomm Services on the Remote Bluetooth Device matching the + // specified RfcommServiceId. + // https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.bluetoothdevice.getrfcommservicesforidasync?view=winrt-20348 + IAsyncOperation rfcommServices = + device->GetRfcommServicesForIdAsync(rfcommServiceId); + + RfcommDeviceService requestedService(nullptr); + + if (rfcommServices.get().Services().Size() > 0) { + requestedService = rfcommServices.get().Services().GetAt(0); + } else { + NEARBY_LOGS(ERROR) << __func__ << ": No services found."; + return nullptr; + } + + return requestedService; +} + +bool BluetoothClassicMedium::CheckSdp(RfcommDeviceService requestedService) { + // Do various checks of the SDP record to make sure you are talking to a + // device that actually supports the Bluetooth Rfcomm Service + // https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.rfcomm.rfcommdeviceservice.getsdprawattributesasync?view=winrt-20348 + auto attributes = requestedService.GetSdpRawAttributesAsync().get(); + if (!attributes.HasKey(Constants::SdpServiceNameAttributeId)) { + NEARBY_LOGS(ERROR) << __func__ << ": Missing SdpServiceNameAttributeId."; + return false; + } + + auto attributeReader = DataReader::FromBuffer( + attributes.Lookup(Constants::SdpServiceNameAttributeId)); + + auto attributeType = attributeReader.ReadByte(); + + if (attributeType != Constants::SdpServiceNameAttributeType) { + NEARBY_LOGS(ERROR) << __func__ << ": Missing SdpServiceNameAttributeType."; + return false; + } + + return true; +} +// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#listenUsingInsecureRfcommWithServiceRecord +// +// service_uuid is the canonical textual representation +// (https://en.wikipedia.org/wiki/Universally_unique_identifier#Format) of a +// type 3 name-based +// (https://en.wikipedia.org/wiki/Universally_unique_identifier#Versions_3_and_5_(namespace_name-based)) +// UUID. +// +// Returns nullptr error. +std::unique_ptr +BluetoothClassicMedium::ListenForService(const std::string& service_name, + const std::string& service_uuid) { + if (service_uuid.empty()) { + NEARBY_LOGS(ERROR) << __func__ << ": service_uuid was empty."; + return nullptr; + } + + if (service_name.empty()) { + NEARBY_LOGS(ERROR) << __func__ << ": service_name was empty."; + return nullptr; + } + + auto bluetooth_server_socket = + std::make_unique( + service_name, service_uuid); + + if (bluetooth_server_socket == nullptr) { + NEARBY_LOGS(ERROR) << __func__ << ": Failed to create the server socket."; + return nullptr; + } + + bool radioDiscoverable = bluetooth_adapter_.GetScanMode() == + BluetoothAdapter::ScanMode::kConnectableDiscoverable; + + Exception result = bluetooth_server_socket->StartListening(radioDiscoverable); + + if (result.value != Exception::kSuccess) { + NEARBY_LOGS(ERROR) << __func__ << ": Failed to start listening."; + return nullptr; + } + + return std::move(bluetooth_server_socket); +} + +api::BluetoothDevice* BluetoothClassicMedium::GetRemoteDevice( + const std::string& mac_address) { + return new BluetoothDevice(mac_address); +} + +bool BluetoothClassicMedium::StartScanning() { + if (!IsWatcherStarted()) { + // The Start method can only be called when the DeviceWatcher is in the + // Created, Stopped or Aborted state. + auto status = device_watcher_.Status(); + + if (status == DeviceWatcherStatus::Created || + status == DeviceWatcherStatus::Stopped || + status == DeviceWatcherStatus::Aborted) { + device_watcher_.Start(); + + return true; + } + } + + NEARBY_LOGS(ERROR) + << __func__ + << ": Attempted to start scanning when watcher already started."; + return false; +} + +bool BluetoothClassicMedium::StopScanning() { + if (IsWatcherRunning()) { + device_watcher_.Stop(); + return true; + } + NEARBY_LOGS(ERROR) + << __func__ + << ": Attempted to stop scanning when watcher already stopped."; + return false; +} + +winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Added( + DeviceWatcher sender, DeviceInformation deviceInfo) { + if (IsWatcherStarted()) { + // Represents a Bluetooth device. + // https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.bluetoothdevice?view=winrt-20348 + std::unique_ptr + windowsBluetoothDevice; + + // Create an iterator for the internal list + std::map>::const_iterator + it = devices_by_id_.find(deviceInfo.Id()); + + // Add to our internal list if necessary + if (it == devices_by_id_.end()) { + // Create a bluetooth device out of this id + winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromIdAsync( + deviceInfo.Id()) + .Completed( + [this, deviceInfo, wbd = std::move(windowsBluetoothDevice)]( + auto&& async, + winrt::Windows::Foundation::AsyncStatus status) { + EnterCriticalSection(&critical_section_); + + std::unique_ptr bluetoothDevice = + std::make_unique(async.get()); + + devices_by_id_[deviceInfo.Id()] = std::move(bluetoothDevice); + + if (discovery_callback_.device_discovered_cb != nullptr) { + discovery_callback_.device_discovered_cb( + *devices_by_id_[deviceInfo.Id()]); + } + + LeaveCriticalSection(&critical_section_); + }); + } + } + + return winrt::fire_and_forget(); +} + +winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Updated( + DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate) { + if (IsWatcherStarted()) { + // TODO(jfcarroll): Check for device name change + } + + return winrt::fire_and_forget(); +} + +winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Removed( + DeviceWatcher sender, DeviceInformationUpdate deviceInfo) { + EnterCriticalSection(&critical_section_); + + if (IsWatcherStarted()) { + if (discovery_callback_.device_lost_cb != nullptr) { + discovery_callback_.device_lost_cb(*devices_by_id_[deviceInfo.Id()]); + } + + devices_by_id_.erase(deviceInfo.Id()); + } + + LeaveCriticalSection(&critical_section_); + + return winrt::fire_and_forget(); +} + +bool BluetoothClassicMedium::IsWatcherStarted() { + if (device_watcher_ == nullptr) { + return false; + } + + DeviceWatcherStatus status = device_watcher_.Status(); + return (status == DeviceWatcherStatus::Started) || + (status == DeviceWatcherStatus::EnumerationCompleted); +} + +bool BluetoothClassicMedium::IsWatcherRunning() { + if (device_watcher_ == nullptr) { + return false; + } + + DeviceWatcherStatus status = device_watcher_.Status(); + return (status == DeviceWatcherStatus::Started) || + (status == DeviceWatcherStatus::EnumerationCompleted) || + (status == DeviceWatcherStatus::Stopping); +} + +} // namespace windows +} // namespace nearby +} // namespace location diff --git a/cpp/platform/impl/windows/bluetooth_classic_medium.h b/cpp/platform/impl/windows/bluetooth_classic_medium.h index 09b39263..a5d96926 100644 --- a/cpp/platform/impl/windows/bluetooth_classic_medium.h +++ b/cpp/platform/impl/windows/bluetooth_classic_medium.h @@ -1,191 +1,191 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_MEDIUM_H_ -#define PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_MEDIUM_H_ - -#include "platform/api/bluetooth_classic.h" -#include "platform/impl/windows/bluetooth_adapter.h" -#include "platform/impl/windows/bluetooth_classic_device.h" -#include "platform/impl/windows/bluetooth_classic_server_socket.h" -#include "platform/impl/windows/bluetooth_classic_socket.h" -#include "platform/impl/windows/generated/winrt/Windows.Devices.Enumeration.h" -#include "platform/impl/windows/generated/winrt/Windows.Networking.Sockets.h" -#include "platform/impl/windows/generated/winrt/base.h" - -namespace location { -namespace nearby { -namespace windows { - -// Represents a device. This class allows access to well-known device properties -// as well as additional properties specified during device enumeration. -// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.deviceinformation?view=winrt-20348 -using winrt::Windows::Devices::Enumeration::DeviceInformation; - -// Represents the kind of DeviceInformation object. -// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.deviceinformationkind?view=winrt-20348 -using winrt::Windows::Devices::Enumeration::DeviceInformationKind; - -// Contains updated properties for a DeviceInformation object. -// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.deviceinformationupdate?view=winrt-20348 -using winrt::Windows::Devices::Enumeration::DeviceInformationUpdate; - -// Enumerates devices dynamically, so that the app receives notifications if -// devices are added, removed, or changed after the initial enumeration is -// complete. -// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcher?view=winrt-20348 -using winrt::Windows::Devices::Enumeration::DeviceWatcher; - -// Describes the state of a DeviceWatcher object. -// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcherstatus?view=winrt-20348 -using winrt::Windows::Devices::Enumeration::DeviceWatcherStatus; - -// Represents an instance of a service on a Bluetooth basic rate device. -// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.rfcomm.rfcommdeviceservice?view=winrt-20348 -using winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommDeviceService; - -// Indicates the status of the access to a device. -// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.deviceaccessstatus?view=winrt-20348 -using winrt::Windows::Devices::Enumeration::DeviceAccessStatus; - -// Contains the information about access to a device. -// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.deviceaccessinformation?view=winrt-20348 -using winrt::Windows::Devices::Enumeration::DeviceAccessInformation; - -// Represents an RFCOMM service ID. -// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.rfcomm.rfcommserviceid?view=winrt-20348 -using winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommServiceId; - -// Reads data from an input stream. -// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.datareader?view=winrt-20348 -using winrt::Windows::Storage::Streams::DataReader; - -// Writes data to an output stream. -// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.datawriter?view=winrt-20348 -using winrt::Windows::Storage::Streams::DataWriter; - -// Bluetooth protocol ID = \"{e0cbf06c-cd8b-4647-bb8a-263b43f0f974}\" -// https://docs.microsoft.com/en-us/windows/uwp/devices-sensors/aep-service-class-ids -#define BLUETOOTH_SELECTOR \ - L"System.Devices.Aep.ProtocolId:=\"{e0cbf06c-cd8b-4647-bb8a-263b43f0f974}\"" - -// Container of operations that can be performed over the Bluetooth Classic -// medium. -class BluetoothClassicMedium : public api::BluetoothClassicMedium { - public: - BluetoothClassicMedium(api::BluetoothAdapter& bluetoothAdapter); - - ~BluetoothClassicMedium() override; - - // https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#startDiscovery() - bool StartDiscovery(DiscoveryCallback discovery_callback) override; - - // https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#cancelDiscovery() - // - // Returns true once discovery is well and truly stopped; after this returns, - // there must be no more invocations of the DiscoveryCallback passed in to - // StartDiscovery(). - bool StopDiscovery() override; - - // A combination of - // https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#createInsecureRfcommSocketToServiceRecord - // followed by - // https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html#connect(). - // - // service_uuid is the canonical textual representation - // (https://en.wikipedia.org/wiki/Universally_unique_identifier#Format) of a - // type 3 name-based - // (https://en.wikipedia.org/wiki/Universally_unique_identifier#Versions_3_and_5_(namespace_name-based)) - // UUID. - // - // On success, returns a new BluetoothSocket. - // On error, throw's an exception - std::unique_ptr ConnectToService( - api::BluetoothDevice& remote_device, const std::string& service_uuid, - CancellationFlag* cancellation_flag) override; - - // https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#listenUsingInsecureRfcommWithServiceRecord - // - // service_uuid is the canonical textual representation - // (https://en.wikipedia.org/wiki/Universally_unique_identifier#Format) of a - // type 3 name-based - // (https://en.wikipedia.org/wiki/Universally_unique_identifier#Versions_3_and_5_(namespace_name-based)) - // UUID. - // - // Returns nullptr error. - std::unique_ptr ListenForService( - const std::string& service_name, - const std::string& service_uuid) override; - - api::BluetoothDevice* GetRemoteDevice( - const std::string& mac_address) override; - - private: - bool StartScanning(); - bool StopScanning(); - bool IsWatcherStarted(); - bool IsWatcherRunning(); - void InitializeDeviceWatcher(); - void OnScanModeChanged(BluetoothAdapter::ScanMode scanMode); - - // This is for a coroutine whose return type is winrt::fire_and_forget, which - // handles async operations which don't have any dependencies. - // https://docs.microsoft.com/en-us/uwp/cpp-ref-for-winrt/fire-and-forget - winrt::fire_and_forget DeviceWatcher_Added(DeviceWatcher sender, - DeviceInformation deviceInfo); - - winrt::fire_and_forget DeviceWatcher_Updated( - DeviceWatcher sender, DeviceInformationUpdate deviceInfo); - - winrt::fire_and_forget DeviceWatcher_Removed( - DeviceWatcher sender, DeviceInformationUpdate deviceInfo); - - // Check to make sure we can connect if we try - bool HaveAccess(winrt::hstring deviceId); - - // Get the service requested - RfcommDeviceService GetRequestedService(BluetoothDevice* device, - winrt::guid service); - - // Check to see that the device actually handles the requested service - bool CheckSdp(RfcommDeviceService requestedService); - - BluetoothClassicMedium::DiscoveryCallback discovery_callback_; - - DeviceWatcher device_watcher_ = nullptr; - - std::unique_ptr bluetooth_socket_; - std::unique_ptr bluetooth_server_socket_; - - std::string service_name_; - std::string service_uuid_; - - // hstring is the only type of string winrt understands. - // https://docs.microsoft.com/en-us/uwp/cpp-ref-for-winrt/hstring - std::map> devices_by_id_; - - // CRITICAL_SECTION is a lightweight synchronization mechanism - // https://docs.microsoft.com/en-us/windows/win32/sync/critical-section-objects - CRITICAL_SECTION critical_section_; - - BluetoothAdapter& bluetooth_adapter_; - - BluetoothAdapter::ScanMode scan_mode_; -}; - -} // namespace windows -} // namespace nearby -} // namespace location - -#endif // PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_MEDIUM_H_ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_MEDIUM_H_ +#define PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_MEDIUM_H_ + +#include "platform/api/bluetooth_classic.h" +#include "platform/impl/windows/bluetooth_adapter.h" +#include "platform/impl/windows/bluetooth_classic_device.h" +#include "platform/impl/windows/bluetooth_classic_server_socket.h" +#include "platform/impl/windows/bluetooth_classic_socket.h" +#include "platform/impl/windows/generated/winrt/Windows.Devices.Enumeration.h" +#include "platform/impl/windows/generated/winrt/Windows.Networking.Sockets.h" +#include "platform/impl/windows/generated/winrt/base.h" + +namespace location { +namespace nearby { +namespace windows { + +// Represents a device. This class allows access to well-known device properties +// as well as additional properties specified during device enumeration. +// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.deviceinformation?view=winrt-20348 +using winrt::Windows::Devices::Enumeration::DeviceInformation; + +// Represents the kind of DeviceInformation object. +// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.deviceinformationkind?view=winrt-20348 +using winrt::Windows::Devices::Enumeration::DeviceInformationKind; + +// Contains updated properties for a DeviceInformation object. +// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.deviceinformationupdate?view=winrt-20348 +using winrt::Windows::Devices::Enumeration::DeviceInformationUpdate; + +// Enumerates devices dynamically, so that the app receives notifications if +// devices are added, removed, or changed after the initial enumeration is +// complete. +// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcher?view=winrt-20348 +using winrt::Windows::Devices::Enumeration::DeviceWatcher; + +// Describes the state of a DeviceWatcher object. +// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcherstatus?view=winrt-20348 +using winrt::Windows::Devices::Enumeration::DeviceWatcherStatus; + +// Represents an instance of a service on a Bluetooth basic rate device. +// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.rfcomm.rfcommdeviceservice?view=winrt-20348 +using winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommDeviceService; + +// Indicates the status of the access to a device. +// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.deviceaccessstatus?view=winrt-20348 +using winrt::Windows::Devices::Enumeration::DeviceAccessStatus; + +// Contains the information about access to a device. +// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.deviceaccessinformation?view=winrt-20348 +using winrt::Windows::Devices::Enumeration::DeviceAccessInformation; + +// Represents an RFCOMM service ID. +// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.rfcomm.rfcommserviceid?view=winrt-20348 +using winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommServiceId; + +// Reads data from an input stream. +// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.datareader?view=winrt-20348 +using winrt::Windows::Storage::Streams::DataReader; + +// Writes data to an output stream. +// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.datawriter?view=winrt-20348 +using winrt::Windows::Storage::Streams::DataWriter; + +// Bluetooth protocol ID = \"{e0cbf06c-cd8b-4647-bb8a-263b43f0f974}\" +// https://docs.microsoft.com/en-us/windows/uwp/devices-sensors/aep-service-class-ids +#define BLUETOOTH_SELECTOR \ + L"System.Devices.Aep.ProtocolId:=\"{e0cbf06c-cd8b-4647-bb8a-263b43f0f974}\"" + +// Container of operations that can be performed over the Bluetooth Classic +// medium. +class BluetoothClassicMedium : public api::BluetoothClassicMedium { + public: + BluetoothClassicMedium(api::BluetoothAdapter& bluetoothAdapter); + + ~BluetoothClassicMedium() override; + + // https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#startDiscovery() + bool StartDiscovery(DiscoveryCallback discovery_callback) override; + + // https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#cancelDiscovery() + // + // Returns true once discovery is well and truly stopped; after this returns, + // there must be no more invocations of the DiscoveryCallback passed in to + // StartDiscovery(). + bool StopDiscovery() override; + + // A combination of + // https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#createInsecureRfcommSocketToServiceRecord + // followed by + // https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html#connect(). + // + // service_uuid is the canonical textual representation + // (https://en.wikipedia.org/wiki/Universally_unique_identifier#Format) of a + // type 3 name-based + // (https://en.wikipedia.org/wiki/Universally_unique_identifier#Versions_3_and_5_(namespace_name-based)) + // UUID. + // + // On success, returns a new BluetoothSocket. + // On error, throw's an exception + std::unique_ptr ConnectToService( + api::BluetoothDevice& remote_device, const std::string& service_uuid, + CancellationFlag* cancellation_flag) override; + + // https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#listenUsingInsecureRfcommWithServiceRecord + // + // service_uuid is the canonical textual representation + // (https://en.wikipedia.org/wiki/Universally_unique_identifier#Format) of a + // type 3 name-based + // (https://en.wikipedia.org/wiki/Universally_unique_identifier#Versions_3_and_5_(namespace_name-based)) + // UUID. + // + // Returns nullptr error. + std::unique_ptr ListenForService( + const std::string& service_name, + const std::string& service_uuid) override; + + api::BluetoothDevice* GetRemoteDevice( + const std::string& mac_address) override; + + private: + bool StartScanning(); + bool StopScanning(); + bool IsWatcherStarted(); + bool IsWatcherRunning(); + void InitializeDeviceWatcher(); + void OnScanModeChanged(BluetoothAdapter::ScanMode scanMode); + + // This is for a coroutine whose return type is winrt::fire_and_forget, which + // handles async operations which don't have any dependencies. + // https://docs.microsoft.com/en-us/uwp/cpp-ref-for-winrt/fire-and-forget + winrt::fire_and_forget DeviceWatcher_Added(DeviceWatcher sender, + DeviceInformation deviceInfo); + + winrt::fire_and_forget DeviceWatcher_Updated( + DeviceWatcher sender, DeviceInformationUpdate deviceInfo); + + winrt::fire_and_forget DeviceWatcher_Removed( + DeviceWatcher sender, DeviceInformationUpdate deviceInfo); + + // Check to make sure we can connect if we try + bool HaveAccess(winrt::hstring deviceId); + + // Get the service requested + RfcommDeviceService GetRequestedService(BluetoothDevice* device, + winrt::guid service); + + // Check to see that the device actually handles the requested service + bool CheckSdp(RfcommDeviceService requestedService); + + BluetoothClassicMedium::DiscoveryCallback discovery_callback_; + + DeviceWatcher device_watcher_ = nullptr; + + std::unique_ptr bluetooth_socket_; + std::unique_ptr bluetooth_server_socket_; + + std::string service_name_; + std::string service_uuid_; + + // hstring is the only type of string winrt understands. + // https://docs.microsoft.com/en-us/uwp/cpp-ref-for-winrt/hstring + std::map> devices_by_id_; + + // CRITICAL_SECTION is a lightweight synchronization mechanism + // https://docs.microsoft.com/en-us/windows/win32/sync/critical-section-objects + CRITICAL_SECTION critical_section_; + + BluetoothAdapter& bluetooth_adapter_; + + BluetoothAdapter::ScanMode scan_mode_; +}; + +} // namespace windows +} // namespace nearby +} // namespace location + +#endif // PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_MEDIUM_H_ diff --git a/cpp/platform/impl/windows/bluetooth_classic_server_socket.cc b/cpp/platform/impl/windows/bluetooth_classic_server_socket.cc index daff43e5..958c453e 100644 --- a/cpp/platform/impl/windows/bluetooth_classic_server_socket.cc +++ b/cpp/platform/impl/windows/bluetooth_classic_server_socket.cc @@ -1,196 +1,196 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "platform/impl/windows/bluetooth_classic_server_socket.h" - -#include -#include -#include - -#include "platform/impl/windows/bluetooth_classic_socket.h" -#include "platform/impl/windows/generated/winrt/Windows.Foundation.Collections.h" -#include "platform/impl/windows/utils.h" -#include "platform/public/logging.h" - -namespace location { -namespace nearby { -namespace windows { - -BluetoothServerSocket::BluetoothServerSocket(const std::string service_name, - const std::string service_uuid) - : radio_discoverable_(false), - service_name_(service_name), - service_uuid_(service_uuid), - rfcomm_provider_(nullptr) { - InitializeCriticalSection(&critical_section_); -} - -BluetoothServerSocket::~BluetoothServerSocket() {} - -// https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html#accept() -// -// Blocks until either: -// - at least one incoming connection request is available, or -// - ServerSocket is closed. -// On success, returns connected socket, ready to exchange data. -// Returns nullptr on error. -// Once error is reported, it is permanent, and ServerSocket has to be closed. -std::unique_ptr BluetoothServerSocket::Accept() { - while (bluetooth_sockets_.empty() && !closed_) { - Sleep(1000); - } - - EnterCriticalSection(&critical_section_); - if (!closed_) { - std::unique_ptr bluetoothSocket = - std::move(bluetooth_sockets_.front()); - bluetooth_sockets_.pop(); - LeaveCriticalSection(&critical_section_); - - return std::move(bluetoothSocket); - } else { - bluetooth_sockets_ = {}; - LeaveCriticalSection(&critical_section_); - } - - return nullptr; -} - -Exception BluetoothServerSocket::StartListening(bool radioDiscoverable) { - EnterCriticalSection(&critical_section_); - - radio_discoverable_ = radioDiscoverable; - - // Create the StreamSocketListener - stream_socket_listener_ = StreamSocketListener(); - - // Configure control property - stream_socket_listener_.Control().QualityOfService( - SocketQualityOfService::LowLatency); - - stream_socket_listener_.Control().KeepAlive(true); - - // Note From the perspective of a StreamSocket, a Parallel Patterns Library - // (PPL) completion handler is done executing (and the socket is eligible for - // disposal) before the continuation body runs. So, to keep your socket from - // being disposed if you want to use it inside a continuation, you'll need to - // use one of the techniques described in References to StreamSockets in C++ - // PPL continuations. - // Assign ConnectionReceived event to event handler on the server socket - stream_socket_listener_.ConnectionReceived( - [this](StreamSocketListener streamSocketListener, - StreamSocketListenerConnectionReceivedEventArgs args) { - EnterCriticalSection(&critical_section_); - if (!closed_) { - this->bluetooth_sockets_.push( - std::make_unique(args.Socket())); - } - LeaveCriticalSection(&critical_section_); - }); - - try { - auto rfcommProviderRef = - RfcommServiceProvider::CreateAsync( - RfcommServiceId::FromUuid(winrt::guid(service_uuid_))) - .get(); - - rfcomm_provider_ = rfcommProviderRef; - - stream_socket_listener_ - .BindServiceNameAsync( - winrt::to_hstring(rfcomm_provider_.ServiceId().AsString()), - SocketProtectionLevel::PlainSocket) - .get(); - - // Set the SDP attributes and start Bluetooth advertising - InitializeServiceSdpAttributes(rfcomm_provider_, service_name_); - } catch (std::exception exception) { - // We will log and eat the exception since the caller - // expects nullptr if it fails - NEARBY_LOGS(ERROR) << __func__ << ": Exception setting up for listen: " - << exception.what(); - - LeaveCriticalSection(&critical_section_); - - return {Exception::kFailed}; - } - - StartAdvertising(); - - LeaveCriticalSection(&critical_section_); - - return {Exception::kSuccess}; -} - -Exception BluetoothServerSocket::StartAdvertising() { - try { - rfcomm_provider_.StartAdvertising(stream_socket_listener_, - radio_discoverable_); - } catch (std::exception exception) { - // We will log and eat the exception since the caller - // expects nullptr if it fails - NEARBY_LOGS(ERROR) << __func__ << ": Exception calling StartAdvertising: " - << exception.what(); - - LeaveCriticalSection(&critical_section_); - - return {Exception::kFailed}; - } - - return {Exception::kSuccess}; -} - -void BluetoothServerSocket::StopAdvertising() { - rfcomm_provider_.StopAdvertising(); -} - -void BluetoothServerSocket::InitializeServiceSdpAttributes( - RfcommServiceProvider rfcommProvider, std::string service_name) { - auto sdpWriter = DataWriter(); - - // Write the Service Name Attribute. - sdpWriter.WriteByte(Constants::SdpServiceNameAttributeType); - - // The length of the UTF-8 encoded Service Name SDP Attribute. - sdpWriter.WriteByte(service_name.size()); - - // The UTF-8 encoded Service Name value. - sdpWriter.UnicodeEncoding(UnicodeEncoding::Utf8); - sdpWriter.WriteString(winrt::to_hstring(service_name)); - - // Set the SDP Attribute on the RFCOMM Service Provider. - rfcommProvider.SdpRawAttributes().Insert(Constants::SdpServiceNameAttributeId, - sdpWriter.DetachBuffer()); -} - -// https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html#close() -// -// Returns Exception::kIo on error, Exception::kSuccess otherwise. -Exception BluetoothServerSocket::Close() { - EnterCriticalSection(&critical_section_); - if (closed_) { - LeaveCriticalSection(&critical_section_); - return {Exception::kSuccess}; - } - - rfcomm_provider_.StopAdvertising(); - closed_ = true; - bluetooth_sockets_ = {}; - LeaveCriticalSection(&critical_section_); - - return {Exception::kSuccess}; -} -} // namespace windows -} // namespace nearby -} // namespace location +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "platform/impl/windows/bluetooth_classic_server_socket.h" + +#include +#include +#include + +#include "platform/impl/windows/bluetooth_classic_socket.h" +#include "platform/impl/windows/generated/winrt/Windows.Foundation.Collections.h" +#include "platform/impl/windows/utils.h" +#include "platform/public/logging.h" + +namespace location { +namespace nearby { +namespace windows { + +BluetoothServerSocket::BluetoothServerSocket(const std::string service_name, + const std::string service_uuid) + : radio_discoverable_(false), + service_name_(service_name), + service_uuid_(service_uuid), + rfcomm_provider_(nullptr) { + InitializeCriticalSection(&critical_section_); +} + +BluetoothServerSocket::~BluetoothServerSocket() {} + +// https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html#accept() +// +// Blocks until either: +// - at least one incoming connection request is available, or +// - ServerSocket is closed. +// On success, returns connected socket, ready to exchange data. +// Returns nullptr on error. +// Once error is reported, it is permanent, and ServerSocket has to be closed. +std::unique_ptr BluetoothServerSocket::Accept() { + while (bluetooth_sockets_.empty() && !closed_) { + Sleep(1000); + } + + EnterCriticalSection(&critical_section_); + if (!closed_) { + std::unique_ptr bluetoothSocket = + std::move(bluetooth_sockets_.front()); + bluetooth_sockets_.pop(); + LeaveCriticalSection(&critical_section_); + + return std::move(bluetoothSocket); + } else { + bluetooth_sockets_ = {}; + LeaveCriticalSection(&critical_section_); + } + + return nullptr; +} + +Exception BluetoothServerSocket::StartListening(bool radioDiscoverable) { + EnterCriticalSection(&critical_section_); + + radio_discoverable_ = radioDiscoverable; + + // Create the StreamSocketListener + stream_socket_listener_ = StreamSocketListener(); + + // Configure control property + stream_socket_listener_.Control().QualityOfService( + SocketQualityOfService::LowLatency); + + stream_socket_listener_.Control().KeepAlive(true); + + // Note From the perspective of a StreamSocket, a Parallel Patterns Library + // (PPL) completion handler is done executing (and the socket is eligible for + // disposal) before the continuation body runs. So, to keep your socket from + // being disposed if you want to use it inside a continuation, you'll need to + // use one of the techniques described in References to StreamSockets in C++ + // PPL continuations. + // Assign ConnectionReceived event to event handler on the server socket + stream_socket_listener_.ConnectionReceived( + [this](StreamSocketListener streamSocketListener, + StreamSocketListenerConnectionReceivedEventArgs args) { + EnterCriticalSection(&critical_section_); + if (!closed_) { + this->bluetooth_sockets_.push( + std::make_unique(args.Socket())); + } + LeaveCriticalSection(&critical_section_); + }); + + try { + auto rfcommProviderRef = + RfcommServiceProvider::CreateAsync( + RfcommServiceId::FromUuid(winrt::guid(service_uuid_))) + .get(); + + rfcomm_provider_ = rfcommProviderRef; + + stream_socket_listener_ + .BindServiceNameAsync( + winrt::to_hstring(rfcomm_provider_.ServiceId().AsString()), + SocketProtectionLevel::PlainSocket) + .get(); + + // Set the SDP attributes and start Bluetooth advertising + InitializeServiceSdpAttributes(rfcomm_provider_, service_name_); + } catch (std::exception exception) { + // We will log and eat the exception since the caller + // expects nullptr if it fails + NEARBY_LOGS(ERROR) << __func__ << ": Exception setting up for listen: " + << exception.what(); + + LeaveCriticalSection(&critical_section_); + + return {Exception::kFailed}; + } + + StartAdvertising(); + + LeaveCriticalSection(&critical_section_); + + return {Exception::kSuccess}; +} + +Exception BluetoothServerSocket::StartAdvertising() { + try { + rfcomm_provider_.StartAdvertising(stream_socket_listener_, + radio_discoverable_); + } catch (std::exception exception) { + // We will log and eat the exception since the caller + // expects nullptr if it fails + NEARBY_LOGS(ERROR) << __func__ << ": Exception calling StartAdvertising: " + << exception.what(); + + LeaveCriticalSection(&critical_section_); + + return {Exception::kFailed}; + } + + return {Exception::kSuccess}; +} + +void BluetoothServerSocket::StopAdvertising() { + rfcomm_provider_.StopAdvertising(); +} + +void BluetoothServerSocket::InitializeServiceSdpAttributes( + RfcommServiceProvider rfcommProvider, std::string service_name) { + auto sdpWriter = DataWriter(); + + // Write the Service Name Attribute. + sdpWriter.WriteByte(Constants::SdpServiceNameAttributeType); + + // The length of the UTF-8 encoded Service Name SDP Attribute. + sdpWriter.WriteByte(service_name.size()); + + // The UTF-8 encoded Service Name value. + sdpWriter.UnicodeEncoding(UnicodeEncoding::Utf8); + sdpWriter.WriteString(winrt::to_hstring(service_name)); + + // Set the SDP Attribute on the RFCOMM Service Provider. + rfcommProvider.SdpRawAttributes().Insert(Constants::SdpServiceNameAttributeId, + sdpWriter.DetachBuffer()); +} + +// https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html#close() +// +// Returns Exception::kIo on error, Exception::kSuccess otherwise. +Exception BluetoothServerSocket::Close() { + EnterCriticalSection(&critical_section_); + if (closed_) { + LeaveCriticalSection(&critical_section_); + return {Exception::kSuccess}; + } + + rfcomm_provider_.StopAdvertising(); + closed_ = true; + bluetooth_sockets_ = {}; + LeaveCriticalSection(&critical_section_); + + return {Exception::kSuccess}; +} +} // namespace windows +} // namespace nearby +} // namespace location diff --git a/cpp/platform/impl/windows/bluetooth_classic_server_socket.h b/cpp/platform/impl/windows/bluetooth_classic_server_socket.h index 1bfb47be..b8712b50 100644 --- a/cpp/platform/impl/windows/bluetooth_classic_server_socket.h +++ b/cpp/platform/impl/windows/bluetooth_classic_server_socket.h @@ -1,129 +1,129 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_SERVER_SOCKET_H_ -#define PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_SERVER_SOCKET_H_ - -#include - -#include - -#include "platform/api/bluetooth_classic.h" -#include "platform/impl/windows/bluetooth_classic_socket.h" -#include "platform/impl/windows/generated/winrt/Windows.Devices.Bluetooth.Rfcomm.h" -#include "platform/impl/windows/generated/winrt/Windows.Foundation.h" -#include "platform/impl/windows/generated/winrt/Windows.Networking.Sockets.h" -#include "platform/impl/windows/generated/winrt/base.h" - -namespace location { -namespace nearby { -namespace windows { - -// Supports listening for an incoming network connection using Bluetooth RFCOMM. -// https://docs.microsoft.com/en-us/uwp/api/windows.networking.sockets.streamsocketlistener?view=winrt-20348 -using winrt::Windows::Networking::Sockets::StreamSocketListener; - -// Provides data for a ConnectionReceived event on a StreamSocketListener -// object. -// https://docs.microsoft.com/en-us/uwp/api/windows.networking.sockets.streamsocketlistenerconnectionreceivedeventargs?view=winrt-20348 -using winrt::Windows::Networking::Sockets:: - StreamSocketListenerConnectionReceivedEventArgs; - -// Represents an asynchronous action. -// https://docs.microsoft.com/en-us/uwp/api/windows.foundation.iasyncaction?view=winrt-20348 -using winrt::Windows::Foundation::IAsyncAction; - -// Specifies the quality of service for a StreamSocket object. -// https://docs.microsoft.com/en-us/uwp/api/windows.networking.sockets.socketqualityofservice?view=winrt-20348 -using winrt::Windows::Networking::Sockets::SocketQualityOfService; - -// Represents an instance of a local RFCOMM service. -// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.rfcomm.rfcommserviceprovider?view=winrt-20348 -using winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommServiceProvider; - -// Represents an RFCOMM service ID. -// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.rfcomm.rfcommserviceid?view=winrt-20348 -using winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommServiceId; - -// Writes data to an output stream. -// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.datawriter?view=winrt-20348 -using winrt::Windows::Storage::Streams::DataWriter; - -// Specifies the type of character encoding for a stream. -// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.unicodeencoding?view=winrt-20348 -using winrt::Windows::Storage::Streams::UnicodeEncoding; - -// Specifies the level of encryption to use on a StreamSocket object. -// https://docs.microsoft.com/en-us/uwp/api/windows.networking.sockets.socketprotectionlevel?view=winrt-22000 -using winrt::Windows::Networking::Sockets::SocketProtectionLevel; - -// https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html. -class BluetoothServerSocket : public api::BluetoothServerSocket { - public: - BluetoothServerSocket(const std::string service_name, - const std::string service_uuid); - - ~BluetoothServerSocket() override; - - // https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html#accept() - // - // Blocks until either: - // - at least one incoming connection request is available, or - // - ServerSocket is closed. - // On success, returns connected socket, ready to exchange data. - // Returns nullptr on error. - // Once error is reported, it is permanent, and ServerSocket has to be closed. - std::unique_ptr Accept() override; - - // https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html#close() - // - // Returns Exception::kIo on error, Exception::kSuccess otherwise. - Exception Close() override; - - Exception StartListening(bool radioDiscoverable); - - void SetScanMode(bool radioDiscoverable) { - StopAdvertising(); - radio_discoverable_ = radioDiscoverable; - StartAdvertising(); - } - - private: - void InitializeServiceSdpAttributes(RfcommServiceProvider rfcommProvider, - std::string service_name); - - Exception StartAdvertising(); - void StopAdvertising(); - - // This is used to store sockets in case Accept hasn't been called. Once - // Accept has been called the socket is popped from the queue and returned to - // the caller - std::queue> bluetooth_sockets_; - - StreamSocketListener stream_socket_listener_; - winrt::event_token listener_token_; - CRITICAL_SECTION critical_section_; - bool closed_ = false; - bool radio_discoverable_; - - const std::string service_name_; - const std::string service_uuid_; - - RfcommServiceProvider rfcomm_provider_; -}; - -} // namespace windows -} // namespace nearby -} // namespace location -#endif // PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_SERVER_SOCKET_H_ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_SERVER_SOCKET_H_ +#define PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_SERVER_SOCKET_H_ + +#include + +#include + +#include "platform/api/bluetooth_classic.h" +#include "platform/impl/windows/bluetooth_classic_socket.h" +#include "platform/impl/windows/generated/winrt/Windows.Devices.Bluetooth.Rfcomm.h" +#include "platform/impl/windows/generated/winrt/Windows.Foundation.h" +#include "platform/impl/windows/generated/winrt/Windows.Networking.Sockets.h" +#include "platform/impl/windows/generated/winrt/base.h" + +namespace location { +namespace nearby { +namespace windows { + +// Supports listening for an incoming network connection using Bluetooth RFCOMM. +// https://docs.microsoft.com/en-us/uwp/api/windows.networking.sockets.streamsocketlistener?view=winrt-20348 +using winrt::Windows::Networking::Sockets::StreamSocketListener; + +// Provides data for a ConnectionReceived event on a StreamSocketListener +// object. +// https://docs.microsoft.com/en-us/uwp/api/windows.networking.sockets.streamsocketlistenerconnectionreceivedeventargs?view=winrt-20348 +using winrt::Windows::Networking::Sockets:: + StreamSocketListenerConnectionReceivedEventArgs; + +// Represents an asynchronous action. +// https://docs.microsoft.com/en-us/uwp/api/windows.foundation.iasyncaction?view=winrt-20348 +using winrt::Windows::Foundation::IAsyncAction; + +// Specifies the quality of service for a StreamSocket object. +// https://docs.microsoft.com/en-us/uwp/api/windows.networking.sockets.socketqualityofservice?view=winrt-20348 +using winrt::Windows::Networking::Sockets::SocketQualityOfService; + +// Represents an instance of a local RFCOMM service. +// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.rfcomm.rfcommserviceprovider?view=winrt-20348 +using winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommServiceProvider; + +// Represents an RFCOMM service ID. +// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.rfcomm.rfcommserviceid?view=winrt-20348 +using winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommServiceId; + +// Writes data to an output stream. +// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.datawriter?view=winrt-20348 +using winrt::Windows::Storage::Streams::DataWriter; + +// Specifies the type of character encoding for a stream. +// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.unicodeencoding?view=winrt-20348 +using winrt::Windows::Storage::Streams::UnicodeEncoding; + +// Specifies the level of encryption to use on a StreamSocket object. +// https://docs.microsoft.com/en-us/uwp/api/windows.networking.sockets.socketprotectionlevel?view=winrt-22000 +using winrt::Windows::Networking::Sockets::SocketProtectionLevel; + +// https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html. +class BluetoothServerSocket : public api::BluetoothServerSocket { + public: + BluetoothServerSocket(const std::string service_name, + const std::string service_uuid); + + ~BluetoothServerSocket() override; + + // https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html#accept() + // + // Blocks until either: + // - at least one incoming connection request is available, or + // - ServerSocket is closed. + // On success, returns connected socket, ready to exchange data. + // Returns nullptr on error. + // Once error is reported, it is permanent, and ServerSocket has to be closed. + std::unique_ptr Accept() override; + + // https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html#close() + // + // Returns Exception::kIo on error, Exception::kSuccess otherwise. + Exception Close() override; + + Exception StartListening(bool radioDiscoverable); + + void SetScanMode(bool radioDiscoverable) { + StopAdvertising(); + radio_discoverable_ = radioDiscoverable; + StartAdvertising(); + } + + private: + void InitializeServiceSdpAttributes(RfcommServiceProvider rfcommProvider, + std::string service_name); + + Exception StartAdvertising(); + void StopAdvertising(); + + // This is used to store sockets in case Accept hasn't been called. Once + // Accept has been called the socket is popped from the queue and returned to + // the caller + std::queue> bluetooth_sockets_; + + StreamSocketListener stream_socket_listener_; + winrt::event_token listener_token_; + CRITICAL_SECTION critical_section_; + bool closed_ = false; + bool radio_discoverable_; + + const std::string service_name_; + const std::string service_uuid_; + + RfcommServiceProvider rfcomm_provider_; +}; + +} // namespace windows +} // namespace nearby +} // namespace location +#endif // PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_SERVER_SOCKET_H_ diff --git a/cpp/platform/impl/windows/bluetooth_classic_socket.cc b/cpp/platform/impl/windows/bluetooth_classic_socket.cc index 89694b52..3ce04b30 100644 --- a/cpp/platform/impl/windows/bluetooth_classic_socket.cc +++ b/cpp/platform/impl/windows/bluetooth_classic_socket.cc @@ -1,194 +1,194 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "platform/impl/windows/bluetooth_classic_socket.h" - -#include "platform/base/logging.h" -#include "platform/impl/windows/generated/winrt/Windows.Networking.Sockets.h" - -namespace location { -namespace nearby { -namespace windows { - -BluetoothSocket::BluetoothSocket(StreamSocket streamSocket) - : windows_socket_(streamSocket) { - bluetooth_device_ = std::make_unique( - winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromHostNameAsync( - windows_socket_.Information().RemoteHostName()) - .get()); - input_stream_ = - std::make_unique(windows_socket_.InputStream()); - output_stream_ = - std::make_unique(windows_socket_.OutputStream()); -} - -BluetoothSocket::BluetoothSocket() {} - -BluetoothSocket::~BluetoothSocket() {} - -// NOTE: -// It is an undefined behavior if GetInputStream() or GetOutputStream() is -// called for a not-connected BluetoothSocket, i.e. any object that is not -// returned by BluetoothClassicMedium::ConnectToService() for client side or -// BluetoothServerSocket::Accept() for server side of connection. -// Returns the InputStream of this connected BluetoothSocket. -InputStream& BluetoothSocket::GetInputStream() { return *input_stream_.get(); } - -// Returns the OutputStream of this connected BluetoothSocket. -OutputStream& BluetoothSocket::GetOutputStream() { - return *output_stream_.get(); -} - -// Closes both input and output streams, marks Socket as closed. -// After this call object should be treated as not connected. -// Returns Exception::kIo on error, Exception::kSuccess otherwise. -Exception BluetoothSocket::Close() { - // The Close method aborts any pending operations and releases all unmanaged - // resources associated with the StreamSocket object, including the Input and - // Output streams - windows_socket_.Close(); - return {Exception::kSuccess}; -} - -// https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html#getRemoteDevice() -// Returns valid BluetoothDevice pointer if there is a connection, and -// nullptr otherwise. -api::BluetoothDevice* BluetoothSocket::GetRemoteDevice() { - return bluetooth_device_.get(); -} - -// Starts an asynchronous operation on a StreamSocket object to connect to a -// remote network destination specified by a remote hostname and a remote -// service name. -void BluetoothSocket::Connect(HostName connectionHostName, - winrt::hstring connectionServiceName) { - windows_socket_ = winrt::Windows::Networking::Sockets::StreamSocket(); - - // https://docs.microsoft.com/en-us/uwp/api/windows.networking.sockets.streamsocket.connectasync?view=winrt-20348 - windows_socket_.ConnectAsync(connectionHostName, connectionServiceName).get(); - - auto info = windows_socket_.Information(); - auto hostName = info.RemoteHostName(); - - bluetooth_device_ = std::make_unique( - winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromHostNameAsync( - windows_socket_.Information().RemoteHostName()) - .get()); - - input_stream_ = - std::make_unique(windows_socket_.InputStream()); - output_stream_ = - std::make_unique(windows_socket_.OutputStream()); -} - -BluetoothSocket::BluetoothInputStream::BluetoothInputStream( - IInputStream stream) { - winrt_stream_ = stream; -} - -ExceptionOr BluetoothSocket::BluetoothInputStream::Read( - std::int64_t size) { - if (winrt_stream_ == nullptr) { - return {Exception::kFailed}; - } - - Buffer buffer = Buffer(size); - - winrt_stream_.ReadAsync(buffer, size, InputStreamOptions::Partial).get(); - - DataReader dataReader = DataReader::FromBuffer(buffer); - - ByteArray data((char*)buffer.data(), buffer.Length()); - - return ExceptionOr(data); -} - -IAsyncAction BluetoothSocket::CancelIOAsync() { - // Cancels pending reads and writes over a StreamSocket object. - // https://docs.microsoft.com/en-us/uwp/api/windows.networking.sockets.streamsocket.cancelioasync?view=winrt-20348 - return windows_socket_.CancelIOAsync(); -} - -Exception BluetoothSocket::BluetoothInputStream::Close() { - if (winrt_stream_ == nullptr) { - return {Exception::kSuccess}; // Already closed, don't error out - } - - try { - winrt_stream_.Close(); - winrt_stream_ = nullptr; - } catch (std::exception exception) { - return {Exception::kFailed}; - } - - return {Exception::kSuccess}; -} - -BluetoothSocket::BluetoothOutputStream::BluetoothOutputStream( - IOutputStream stream) { - winrt_stream_ = stream; -} - -Exception BluetoothSocket::BluetoothOutputStream::Write(const ByteArray& data) { - Buffer buffer = Buffer(data.size()); - std::memcpy(buffer.data(), data.data(), data.size()); - buffer.Length(data.size()); - if (winrt_stream_ == nullptr) { - return {Exception::kFailed}; - } - - try { - auto hresult = winrt_stream_.WriteAsync(buffer).get(); - } catch (winrt::hresult_error const& ex) { - NEARBY_LOGS(ERROR) << __func__ << ": winrt exception: " << ex.code() << ": " - << winrt::to_string(ex.message()); - - return {Exception::kFailed}; - } - - return {Exception::kSuccess}; -} - -Exception BluetoothSocket::BluetoothOutputStream::Flush() { - if (winrt_stream_ == nullptr) { - return {Exception::kFailed}; - } - - try { - winrt_stream_.FlushAsync().get(); - } catch (std::exception exception) { - return {Exception::kFailed}; - } - - return {Exception::kSuccess}; -} - -Exception BluetoothSocket::BluetoothOutputStream::Close() { - if (winrt_stream_ == nullptr) { - return {Exception::kSuccess}; // Already closed, don't error out - } - - try { - winrt_stream_.Close(); - winrt_stream_ = nullptr; - } catch (std::exception exception) { - return {Exception::kFailed}; - } - - return {Exception::kSuccess}; -} - -} // namespace windows -} // namespace nearby -} // namespace location +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "platform/impl/windows/bluetooth_classic_socket.h" + +#include "platform/base/logging.h" +#include "platform/impl/windows/generated/winrt/Windows.Networking.Sockets.h" + +namespace location { +namespace nearby { +namespace windows { + +BluetoothSocket::BluetoothSocket(StreamSocket streamSocket) + : windows_socket_(streamSocket) { + bluetooth_device_ = std::make_unique( + winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromHostNameAsync( + windows_socket_.Information().RemoteHostName()) + .get()); + input_stream_ = + std::make_unique(windows_socket_.InputStream()); + output_stream_ = + std::make_unique(windows_socket_.OutputStream()); +} + +BluetoothSocket::BluetoothSocket() {} + +BluetoothSocket::~BluetoothSocket() {} + +// NOTE: +// It is an undefined behavior if GetInputStream() or GetOutputStream() is +// called for a not-connected BluetoothSocket, i.e. any object that is not +// returned by BluetoothClassicMedium::ConnectToService() for client side or +// BluetoothServerSocket::Accept() for server side of connection. +// Returns the InputStream of this connected BluetoothSocket. +InputStream& BluetoothSocket::GetInputStream() { return *input_stream_.get(); } + +// Returns the OutputStream of this connected BluetoothSocket. +OutputStream& BluetoothSocket::GetOutputStream() { + return *output_stream_.get(); +} + +// Closes both input and output streams, marks Socket as closed. +// After this call object should be treated as not connected. +// Returns Exception::kIo on error, Exception::kSuccess otherwise. +Exception BluetoothSocket::Close() { + // The Close method aborts any pending operations and releases all unmanaged + // resources associated with the StreamSocket object, including the Input and + // Output streams + windows_socket_.Close(); + return {Exception::kSuccess}; +} + +// https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html#getRemoteDevice() +// Returns valid BluetoothDevice pointer if there is a connection, and +// nullptr otherwise. +api::BluetoothDevice* BluetoothSocket::GetRemoteDevice() { + return bluetooth_device_.get(); +} + +// Starts an asynchronous operation on a StreamSocket object to connect to a +// remote network destination specified by a remote hostname and a remote +// service name. +void BluetoothSocket::Connect(HostName connectionHostName, + winrt::hstring connectionServiceName) { + windows_socket_ = winrt::Windows::Networking::Sockets::StreamSocket(); + + // https://docs.microsoft.com/en-us/uwp/api/windows.networking.sockets.streamsocket.connectasync?view=winrt-20348 + windows_socket_.ConnectAsync(connectionHostName, connectionServiceName).get(); + + auto info = windows_socket_.Information(); + auto hostName = info.RemoteHostName(); + + bluetooth_device_ = std::make_unique( + winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromHostNameAsync( + windows_socket_.Information().RemoteHostName()) + .get()); + + input_stream_ = + std::make_unique(windows_socket_.InputStream()); + output_stream_ = + std::make_unique(windows_socket_.OutputStream()); +} + +BluetoothSocket::BluetoothInputStream::BluetoothInputStream( + IInputStream stream) { + winrt_stream_ = stream; +} + +ExceptionOr BluetoothSocket::BluetoothInputStream::Read( + std::int64_t size) { + if (winrt_stream_ == nullptr) { + return {Exception::kFailed}; + } + + Buffer buffer = Buffer(size); + + winrt_stream_.ReadAsync(buffer, size, InputStreamOptions::Partial).get(); + + DataReader dataReader = DataReader::FromBuffer(buffer); + + ByteArray data((char*)buffer.data(), buffer.Length()); + + return ExceptionOr(data); +} + +IAsyncAction BluetoothSocket::CancelIOAsync() { + // Cancels pending reads and writes over a StreamSocket object. + // https://docs.microsoft.com/en-us/uwp/api/windows.networking.sockets.streamsocket.cancelioasync?view=winrt-20348 + return windows_socket_.CancelIOAsync(); +} + +Exception BluetoothSocket::BluetoothInputStream::Close() { + if (winrt_stream_ == nullptr) { + return {Exception::kSuccess}; // Already closed, don't error out + } + + try { + winrt_stream_.Close(); + winrt_stream_ = nullptr; + } catch (std::exception exception) { + return {Exception::kFailed}; + } + + return {Exception::kSuccess}; +} + +BluetoothSocket::BluetoothOutputStream::BluetoothOutputStream( + IOutputStream stream) { + winrt_stream_ = stream; +} + +Exception BluetoothSocket::BluetoothOutputStream::Write(const ByteArray& data) { + Buffer buffer = Buffer(data.size()); + std::memcpy(buffer.data(), data.data(), data.size()); + buffer.Length(data.size()); + if (winrt_stream_ == nullptr) { + return {Exception::kFailed}; + } + + try { + auto hresult = winrt_stream_.WriteAsync(buffer).get(); + } catch (winrt::hresult_error const& ex) { + NEARBY_LOGS(ERROR) << __func__ << ": winrt exception: " << ex.code() << ": " + << winrt::to_string(ex.message()); + + return {Exception::kFailed}; + } + + return {Exception::kSuccess}; +} + +Exception BluetoothSocket::BluetoothOutputStream::Flush() { + if (winrt_stream_ == nullptr) { + return {Exception::kFailed}; + } + + try { + winrt_stream_.FlushAsync().get(); + } catch (std::exception exception) { + return {Exception::kFailed}; + } + + return {Exception::kSuccess}; +} + +Exception BluetoothSocket::BluetoothOutputStream::Close() { + if (winrt_stream_ == nullptr) { + return {Exception::kSuccess}; // Already closed, don't error out + } + + try { + winrt_stream_.Close(); + winrt_stream_ = nullptr; + } catch (std::exception exception) { + return {Exception::kFailed}; + } + + return {Exception::kSuccess}; +} + +} // namespace windows +} // namespace nearby +} // namespace location diff --git a/cpp/platform/impl/windows/bluetooth_classic_socket.h b/cpp/platform/impl/windows/bluetooth_classic_socket.h index 7c174b6e..57dbf570 100644 --- a/cpp/platform/impl/windows/bluetooth_classic_socket.h +++ b/cpp/platform/impl/windows/bluetooth_classic_socket.h @@ -1,139 +1,139 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_SOCKET_H_ -#define PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_SOCKET_H_ - -#include "platform/api/bluetooth_classic.h" -#include "platform/impl/windows/bluetooth_classic_device.h" -#include "platform/impl/windows/generated/winrt/Windows.Foundation.h" -#include "platform/impl/windows/generated/winrt/Windows.Networking.Sockets.h" -#include "platform/impl/windows/generated/winrt/Windows.Storage.Streams.h" - -namespace location { -namespace nearby { -namespace windows { - -// Provides data for a hostname or an IP address. -// https://docs.microsoft.com/en-us/uwp/api/windows.networking.hostname?view=winrt-20348 -using winrt::Windows::Networking::HostName; - -// Supports network communication using a stream socket over Bluetooth RFCOMM. -// https://docs.microsoft.com/en-us/uwp/api/windows.networking.sockets.streamsocket?view=winrt-20348 -using winrt::Windows::Networking::Sockets::IStreamSocket; -using winrt::Windows::Networking::Sockets::StreamSocket; - -// Provides a default implementation of the IBuffer interface and its related -// interfaces. -// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.buffer?view=winrt-20348 -using winrt::Windows::Storage::Streams::Buffer; - -// Represents a sequential stream of bytes to be read. -// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.iinputstream?view=winrt-20348 -using winrt::Windows::Storage::Streams::IInputStream; - -// Represents a sequential stream of bytes to be written. -// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.ioutputstream?view=winrt-20348 -using winrt::Windows::Storage::Streams::IOutputStream; - -// Specifies the read options for an input stream. -// This enumeration has a FlagsAttribute attribute that allows a bitwise -// combination of its member values. -// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.inputstreamoptions?view=winrt-20348 -using winrt::Windows::Storage::Streams::InputStreamOptions; - -// Reads data from an input stream. -// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.datareader?view=winrt-20348 -using winrt::Windows::Storage::Streams::DataReader; - -// Represents an asynchronous action. -// https://docs.microsoft.com/en-us/uwp/api/windows.foundation.iasyncaction?view=winrt-20348 -using winrt::Windows::Foundation::IAsyncAction; - -// https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html. -class BluetoothSocket : public api::BluetoothSocket { - public: - BluetoothSocket(); - - BluetoothSocket(StreamSocket streamSocket); - - ~BluetoothSocket() override; - - // NOTE: - // It is an undefined behavior if GetInputStream() or GetOutputStream() is - // called for a not-connected BluetoothSocket, i.e. any object that is not - // returned by BluetoothClassicMedium::ConnectToService() for client side or - // BluetoothServerSocket::Accept() for server side of connection. - - // Returns the InputStream of this connected BluetoothSocket. - InputStream& GetInputStream() override; - - // Returns the OutputStream of this connected BluetoothSocket. - OutputStream& GetOutputStream() override; - - // Closes both input and output streams, marks Socket as closed. - // After this call object should be treated as not connected. - // Returns Exception::kIo on error, Exception::kSuccess otherwise. - Exception Close() override; - - // https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html#getRemoteDevice() - // Returns valid BluetoothDevice pointer if there is a connection, and - // nullptr otherwise. - api::BluetoothDevice* GetRemoteDevice() override; - - // Connect asynchronously to the target remote device - void Connect(HostName connectionHostName, - winrt::hstring connectionServiceName); - - IAsyncAction CancelIOAsync(); - - private: - class BluetoothInputStream : public InputStream { - public: - BluetoothInputStream(IInputStream stream); - ~BluetoothInputStream() override = default; - - ExceptionOr Read(std::int64_t size) override; - Exception Close() override; - - private: - IInputStream winrt_stream_; - }; - - class BluetoothOutputStream : public OutputStream { - public: - BluetoothOutputStream(IOutputStream stream); - ~BluetoothOutputStream() override = default; - - Exception Write(const ByteArray& data) override; - Exception Flush() override; - - Exception Close() override; - - private: - IOutputStream winrt_stream_; - }; - - std::unique_ptr input_stream_; - std::unique_ptr output_stream_; - - StreamSocket windows_socket_; - std::unique_ptr bluetooth_device_; -}; - -} // namespace windows -} // namespace nearby -} // namespace location - -#endif // PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_SOCKET_H_ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_SOCKET_H_ +#define PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_SOCKET_H_ + +#include "platform/api/bluetooth_classic.h" +#include "platform/impl/windows/bluetooth_classic_device.h" +#include "platform/impl/windows/generated/winrt/Windows.Foundation.h" +#include "platform/impl/windows/generated/winrt/Windows.Networking.Sockets.h" +#include "platform/impl/windows/generated/winrt/Windows.Storage.Streams.h" + +namespace location { +namespace nearby { +namespace windows { + +// Provides data for a hostname or an IP address. +// https://docs.microsoft.com/en-us/uwp/api/windows.networking.hostname?view=winrt-20348 +using winrt::Windows::Networking::HostName; + +// Supports network communication using a stream socket over Bluetooth RFCOMM. +// https://docs.microsoft.com/en-us/uwp/api/windows.networking.sockets.streamsocket?view=winrt-20348 +using winrt::Windows::Networking::Sockets::IStreamSocket; +using winrt::Windows::Networking::Sockets::StreamSocket; + +// Provides a default implementation of the IBuffer interface and its related +// interfaces. +// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.buffer?view=winrt-20348 +using winrt::Windows::Storage::Streams::Buffer; + +// Represents a sequential stream of bytes to be read. +// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.iinputstream?view=winrt-20348 +using winrt::Windows::Storage::Streams::IInputStream; + +// Represents a sequential stream of bytes to be written. +// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.ioutputstream?view=winrt-20348 +using winrt::Windows::Storage::Streams::IOutputStream; + +// Specifies the read options for an input stream. +// This enumeration has a FlagsAttribute attribute that allows a bitwise +// combination of its member values. +// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.inputstreamoptions?view=winrt-20348 +using winrt::Windows::Storage::Streams::InputStreamOptions; + +// Reads data from an input stream. +// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.datareader?view=winrt-20348 +using winrt::Windows::Storage::Streams::DataReader; + +// Represents an asynchronous action. +// https://docs.microsoft.com/en-us/uwp/api/windows.foundation.iasyncaction?view=winrt-20348 +using winrt::Windows::Foundation::IAsyncAction; + +// https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html. +class BluetoothSocket : public api::BluetoothSocket { + public: + BluetoothSocket(); + + BluetoothSocket(StreamSocket streamSocket); + + ~BluetoothSocket() override; + + // NOTE: + // It is an undefined behavior if GetInputStream() or GetOutputStream() is + // called for a not-connected BluetoothSocket, i.e. any object that is not + // returned by BluetoothClassicMedium::ConnectToService() for client side or + // BluetoothServerSocket::Accept() for server side of connection. + + // Returns the InputStream of this connected BluetoothSocket. + InputStream& GetInputStream() override; + + // Returns the OutputStream of this connected BluetoothSocket. + OutputStream& GetOutputStream() override; + + // Closes both input and output streams, marks Socket as closed. + // After this call object should be treated as not connected. + // Returns Exception::kIo on error, Exception::kSuccess otherwise. + Exception Close() override; + + // https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html#getRemoteDevice() + // Returns valid BluetoothDevice pointer if there is a connection, and + // nullptr otherwise. + api::BluetoothDevice* GetRemoteDevice() override; + + // Connect asynchronously to the target remote device + void Connect(HostName connectionHostName, + winrt::hstring connectionServiceName); + + IAsyncAction CancelIOAsync(); + + private: + class BluetoothInputStream : public InputStream { + public: + BluetoothInputStream(IInputStream stream); + ~BluetoothInputStream() override = default; + + ExceptionOr Read(std::int64_t size) override; + Exception Close() override; + + private: + IInputStream winrt_stream_; + }; + + class BluetoothOutputStream : public OutputStream { + public: + BluetoothOutputStream(IOutputStream stream); + ~BluetoothOutputStream() override = default; + + Exception Write(const ByteArray& data) override; + Exception Flush() override; + + Exception Close() override; + + private: + IOutputStream winrt_stream_; + }; + + std::unique_ptr input_stream_; + std::unique_ptr output_stream_; + + StreamSocket windows_socket_; + std::unique_ptr bluetooth_device_; +}; + +} // namespace windows +} // namespace nearby +} // namespace location + +#endif // PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_SOCKET_H_ diff --git a/cpp/platform/impl/windows/condition_variable_test.cc b/cpp/platform/impl/windows/condition_variable_test.cc index 18ffff2a..ccad7ac5 100644 --- a/cpp/platform/impl/windows/condition_variable_test.cc +++ b/cpp/platform/impl/windows/condition_variable_test.cc @@ -1,104 +1,104 @@ -// Copyright 2021 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "platform/impl/windows/condition_variable.h" - -#include // NOLINT - -#include "absl/time/clock.h" -#include "platform/base/exception.h" -#include "platform/impl/windows/mutex.h" - -#include "gtest/gtest.h" - -class ConditionVariableTests : public testing::Test { - public: - class ConditionVariableTest { - public: - ConditionVariableTest() {} - - std::future WaitForEvent(bool timedWait, // NOLINT - const absl::Duration* timeout) { - return std::async( - std::launch::async, - [this, timedWait, timeout]() mutable { - std::thread::id currentThread = std::this_thread::get_id(); - - if (timedWait == true) { - auto result = this->condition_variable_actual_.Wait(*timeout); - if (result.value == location::nearby::Exception::kSuccess) { - return true; - } else { - return false; - } - } else { - this->condition_variable_actual_.Wait(); - } - return true; - }); - } - - void PostEvent() { - std::lock_guard guard(mutex_actual_.GetWindowsMutex()); - condition_variable_actual_.Notify(); - } - - private: - location::nearby::windows::Mutex mutex_actual_ = - location::nearby::windows::Mutex( - location::nearby::windows::Mutex::Mode::kRegular); - location::nearby::windows::Mutex& mutex_ = mutex_actual_; - location::nearby::windows::ConditionVariable condition_variable_actual_ = - location::nearby::windows::ConditionVariable(&mutex_); - location::nearby::windows::ConditionVariable& condition_variable_ = - condition_variable_actual_; - }; -}; - -TEST_F(ConditionVariableTests, SuccessfulCreation) { - // Arrange - ConditionVariableTest conditionVariableTest; - - auto result = conditionVariableTest.WaitForEvent(false, nullptr); - - Sleep(1); - - // Act - conditionVariableTest.PostEvent(); - - // Assert - ASSERT_TRUE(result.get()); -} - -TEST_F(ConditionVariableTests, TimedCreation) { - // Arrange - ConditionVariableTest conditionVariableTest; - const absl::Duration duration = absl::Milliseconds(100); - - // Act - auto result = conditionVariableTest.WaitForEvent(true, &duration); - - // Assert - ASSERT_FALSE(result.get()); // Timed out - - // Act - result = conditionVariableTest.WaitForEvent(true, &duration); - - Sleep(1); - - conditionVariableTest.PostEvent(); - - // Assert - ASSERT_TRUE(result.get()); // Didn't timeout -} +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "platform/impl/windows/condition_variable.h" + +#include // NOLINT + +#include "absl/time/clock.h" +#include "platform/base/exception.h" +#include "platform/impl/windows/mutex.h" + +#include "gtest/gtest.h" + +class ConditionVariableTests : public testing::Test { + public: + class ConditionVariableTest { + public: + ConditionVariableTest() {} + + std::future WaitForEvent(bool timedWait, // NOLINT + const absl::Duration* timeout) { + return std::async( + std::launch::async, + [this, timedWait, timeout]() mutable { + std::thread::id currentThread = std::this_thread::get_id(); + + if (timedWait == true) { + auto result = this->condition_variable_actual_.Wait(*timeout); + if (result.value == location::nearby::Exception::kSuccess) { + return true; + } else { + return false; + } + } else { + this->condition_variable_actual_.Wait(); + } + return true; + }); + } + + void PostEvent() { + std::lock_guard guard(mutex_actual_.GetWindowsMutex()); + condition_variable_actual_.Notify(); + } + + private: + location::nearby::windows::Mutex mutex_actual_ = + location::nearby::windows::Mutex( + location::nearby::windows::Mutex::Mode::kRegular); + location::nearby::windows::Mutex& mutex_ = mutex_actual_; + location::nearby::windows::ConditionVariable condition_variable_actual_ = + location::nearby::windows::ConditionVariable(&mutex_); + location::nearby::windows::ConditionVariable& condition_variable_ = + condition_variable_actual_; + }; +}; + +TEST_F(ConditionVariableTests, SuccessfulCreation) { + // Arrange + ConditionVariableTest conditionVariableTest; + + auto result = conditionVariableTest.WaitForEvent(false, nullptr); + + Sleep(1); + + // Act + conditionVariableTest.PostEvent(); + + // Assert + ASSERT_TRUE(result.get()); +} + +TEST_F(ConditionVariableTests, TimedCreation) { + // Arrange + ConditionVariableTest conditionVariableTest; + const absl::Duration duration = absl::Milliseconds(100); + + // Act + auto result = conditionVariableTest.WaitForEvent(true, &duration); + + // Assert + ASSERT_FALSE(result.get()); // Timed out + + // Act + result = conditionVariableTest.WaitForEvent(true, &duration); + + Sleep(1); + + conditionVariableTest.PostEvent(); + + // Assert + ASSERT_TRUE(result.get()); // Didn't timeout +} diff --git a/cpp/platform/impl/windows/count_down_latch_test.cc b/cpp/platform/impl/windows/count_down_latch_test.cc index 520c6119..ace8ee02 100644 --- a/cpp/platform/impl/windows/count_down_latch_test.cc +++ b/cpp/platform/impl/windows/count_down_latch_test.cc @@ -1,186 +1,186 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "platform/impl/shared/count_down_latch.h" - -#include - -#include "gtest/gtest.h" -#include "platform/api/platform.h" - -class CountDownLatchTests : public testing::Test { - public: - class TestData { - public: - std::unique_ptr& countDownLatch; - LONG volatile& count; - }; - - class CountDownLatchTest { - public: - static DWORD ThreadProcCountDown(LPVOID lpParam) { - TestData* testData = static_cast(lpParam); - - Sleep(1); - - InterlockedIncrement(&testData->count); - testData->countDownLatch->CountDown(); - return 0; - } - - static DWORD ThreadProcAwait(LPVOID lpParam) { - TestData* testData = static_cast(lpParam); - - Sleep(1); - - testData->countDownLatch->Await(); - InterlockedIncrement(&testData->count); - - return 0; - } - }; - - CountDownLatchTests() {} -}; - -TEST_F(CountDownLatchTests, CountDownLatchAwaitSucceeds) { - // Arrange - LONG volatile count = 0; - - std::unique_ptr countDownLatch = - location::nearby::api::ImplementationPlatform::CreateCountDownLatch(3); - - HANDLE hThreads[3]; - DWORD dwThreadID; - - TestData testData{countDownLatch, count}; - - // Setup 3 threads - for (int i = 0; i < 3; i++) { - // TODO: More complex scenarios may require use of a parameter - // to the thread procedure, such as an event per thread to - // be used for synchronization. - hThreads[i] = CreateThread( - NULL, // default security - 0, // default stack size - CountDownLatchTest::ThreadProcCountDown, // name of the thread function - &testData, // no thread parameters - 0, // default startup flags - &dwThreadID); - - EXPECT_TRUE(hThreads[i] != NULL); - } - - // Act - location::nearby::Exception result = countDownLatch->Await(); - - // - // Assert - EXPECT_EQ(result.value, location::nearby::Exception::kSuccess); - EXPECT_EQ(count, 3); -} - -TEST_F(CountDownLatchTests, CountDownLatchAwaitTimeoutTimesOut) { - // Arrange - LONG volatile count = 0; - - std::unique_ptr countDownLatch = - location::nearby::api::ImplementationPlatform::CreateCountDownLatch(3); - - // Act - location::nearby::ExceptionOr result = - countDownLatch->Await(absl::Milliseconds(5)); - - Sleep(40); - - // Assert - EXPECT_FALSE(result.GetResult()); - // TODO(jfcarroll)I think there's a bug in the shared version of this, it's - // not returning a timeout exception, need to look at it some more. - // EXPECT_EQ(result.GetException().value, - // location::nearby::Exception::kTimeout); -} - -TEST_F(CountDownLatchTests, CountDownLatchAwaitNoTimeoutSucceeds) { - // Arrange - LONG volatile count = 0; - - std::unique_ptr countDownLatch = - location::nearby::api::ImplementationPlatform::CreateCountDownLatch(3); - - TestData testData{countDownLatch, count}; - - HANDLE hThreads[3]; - DWORD dwThreadID; - - // Setup 3 threads - for (int i = 0; i < 3; i++) { - // TODO: More complex scenarios may require use of a parameter - // to the thread procedure, such as an event per thread to - // be used for synchronization. - hThreads[i] = CreateThread( - NULL, // default security - 0, // default stack size - CountDownLatchTest::ThreadProcCountDown, // name of the thread function - &testData, // no thread parameters - 0, // default startup flags - &dwThreadID); - - EXPECT_TRUE(hThreads[i] != NULL); - } - - WaitForMultipleObjects(3, hThreads, true, INFINITE); - // Act - location::nearby::ExceptionOr result = - countDownLatch->Await(absl::Milliseconds(100)); - - // Assert - EXPECT_TRUE(result.GetResult()); - EXPECT_EQ(result.GetException().value, location::nearby::Exception::kSuccess); - EXPECT_EQ(count, 3); -} - -TEST_F(CountDownLatchTests, CountDownLatchCountDownBeforeAwaitSucceeds) { - // Arrange - LONG volatile count = 0; - std::unique_ptr countDownLatch = - location::nearby::api::ImplementationPlatform::CreateCountDownLatch(1); - - HANDLE hThread; - DWORD dwThreadID; - - TestData testData{countDownLatch, count}; - - hThread = CreateThread( - NULL, // default security - 0, // default stack size - CountDownLatchTest::ThreadProcAwait, // name of the thread function - &testData, // no thread parameters - 0, // default startup flags - &dwThreadID); - - EXPECT_TRUE(hThread != NULL); - - // Act - countDownLatch->CountDown(); // This countdown occurs before the thread has a - // chance to run - - if (hThread != NULL) { - WaitForSingleObject(hThread, - INFINITE); // This will wait till the thread exits - } - - // Assert - EXPECT_EQ(count, 1); -} +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "platform/impl/shared/count_down_latch.h" + +#include + +#include "gtest/gtest.h" +#include "platform/api/platform.h" + +class CountDownLatchTests : public testing::Test { + public: + class TestData { + public: + std::unique_ptr& countDownLatch; + LONG volatile& count; + }; + + class CountDownLatchTest { + public: + static DWORD ThreadProcCountDown(LPVOID lpParam) { + TestData* testData = static_cast(lpParam); + + Sleep(1); + + InterlockedIncrement(&testData->count); + testData->countDownLatch->CountDown(); + return 0; + } + + static DWORD ThreadProcAwait(LPVOID lpParam) { + TestData* testData = static_cast(lpParam); + + Sleep(1); + + testData->countDownLatch->Await(); + InterlockedIncrement(&testData->count); + + return 0; + } + }; + + CountDownLatchTests() {} +}; + +TEST_F(CountDownLatchTests, CountDownLatchAwaitSucceeds) { + // Arrange + LONG volatile count = 0; + + std::unique_ptr countDownLatch = + location::nearby::api::ImplementationPlatform::CreateCountDownLatch(3); + + HANDLE hThreads[3]; + DWORD dwThreadID; + + TestData testData{countDownLatch, count}; + + // Setup 3 threads + for (int i = 0; i < 3; i++) { + // TODO: More complex scenarios may require use of a parameter + // to the thread procedure, such as an event per thread to + // be used for synchronization. + hThreads[i] = CreateThread( + NULL, // default security + 0, // default stack size + CountDownLatchTest::ThreadProcCountDown, // name of the thread function + &testData, // no thread parameters + 0, // default startup flags + &dwThreadID); + + EXPECT_TRUE(hThreads[i] != NULL); + } + + // Act + location::nearby::Exception result = countDownLatch->Await(); + + // + // Assert + EXPECT_EQ(result.value, location::nearby::Exception::kSuccess); + EXPECT_EQ(count, 3); +} + +TEST_F(CountDownLatchTests, CountDownLatchAwaitTimeoutTimesOut) { + // Arrange + LONG volatile count = 0; + + std::unique_ptr countDownLatch = + location::nearby::api::ImplementationPlatform::CreateCountDownLatch(3); + + // Act + location::nearby::ExceptionOr result = + countDownLatch->Await(absl::Milliseconds(5)); + + Sleep(40); + + // Assert + EXPECT_FALSE(result.GetResult()); + // TODO(jfcarroll)I think there's a bug in the shared version of this, it's + // not returning a timeout exception, need to look at it some more. + // EXPECT_EQ(result.GetException().value, + // location::nearby::Exception::kTimeout); +} + +TEST_F(CountDownLatchTests, CountDownLatchAwaitNoTimeoutSucceeds) { + // Arrange + LONG volatile count = 0; + + std::unique_ptr countDownLatch = + location::nearby::api::ImplementationPlatform::CreateCountDownLatch(3); + + TestData testData{countDownLatch, count}; + + HANDLE hThreads[3]; + DWORD dwThreadID; + + // Setup 3 threads + for (int i = 0; i < 3; i++) { + // TODO: More complex scenarios may require use of a parameter + // to the thread procedure, such as an event per thread to + // be used for synchronization. + hThreads[i] = CreateThread( + NULL, // default security + 0, // default stack size + CountDownLatchTest::ThreadProcCountDown, // name of the thread function + &testData, // no thread parameters + 0, // default startup flags + &dwThreadID); + + EXPECT_TRUE(hThreads[i] != NULL); + } + + WaitForMultipleObjects(3, hThreads, true, INFINITE); + // Act + location::nearby::ExceptionOr result = + countDownLatch->Await(absl::Milliseconds(100)); + + // Assert + EXPECT_TRUE(result.GetResult()); + EXPECT_EQ(result.GetException().value, location::nearby::Exception::kSuccess); + EXPECT_EQ(count, 3); +} + +TEST_F(CountDownLatchTests, CountDownLatchCountDownBeforeAwaitSucceeds) { + // Arrange + LONG volatile count = 0; + std::unique_ptr countDownLatch = + location::nearby::api::ImplementationPlatform::CreateCountDownLatch(1); + + HANDLE hThread; + DWORD dwThreadID; + + TestData testData{countDownLatch, count}; + + hThread = CreateThread( + NULL, // default security + 0, // default stack size + CountDownLatchTest::ThreadProcAwait, // name of the thread function + &testData, // no thread parameters + 0, // default startup flags + &dwThreadID); + + EXPECT_TRUE(hThread != NULL); + + // Act + countDownLatch->CountDown(); // This countdown occurs before the thread has a + // chance to run + + if (hThread != NULL) { + WaitForSingleObject(hThread, + INFINITE); // This will wait till the thread exits + } + + // Assert + EXPECT_EQ(count, 1); +} diff --git a/cpp/platform/impl/windows/executor_test.cc b/cpp/platform/impl/windows/executor_test.cc index 5ce5ca2f..fd4d6427 100644 --- a/cpp/platform/impl/windows/executor_test.cc +++ b/cpp/platform/impl/windows/executor_test.cc @@ -1,348 +1,348 @@ -// Copyright 2021 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "platform/impl/windows/executor.h" - -#include -#include - -#include "platform/impl/windows/test_data.h" - -#include "gtest/gtest.h" - -TEST(ExecutorTests, SingleThreadedExecutorSucceeds) { - // Arrange - std::string expected(RUNNABLE_0_TEXT.c_str()); - - std::unique_ptr executor = - std::make_unique(); - std::string output = std::string(); - // Container to note threads that ran - std::unique_ptr> threadIds = - std::make_unique>(); - - threadIds->push_back(GetCurrentThreadId()); - - // Act - executor->Execute([&output, &threadIds]() { - threadIds->push_back(GetCurrentThreadId()); - output.append(RUNNABLE_0_TEXT.c_str()); - }); - - executor->Shutdown(); - - // Assert - // We should've run 1 time on the main thread, and 5 times on the - // workerThread - ASSERT_EQ(threadIds->size(), 2); - // We should still be on the main thread - ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); - // We should've run all runnables on the worker thread - ASSERT_EQ(output, expected); -} - -TEST(ExecutorTests, SingleThreadedExecutorAfterShutdownFails) { - // Arrange - std::string expected(""); - - std::unique_ptr executor = - std::make_unique(); - std::unique_ptr output = std::make_unique(); - // Container to note threads that ran - std::unique_ptr> threadIds = - std::make_unique>(); - - threadIds->push_back(GetCurrentThreadId()); - executor->Shutdown(); - - // Act - executor->Execute([&output, &threadIds]() { - threadIds->push_back(GetCurrentThreadId()); - output->append(RUNNABLE_0_TEXT.c_str()); - }); - - // Assert - // We should've run 1 time on the main thread, and 5 times on the - // workerThread - ASSERT_EQ(threadIds->size(), 1); - // We should still be on the main thread - ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); - // We should've run all runnables on the worker thread - ASSERT_EQ(*output.get(), expected); -} - -TEST(ExecutorTests, SingleThreadedExecutorExecuteNullSucceeds) { - // Arrange - std::string expected(RUNNABLE_0_TEXT.c_str()); - - std::unique_ptr executor = - std::make_unique(); - std::string output = std::string(); - // Container to note threads that ran - std::unique_ptr> threadIds = - std::make_unique>(); - - threadIds->push_back(GetCurrentThreadId()); - - // Act - executor->Execute(nullptr); - executor->Execute([&output, &threadIds]() { - threadIds->push_back(GetCurrentThreadId()); - output.append(RUNNABLE_0_TEXT.c_str()); - }); - executor->Execute(nullptr); - - executor->Shutdown(); - - // Assert - // We should've run 1 time on the main thread, and 5 times on the - // workerThread - ASSERT_EQ(threadIds->size(), 2); - // We should still be on the main thread - ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); - // We should've run all runnables on the worker thread - ASSERT_EQ(output, expected); -} - -TEST(ExecutorTests, SingleThreadedExecutorMultipleTasksSucceeds) { - // Arrange - std::string expected(RUNNABLE_ALL_TEXT.c_str()); - - std::unique_ptr executor = - std::make_unique(); - std::string output = std::string(); - // Container to note threads that ran - std::unique_ptr> threadIds = - std::make_unique>(); - - threadIds->push_back(GetCurrentThreadId()); - - // Act - for (int index = 0; index < 5; index++) { - executor->Execute([&output, &threadIds, index]() { - threadIds->push_back(GetCurrentThreadId()); - char buffer[128]; - snprintf(buffer, sizeof(buffer), "%s%d, ", RUNNABLE_TEXT.c_str(), index); - output.append(std::string(buffer)); - }); - } - - executor->Shutdown(); - - // Assert - // We should've run 1 time on the main thread, and 5 times on the - // workerThread - ASSERT_EQ(threadIds->size(), 6); - // We should still be on the main thread - ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); - // We should've run all runnables on the worker thread - auto workerThreadId = threadIds->at(1); - for (int index = 1; index < threadIds->size(); index++) { - ASSERT_EQ(threadIds->at(index), workerThreadId); - } - - // We should of run them in the order submitted - ASSERT_EQ(output, expected); -} - -TEST(ExecutorTests, MultiThreadedExecutorSingleTaskSucceeds) { - // Arrange - std::string expected(RUNNABLE_0_TEXT.c_str()); - - std::unique_ptr executor = - std::make_unique(2); - - // Container to note threads that ran - std::unique_ptr> threadIds = - std::make_unique>(); - - std::shared_ptr output = std::make_shared(); - - threadIds->push_back(GetCurrentThreadId()); - - // Act - executor->Execute([output, &threadIds]() { - threadIds->push_back(GetCurrentThreadId()); - output->append(RUNNABLE_0_TEXT.c_str()); - }); - - executor->Shutdown(); - - // Assert - // We should've run 1 time on the main thread, and 5 times on the - // workerThread - ASSERT_EQ(threadIds->size(), 2); - // We should still be on the main thread - ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); - // We should've run the task - ASSERT_EQ(*output.get(), expected); -} - -TEST(ExecutorTests, MultiThreadedExecutorMultipleTasksSucceeds) { - // Arrange - std::unique_ptr executor = - std::make_unique(2); - - // Container to note threads that ran - std::unique_ptr> threadIds = - std::make_unique>(); - - std::shared_ptr output = std::make_shared(); - - threadIds->push_back(GetCurrentThreadId()); - - // Act - for (int index = 0; index < 5; index++) { - executor->Execute([&output, &threadIds, index]() { - threadIds->push_back(GetCurrentThreadId()); - char buffer[128]; - snprintf(buffer, sizeof(buffer), "%s %d, ", RUNNABLE_TEXT.c_str(), index); - output->append(std::string(buffer)); - }); - } - - executor->Shutdown(); - - // Assert - // We should've run 1 time on the main thread, and 5 times on the - // workerThread - ASSERT_EQ(threadIds->size(), 6); - // We should still be on the main thread - ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); -} - -TEST(ExecutorTests, MultiThreadedExecutorSingleTaskAfterShutdownFails) { - // Arrange - std::string expected(""); - - std::unique_ptr executor = - std::make_unique(2); - - // Container to note threads that ran - std::unique_ptr> threadIds = - std::make_unique>(); - - std::shared_ptr output = std::make_shared(); - - threadIds->push_back(GetCurrentThreadId()); - - executor->Shutdown(); - - // Act - executor->Execute([output, &threadIds]() { - threadIds->push_back(GetCurrentThreadId()); - output->append(RUNNABLE_0_TEXT.c_str()); - }); - - // Assert - // We should've run 1 time on the main thread, and 5 times on the - // workerThread - ASSERT_EQ(threadIds->size(), 1); - // We should still be on the main thread - ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); - // We should've run the task - ASSERT_EQ(*output.get(), expected); -} - -TEST(ExecutorTests, MultiThreadedExecutorNegativeThreadsThrows) { - // Arrange - // Act - // Assert - EXPECT_THROW( - { - try { - auto result = - std::make_unique(-1); - } catch (const std::invalid_argument::exception& e) { - // and this tests that it has the correct message - EXPECT_STREQ(INVALID_ARGUMENT_TEXT, e.what()); - throw; - } - }, - std::invalid_argument); -} - -TEST(ExecutorTests, MultiThreadedExecutorTooManyThreadsThrows) { - // Arrange - // Act - // Assert - EXPECT_THROW( - { - try { - auto result = - std::make_unique(65); - } catch (const location::nearby::windows::ThreadPoolException& e) { - // and this tests that it has the correct message - EXPECT_STREQ(THREADPOOL_MAX_SIZE_TEXT, e.what()); - throw; - } - }, - location::nearby::windows::ThreadPoolException); -} - -TEST(ExecutorTests, - MultiThreadedExecutorMultipleTasksLargeNumberOfThreadsSucceeds) { - // Arrange - std::unique_ptr executor = - std::make_unique( - MAXIMUM_WAIT_OBJECTS - 1); - - // Container to note threads that ran - std::vector threadIds = std::vector(); - - std::shared_ptr output = std::make_shared(); - - threadIds.push_back(GetCurrentThreadId()); - - CRITICAL_SECTION testCriticalSection; - InitializeCriticalSection(&testCriticalSection); - - // Act - for (int index = 0; index < 250; index++) { - executor->Execute( - [output, &threadIds, index, &testCriticalSection]() mutable { - DWORD id = GetCurrentThreadId(); - - EnterCriticalSection(&testCriticalSection); - - threadIds.push_back(id); - output->append(RUNNABLE_TEXT); - output->append(std::to_string(index)); - output->append(RUNNABLE_SEPARATOR_TEXT); - - LeaveCriticalSection(&testCriticalSection); - // Using rand since this is in a critical section - // and windows doesn't have a rand_r anyway - auto sleepTime = (std::rand() % 101) + 1; // NOLINT - - Sleep(sleepTime); - }); - } - - executor->Shutdown(); - DeleteCriticalSection(&testCriticalSection); - - // Assert - // We should still be on the main thread - ASSERT_EQ(GetCurrentThreadId(), threadIds.at(0)); - - std::sort(threadIds.begin(), threadIds.end()); - int64_t uniqueIds = - std::unique(threadIds.begin(), threadIds.end()) - threadIds.begin(); - - ASSERT_EQ(uniqueIds, 64); - // We should've run 1 time on the main thread, and 200 times on the - // workerThreads - ASSERT_EQ(threadIds.size(), 251); -} +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "platform/impl/windows/executor.h" + +#include +#include + +#include "platform/impl/windows/test_data.h" + +#include "gtest/gtest.h" + +TEST(ExecutorTests, SingleThreadedExecutorSucceeds) { + // Arrange + std::string expected(RUNNABLE_0_TEXT.c_str()); + + std::unique_ptr executor = + std::make_unique(); + std::string output = std::string(); + // Container to note threads that ran + std::unique_ptr> threadIds = + std::make_unique>(); + + threadIds->push_back(GetCurrentThreadId()); + + // Act + executor->Execute([&output, &threadIds]() { + threadIds->push_back(GetCurrentThreadId()); + output.append(RUNNABLE_0_TEXT.c_str()); + }); + + executor->Shutdown(); + + // Assert + // We should've run 1 time on the main thread, and 5 times on the + // workerThread + ASSERT_EQ(threadIds->size(), 2); + // We should still be on the main thread + ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); + // We should've run all runnables on the worker thread + ASSERT_EQ(output, expected); +} + +TEST(ExecutorTests, SingleThreadedExecutorAfterShutdownFails) { + // Arrange + std::string expected(""); + + std::unique_ptr executor = + std::make_unique(); + std::unique_ptr output = std::make_unique(); + // Container to note threads that ran + std::unique_ptr> threadIds = + std::make_unique>(); + + threadIds->push_back(GetCurrentThreadId()); + executor->Shutdown(); + + // Act + executor->Execute([&output, &threadIds]() { + threadIds->push_back(GetCurrentThreadId()); + output->append(RUNNABLE_0_TEXT.c_str()); + }); + + // Assert + // We should've run 1 time on the main thread, and 5 times on the + // workerThread + ASSERT_EQ(threadIds->size(), 1); + // We should still be on the main thread + ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); + // We should've run all runnables on the worker thread + ASSERT_EQ(*output.get(), expected); +} + +TEST(ExecutorTests, SingleThreadedExecutorExecuteNullSucceeds) { + // Arrange + std::string expected(RUNNABLE_0_TEXT.c_str()); + + std::unique_ptr executor = + std::make_unique(); + std::string output = std::string(); + // Container to note threads that ran + std::unique_ptr> threadIds = + std::make_unique>(); + + threadIds->push_back(GetCurrentThreadId()); + + // Act + executor->Execute(nullptr); + executor->Execute([&output, &threadIds]() { + threadIds->push_back(GetCurrentThreadId()); + output.append(RUNNABLE_0_TEXT.c_str()); + }); + executor->Execute(nullptr); + + executor->Shutdown(); + + // Assert + // We should've run 1 time on the main thread, and 5 times on the + // workerThread + ASSERT_EQ(threadIds->size(), 2); + // We should still be on the main thread + ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); + // We should've run all runnables on the worker thread + ASSERT_EQ(output, expected); +} + +TEST(ExecutorTests, SingleThreadedExecutorMultipleTasksSucceeds) { + // Arrange + std::string expected(RUNNABLE_ALL_TEXT.c_str()); + + std::unique_ptr executor = + std::make_unique(); + std::string output = std::string(); + // Container to note threads that ran + std::unique_ptr> threadIds = + std::make_unique>(); + + threadIds->push_back(GetCurrentThreadId()); + + // Act + for (int index = 0; index < 5; index++) { + executor->Execute([&output, &threadIds, index]() { + threadIds->push_back(GetCurrentThreadId()); + char buffer[128]; + snprintf(buffer, sizeof(buffer), "%s%d, ", RUNNABLE_TEXT.c_str(), index); + output.append(std::string(buffer)); + }); + } + + executor->Shutdown(); + + // Assert + // We should've run 1 time on the main thread, and 5 times on the + // workerThread + ASSERT_EQ(threadIds->size(), 6); + // We should still be on the main thread + ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); + // We should've run all runnables on the worker thread + auto workerThreadId = threadIds->at(1); + for (int index = 1; index < threadIds->size(); index++) { + ASSERT_EQ(threadIds->at(index), workerThreadId); + } + + // We should of run them in the order submitted + ASSERT_EQ(output, expected); +} + +TEST(ExecutorTests, MultiThreadedExecutorSingleTaskSucceeds) { + // Arrange + std::string expected(RUNNABLE_0_TEXT.c_str()); + + std::unique_ptr executor = + std::make_unique(2); + + // Container to note threads that ran + std::unique_ptr> threadIds = + std::make_unique>(); + + std::shared_ptr output = std::make_shared(); + + threadIds->push_back(GetCurrentThreadId()); + + // Act + executor->Execute([output, &threadIds]() { + threadIds->push_back(GetCurrentThreadId()); + output->append(RUNNABLE_0_TEXT.c_str()); + }); + + executor->Shutdown(); + + // Assert + // We should've run 1 time on the main thread, and 5 times on the + // workerThread + ASSERT_EQ(threadIds->size(), 2); + // We should still be on the main thread + ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); + // We should've run the task + ASSERT_EQ(*output.get(), expected); +} + +TEST(ExecutorTests, MultiThreadedExecutorMultipleTasksSucceeds) { + // Arrange + std::unique_ptr executor = + std::make_unique(2); + + // Container to note threads that ran + std::unique_ptr> threadIds = + std::make_unique>(); + + std::shared_ptr output = std::make_shared(); + + threadIds->push_back(GetCurrentThreadId()); + + // Act + for (int index = 0; index < 5; index++) { + executor->Execute([&output, &threadIds, index]() { + threadIds->push_back(GetCurrentThreadId()); + char buffer[128]; + snprintf(buffer, sizeof(buffer), "%s %d, ", RUNNABLE_TEXT.c_str(), index); + output->append(std::string(buffer)); + }); + } + + executor->Shutdown(); + + // Assert + // We should've run 1 time on the main thread, and 5 times on the + // workerThread + ASSERT_EQ(threadIds->size(), 6); + // We should still be on the main thread + ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); +} + +TEST(ExecutorTests, MultiThreadedExecutorSingleTaskAfterShutdownFails) { + // Arrange + std::string expected(""); + + std::unique_ptr executor = + std::make_unique(2); + + // Container to note threads that ran + std::unique_ptr> threadIds = + std::make_unique>(); + + std::shared_ptr output = std::make_shared(); + + threadIds->push_back(GetCurrentThreadId()); + + executor->Shutdown(); + + // Act + executor->Execute([output, &threadIds]() { + threadIds->push_back(GetCurrentThreadId()); + output->append(RUNNABLE_0_TEXT.c_str()); + }); + + // Assert + // We should've run 1 time on the main thread, and 5 times on the + // workerThread + ASSERT_EQ(threadIds->size(), 1); + // We should still be on the main thread + ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); + // We should've run the task + ASSERT_EQ(*output.get(), expected); +} + +TEST(ExecutorTests, MultiThreadedExecutorNegativeThreadsThrows) { + // Arrange + // Act + // Assert + EXPECT_THROW( + { + try { + auto result = + std::make_unique(-1); + } catch (const std::invalid_argument::exception& e) { + // and this tests that it has the correct message + EXPECT_STREQ(INVALID_ARGUMENT_TEXT, e.what()); + throw; + } + }, + std::invalid_argument); +} + +TEST(ExecutorTests, MultiThreadedExecutorTooManyThreadsThrows) { + // Arrange + // Act + // Assert + EXPECT_THROW( + { + try { + auto result = + std::make_unique(65); + } catch (const location::nearby::windows::ThreadPoolException& e) { + // and this tests that it has the correct message + EXPECT_STREQ(THREADPOOL_MAX_SIZE_TEXT, e.what()); + throw; + } + }, + location::nearby::windows::ThreadPoolException); +} + +TEST(ExecutorTests, + MultiThreadedExecutorMultipleTasksLargeNumberOfThreadsSucceeds) { + // Arrange + std::unique_ptr executor = + std::make_unique( + MAXIMUM_WAIT_OBJECTS - 1); + + // Container to note threads that ran + std::vector threadIds = std::vector(); + + std::shared_ptr output = std::make_shared(); + + threadIds.push_back(GetCurrentThreadId()); + + CRITICAL_SECTION testCriticalSection; + InitializeCriticalSection(&testCriticalSection); + + // Act + for (int index = 0; index < 250; index++) { + executor->Execute( + [output, &threadIds, index, &testCriticalSection]() mutable { + DWORD id = GetCurrentThreadId(); + + EnterCriticalSection(&testCriticalSection); + + threadIds.push_back(id); + output->append(RUNNABLE_TEXT); + output->append(std::to_string(index)); + output->append(RUNNABLE_SEPARATOR_TEXT); + + LeaveCriticalSection(&testCriticalSection); + // Using rand since this is in a critical section + // and windows doesn't have a rand_r anyway + auto sleepTime = (std::rand() % 101) + 1; // NOLINT + + Sleep(sleepTime); + }); + } + + executor->Shutdown(); + DeleteCriticalSection(&testCriticalSection); + + // Assert + // We should still be on the main thread + ASSERT_EQ(GetCurrentThreadId(), threadIds.at(0)); + + std::sort(threadIds.begin(), threadIds.end()); + int64_t uniqueIds = + std::unique(threadIds.begin(), threadIds.end()) - threadIds.begin(); + + ASSERT_EQ(uniqueIds, 64); + // We should've run 1 time on the main thread, and 200 times on the + // workerThreads + ASSERT_EQ(threadIds.size(), 251); +} diff --git a/cpp/platform/impl/windows/generated/BUILD b/cpp/platform/impl/windows/generated/BUILD index bdd07fa8..c3c5a2b7 100644 --- a/cpp/platform/impl/windows/generated/BUILD +++ b/cpp/platform/impl/windows/generated/BUILD @@ -36,7 +36,7 @@ cc_library( ], textual_hdrs = glob(["**/*.h"]), visibility = [ - "//third_party/nearby_connections/connections/windows:__subpackages__", + "//third_party/nearby/connections/windows:__subpackages__", "//platform/impl/windows:__subpackages__", ], ) diff --git a/cpp/platform/impl/windows/input_file_test.cc b/cpp/platform/impl/windows/input_file_test.cc index 5d796cf8..eb2bf811 100644 --- a/cpp/platform/impl/windows/input_file_test.cc +++ b/cpp/platform/impl/windows/input_file_test.cc @@ -1,152 +1,152 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "platform/impl/windows/input_file.h" - -#include "gtest/gtest.h" -#include "platform/base/exception.h" -#include "platform/base/payload_id.h" -#include "platform/impl/windows/test_utils.h" -#include "platform/public/logging.h" - -class InputFileTests : public testing::Test { - protected: - // You can define per-test set-up logic as usual. - void SetUp() override { - location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - - hFile_ = CreateFileA( - test_utils::GetPayloadPath(payloadId).c_str(), // name of the write - GENERIC_WRITE, // open for writing - 0, // do not share - NULL, // default security - CREATE_ALWAYS, // create new file only - FILE_ATTRIBUTE_NORMAL, // normal file - NULL); // no attr. template - - if (hFile_ == INVALID_HANDLE_VALUE) { - NEARBY_LOG(ERROR, - "Failed to create OutputFile with payloadId: %s and error: %d", - test_utils::GetPayloadPath(payloadId).c_str(), GetLastError()); - } - - const char* buffer = TEST_STRING; - DWORD bytesWritten; - - WriteFile(hFile_, buffer, lstrlenA(buffer) * sizeof(char), &bytesWritten, - nullptr); - - CloseHandle(hFile_); - } - - // You can define per-test tear-down logic as usual. - void TearDown() override { - location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - if (FileExists(test_utils::GetPayloadPath(payloadId).c_str())) { - DeleteFileA(test_utils::GetPayloadPath(payloadId).c_str()); - } - } - - BOOL FileExists(const char* szPath) { - DWORD dwAttrib = GetFileAttributesA(szPath); - - return (dwAttrib != INVALID_FILE_ATTRIBUTES && - !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); - } - - private: - HANDLE hFile_ = nullptr; -}; - -TEST_F(InputFileTests, SuccessfulCreation) { - location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - std::unique_ptr inputFile = nullptr; - - inputFile = location::nearby::api::ImplementationPlatform::CreateInputFile( - payloadId, strlen(TEST_STRING)); - - EXPECT_NE(inputFile, nullptr); - EXPECT_EQ(inputFile->Close(), - location::nearby::Exception{location::nearby::Exception::kSuccess}); -} - -TEST_F(InputFileTests, SuccessfulGetFilePath) { - location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - std::unique_ptr inputFile = nullptr; - std::string fileName; - - inputFile = location::nearby::api::ImplementationPlatform::CreateInputFile( - payloadId, strlen(TEST_STRING)); - - fileName = inputFile->GetFilePath(); - - EXPECT_EQ(inputFile->Close(), - location::nearby::Exception{location::nearby::Exception::kSuccess}); - - EXPECT_EQ(fileName, test_utils::GetPayloadPath(payloadId).c_str()); -} - -TEST_F(InputFileTests, SuccessfulGetTotalSize) { - location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - std::unique_ptr inputFile = nullptr; - int64_t size = -1; - - inputFile = location::nearby::api::ImplementationPlatform::CreateInputFile( - payloadId, strlen(TEST_STRING)); - - size = inputFile->GetTotalSize(); - - EXPECT_EQ(inputFile->Close(), - location::nearby::Exception{location::nearby::Exception::kSuccess}); - - EXPECT_EQ(size, strlen(TEST_STRING)); -} - -TEST_F(InputFileTests, SuccessfulRead) { - location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - std::unique_ptr inputFile = nullptr; - - inputFile = location::nearby::api::ImplementationPlatform::CreateInputFile( - payloadId, strlen(TEST_STRING)); - - auto fileSize = inputFile->GetTotalSize(); - auto dataRead = inputFile->Read(fileSize); - - EXPECT_TRUE(dataRead.ok()); - EXPECT_EQ(inputFile->Close(), - location::nearby::Exception{location::nearby::Exception::kSuccess}); - - EXPECT_STREQ(std::string(dataRead.result()).c_str(), TEST_STRING); -} - -TEST_F(InputFileTests, FailedRead) { - location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - std::unique_ptr inputFile = nullptr; - - inputFile = location::nearby::api::ImplementationPlatform::CreateInputFile( - payloadId, strlen(TEST_STRING)); - - auto fileSize = inputFile->GetTotalSize(); - EXPECT_NE(fileSize, -1); - - auto dataRead = inputFile->Read(fileSize); - EXPECT_TRUE(dataRead.ok()); - - dataRead = inputFile->Read(fileSize); - std::string data = std::string(dataRead.result()); - - inputFile->Close(); - - EXPECT_STREQ(data.c_str(), ""); -} +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "platform/impl/windows/input_file.h" + +#include "gtest/gtest.h" +#include "platform/base/exception.h" +#include "platform/base/payload_id.h" +#include "platform/impl/windows/test_utils.h" +#include "platform/public/logging.h" + +class InputFileTests : public testing::Test { + protected: + // You can define per-test set-up logic as usual. + void SetUp() override { + location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); + + hFile_ = CreateFileA( + test_utils::GetPayloadPath(payloadId).c_str(), // name of the write + GENERIC_WRITE, // open for writing + 0, // do not share + NULL, // default security + CREATE_ALWAYS, // create new file only + FILE_ATTRIBUTE_NORMAL, // normal file + NULL); // no attr. template + + if (hFile_ == INVALID_HANDLE_VALUE) { + NEARBY_LOG(ERROR, + "Failed to create OutputFile with payloadId: %s and error: %d", + test_utils::GetPayloadPath(payloadId).c_str(), GetLastError()); + } + + const char* buffer = TEST_STRING; + DWORD bytesWritten; + + WriteFile(hFile_, buffer, lstrlenA(buffer) * sizeof(char), &bytesWritten, + nullptr); + + CloseHandle(hFile_); + } + + // You can define per-test tear-down logic as usual. + void TearDown() override { + location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); + if (FileExists(test_utils::GetPayloadPath(payloadId).c_str())) { + DeleteFileA(test_utils::GetPayloadPath(payloadId).c_str()); + } + } + + BOOL FileExists(const char* szPath) { + DWORD dwAttrib = GetFileAttributesA(szPath); + + return (dwAttrib != INVALID_FILE_ATTRIBUTES && + !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); + } + + private: + HANDLE hFile_ = nullptr; +}; + +TEST_F(InputFileTests, SuccessfulCreation) { + location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); + std::unique_ptr inputFile = nullptr; + + inputFile = location::nearby::api::ImplementationPlatform::CreateInputFile( + payloadId, strlen(TEST_STRING)); + + EXPECT_NE(inputFile, nullptr); + EXPECT_EQ(inputFile->Close(), + location::nearby::Exception{location::nearby::Exception::kSuccess}); +} + +TEST_F(InputFileTests, SuccessfulGetFilePath) { + location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); + std::unique_ptr inputFile = nullptr; + std::string fileName; + + inputFile = location::nearby::api::ImplementationPlatform::CreateInputFile( + payloadId, strlen(TEST_STRING)); + + fileName = inputFile->GetFilePath(); + + EXPECT_EQ(inputFile->Close(), + location::nearby::Exception{location::nearby::Exception::kSuccess}); + + EXPECT_EQ(fileName, test_utils::GetPayloadPath(payloadId).c_str()); +} + +TEST_F(InputFileTests, SuccessfulGetTotalSize) { + location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); + std::unique_ptr inputFile = nullptr; + int64_t size = -1; + + inputFile = location::nearby::api::ImplementationPlatform::CreateInputFile( + payloadId, strlen(TEST_STRING)); + + size = inputFile->GetTotalSize(); + + EXPECT_EQ(inputFile->Close(), + location::nearby::Exception{location::nearby::Exception::kSuccess}); + + EXPECT_EQ(size, strlen(TEST_STRING)); +} + +TEST_F(InputFileTests, SuccessfulRead) { + location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); + std::unique_ptr inputFile = nullptr; + + inputFile = location::nearby::api::ImplementationPlatform::CreateInputFile( + payloadId, strlen(TEST_STRING)); + + auto fileSize = inputFile->GetTotalSize(); + auto dataRead = inputFile->Read(fileSize); + + EXPECT_TRUE(dataRead.ok()); + EXPECT_EQ(inputFile->Close(), + location::nearby::Exception{location::nearby::Exception::kSuccess}); + + EXPECT_STREQ(std::string(dataRead.result()).c_str(), TEST_STRING); +} + +TEST_F(InputFileTests, FailedRead) { + location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); + std::unique_ptr inputFile = nullptr; + + inputFile = location::nearby::api::ImplementationPlatform::CreateInputFile( + payloadId, strlen(TEST_STRING)); + + auto fileSize = inputFile->GetTotalSize(); + EXPECT_NE(fileSize, -1); + + auto dataRead = inputFile->Read(fileSize); + EXPECT_TRUE(dataRead.ok()); + + dataRead = inputFile->Read(fileSize); + std::string data = std::string(dataRead.result()); + + inputFile->Close(); + + EXPECT_STREQ(data.c_str(), ""); +} diff --git a/cpp/platform/impl/windows/mutex_test.cc b/cpp/platform/impl/windows/mutex_test.cc index d66d52cf..ff9ea464 100644 --- a/cpp/platform/impl/windows/mutex_test.cc +++ b/cpp/platform/impl/windows/mutex_test.cc @@ -1,109 +1,109 @@ -// Copyright 2021 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "platform/impl/windows/mutex.h" - -#include // NOLINT - -#include "gtest/gtest.h" - -class MutexTests : public testing::Test { - public: - class MutexTest { - public: - MutexTest(location::nearby::windows::Mutex& mutex) : mutex_(mutex) {} - - std::future WaitForLock() { // NOLINT - return std::async( - std::launch::async, - // for this lambda you need C++14 - [this]() mutable { - std::unique_lock lck(mutex_.GetWindowsMutex()); - return true; - }); - } - - void PostEvent() { - std::lock_guard guard(mutex_.GetWindowsMutex()); - mutex_.Unlock(); - } - - private: - location::nearby::windows::Mutex& mutex_; - }; -}; - -TEST_F(MutexTests, SuccessfulRecursiveCreation) { - // Arrange - location::nearby::windows::Mutex mutex = location::nearby::windows::Mutex( - location::nearby::windows::Mutex::Mode::kRecursive); - - // Act - std::recursive_mutex& actual = mutex.GetWindowsRecursiveMutex(); - - // Assert - ASSERT_TRUE(actual.native_handle() != nullptr); -} - -TEST_F(MutexTests, SuccessfulCreation) { - // Arrange - location::nearby::windows::Mutex mutex( - location::nearby::windows::Mutex::Mode::kRegular); - - // Act - std::mutex& actual = mutex.GetWindowsMutex(); - - // Assert - ASSERT_TRUE(actual.native_handle() != nullptr); -} - -TEST_F(MutexTests, SuccessfulSignal) { - // Arrange - location::nearby::windows::Mutex mutex( - location::nearby::windows::Mutex::Mode::kRegular); - - location::nearby::windows::Mutex& mutexRef = mutex; - MutexTest mutexTest(mutexRef); - - mutex.Lock(); - - // Act - auto result = mutexTest.WaitForLock(); - mutex.Unlock(); - - // Assert - ASSERT_TRUE(result.get()); -} - -TEST_F(MutexTests, SuccessfulRecursiveSignal) { - // Arrange - location::nearby::windows::Mutex mutex( - location::nearby::windows::Mutex::Mode::kRecursive); - - location::nearby::windows::Mutex& mutexRef = mutex; - MutexTest mutexTest(mutexRef); - - mutex.Lock(); - mutex.Lock(); - mutex.Lock(); - - // Act - auto result = mutexTest.WaitForLock(); - mutex.Unlock(); - mutex.Unlock(); - mutex.Unlock(); - - // Assert - ASSERT_TRUE(result.get()); -} +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "platform/impl/windows/mutex.h" + +#include // NOLINT + +#include "gtest/gtest.h" + +class MutexTests : public testing::Test { + public: + class MutexTest { + public: + MutexTest(location::nearby::windows::Mutex& mutex) : mutex_(mutex) {} + + std::future WaitForLock() { // NOLINT + return std::async( + std::launch::async, + // for this lambda you need C++14 + [this]() mutable { + std::unique_lock lck(mutex_.GetWindowsMutex()); + return true; + }); + } + + void PostEvent() { + std::lock_guard guard(mutex_.GetWindowsMutex()); + mutex_.Unlock(); + } + + private: + location::nearby::windows::Mutex& mutex_; + }; +}; + +TEST_F(MutexTests, SuccessfulRecursiveCreation) { + // Arrange + location::nearby::windows::Mutex mutex = location::nearby::windows::Mutex( + location::nearby::windows::Mutex::Mode::kRecursive); + + // Act + std::recursive_mutex& actual = mutex.GetWindowsRecursiveMutex(); + + // Assert + ASSERT_TRUE(actual.native_handle() != nullptr); +} + +TEST_F(MutexTests, SuccessfulCreation) { + // Arrange + location::nearby::windows::Mutex mutex( + location::nearby::windows::Mutex::Mode::kRegular); + + // Act + std::mutex& actual = mutex.GetWindowsMutex(); + + // Assert + ASSERT_TRUE(actual.native_handle() != nullptr); +} + +TEST_F(MutexTests, SuccessfulSignal) { + // Arrange + location::nearby::windows::Mutex mutex( + location::nearby::windows::Mutex::Mode::kRegular); + + location::nearby::windows::Mutex& mutexRef = mutex; + MutexTest mutexTest(mutexRef); + + mutex.Lock(); + + // Act + auto result = mutexTest.WaitForLock(); + mutex.Unlock(); + + // Assert + ASSERT_TRUE(result.get()); +} + +TEST_F(MutexTests, SuccessfulRecursiveSignal) { + // Arrange + location::nearby::windows::Mutex mutex( + location::nearby::windows::Mutex::Mode::kRecursive); + + location::nearby::windows::Mutex& mutexRef = mutex; + MutexTest mutexTest(mutexRef); + + mutex.Lock(); + mutex.Lock(); + mutex.Lock(); + + // Act + auto result = mutexTest.WaitForLock(); + mutex.Unlock(); + mutex.Unlock(); + mutex.Unlock(); + + // Assert + ASSERT_TRUE(result.get()); +} diff --git a/cpp/platform/impl/windows/output_file_test.cc b/cpp/platform/impl/windows/output_file_test.cc index c4560de6..18e47f93 100644 --- a/cpp/platform/impl/windows/output_file_test.cc +++ b/cpp/platform/impl/windows/output_file_test.cc @@ -1,90 +1,90 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "platform/impl/windows/output_file.h" - -#include "gtest/gtest.h" -#include "platform/api/platform.h" -#include "platform/base/exception.h" -#include "platform/base/payload_id.h" -#include "platform/impl/windows/test_utils.h" - -class OutputFileTests : public testing::Test { - protected: - // You can define per-test set-up logic as usual. - void SetUp() override { - location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - if (FileExists(test_utils::GetPayloadPath(payloadId).c_str())) { - DeleteFileA(test_utils::GetPayloadPath(payloadId).c_str()); - } - } - - // You can define per-test tear-down logic as usual. - void TearDown() override { - location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - if (FileExists(test_utils::GetPayloadPath(payloadId).c_str())) { - DeleteFileA(test_utils::GetPayloadPath(payloadId).c_str()); - } - } - - BOOL FileExists(const char* szPath) { - DWORD dwAttrib = GetFileAttributesA(szPath); - - return (dwAttrib != INVALID_FILE_ATTRIBUTES && - !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); - } -}; - -TEST_F(OutputFileTests, SuccessfulCreation) { - location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - std::unique_ptr outputFile = nullptr; - - EXPECT_NO_THROW( - outputFile = - location::nearby::api::ImplementationPlatform::CreateOutputFile( - payloadId)); - - EXPECT_NE(outputFile, nullptr); - EXPECT_NO_THROW(outputFile->Close()); -} - -TEST_F(OutputFileTests, SuccessfulClose) { - location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - std::unique_ptr outputFile = nullptr; - - EXPECT_NO_THROW( - outputFile = - location::nearby::api::ImplementationPlatform::CreateOutputFile( - payloadId)); - - EXPECT_NO_THROW(outputFile->Close()); - - DeleteFileA(test_utils::GetPayloadPath(payloadId).c_str()); -} - -TEST_F(OutputFileTests, SuccessfulWrite) { - location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); - location::nearby::ByteArray data(std::string(TEST_STRING)); - std::unique_ptr outputFile = nullptr; - - EXPECT_NO_THROW( - outputFile = - location::nearby::api::ImplementationPlatform::CreateOutputFile( - payloadId)); - - EXPECT_NO_THROW(outputFile->Write(data)); - EXPECT_NO_THROW(outputFile->Close()); - - DeleteFileA(test_utils::GetPayloadPath(payloadId).c_str()); -} +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "platform/impl/windows/output_file.h" + +#include "gtest/gtest.h" +#include "platform/api/platform.h" +#include "platform/base/exception.h" +#include "platform/base/payload_id.h" +#include "platform/impl/windows/test_utils.h" + +class OutputFileTests : public testing::Test { + protected: + // You can define per-test set-up logic as usual. + void SetUp() override { + location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); + if (FileExists(test_utils::GetPayloadPath(payloadId).c_str())) { + DeleteFileA(test_utils::GetPayloadPath(payloadId).c_str()); + } + } + + // You can define per-test tear-down logic as usual. + void TearDown() override { + location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); + if (FileExists(test_utils::GetPayloadPath(payloadId).c_str())) { + DeleteFileA(test_utils::GetPayloadPath(payloadId).c_str()); + } + } + + BOOL FileExists(const char* szPath) { + DWORD dwAttrib = GetFileAttributesA(szPath); + + return (dwAttrib != INVALID_FILE_ATTRIBUTES && + !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); + } +}; + +TEST_F(OutputFileTests, SuccessfulCreation) { + location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); + std::unique_ptr outputFile = nullptr; + + EXPECT_NO_THROW( + outputFile = + location::nearby::api::ImplementationPlatform::CreateOutputFile( + payloadId)); + + EXPECT_NE(outputFile, nullptr); + EXPECT_NO_THROW(outputFile->Close()); +} + +TEST_F(OutputFileTests, SuccessfulClose) { + location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); + std::unique_ptr outputFile = nullptr; + + EXPECT_NO_THROW( + outputFile = + location::nearby::api::ImplementationPlatform::CreateOutputFile( + payloadId)); + + EXPECT_NO_THROW(outputFile->Close()); + + DeleteFileA(test_utils::GetPayloadPath(payloadId).c_str()); +} + +TEST_F(OutputFileTests, SuccessfulWrite) { + location::nearby::PayloadId payloadId(TEST_PAYLOAD_ID); + location::nearby::ByteArray data(std::string(TEST_STRING)); + std::unique_ptr outputFile = nullptr; + + EXPECT_NO_THROW( + outputFile = + location::nearby::api::ImplementationPlatform::CreateOutputFile( + payloadId)); + + EXPECT_NO_THROW(outputFile->Write(data)); + EXPECT_NO_THROW(outputFile->Close()); + + DeleteFileA(test_utils::GetPayloadPath(payloadId).c_str()); +} diff --git a/cpp/platform/impl/windows/runner.h b/cpp/platform/impl/windows/runner.h index 2363d2b7..911168a8 100644 --- a/cpp/platform/impl/windows/runner.h +++ b/cpp/platform/impl/windows/runner.h @@ -1,42 +1,42 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef PLATFORM_IMPL_WINDOWS_RUNNER_H_ -#define PLATFORM_IMPL_WINDOWS_RUNNER_H_ - -#include "platform/base/runnable.h" - -namespace location { -namespace nearby { -namespace windows { - -class ThreadPool; - -class Runner { - public: - Runner(std::function runnable) - : thread_pool_(nullptr), runnable_(runnable) {} - void Run() { runnable_(); } - ~Runner(){} - ThreadPool* thread_pool_; - - private: - std::function runnable_; -}; - -} // namespace windows -} // namespace nearby -} // namespace location - -#endif // PLATFORM_IMPL_WINDOWS_RUNNER_H_ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef PLATFORM_IMPL_WINDOWS_RUNNER_H_ +#define PLATFORM_IMPL_WINDOWS_RUNNER_H_ + +#include "platform/base/runnable.h" + +namespace location { +namespace nearby { +namespace windows { + +class ThreadPool; + +class Runner { + public: + Runner(std::function runnable) + : thread_pool_(nullptr), runnable_(runnable) {} + void Run() { runnable_(); } + ~Runner(){} + ThreadPool* thread_pool_; + + private: + std::function runnable_; +}; + +} // namespace windows +} // namespace nearby +} // namespace location + +#endif // PLATFORM_IMPL_WINDOWS_RUNNER_H_ diff --git a/cpp/platform/impl/windows/scheduled_executor_test.cc b/cpp/platform/impl/windows/scheduled_executor_test.cc index 1cc121ac..4a52c207 100644 --- a/cpp/platform/impl/windows/scheduled_executor_test.cc +++ b/cpp/platform/impl/windows/scheduled_executor_test.cc @@ -1,174 +1,174 @@ -// Copyright 2021 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#include "platform/impl/windows/scheduled_executor.h" - -#include - -#include "platform/impl/windows/test_data.h" - -#include "gtest/gtest.h" - -TEST(ScheduledExecutorTests, ExecuteSucceeds) { - // Arrange - std::string expected(RUNNABLE_0_TEXT.c_str()); - - std::unique_ptr - submittableExecutor = - std::make_unique(); - std::string output = std::string(); - // Container to note threads that ran - std::unique_ptr> threadIds = - std::make_unique>(); - - threadIds->push_back(GetCurrentThreadId()); - - // Act - submittableExecutor->Execute([&output, &threadIds]() { - threadIds->push_back(GetCurrentThreadId()); - output.append(RUNNABLE_0_TEXT.c_str()); - }); - - submittableExecutor->Shutdown(); - - // Assert - // We should've run 1 time on the main thread, and 1 times on the - // workerThread - ASSERT_EQ(threadIds->size(), 2); - // We should still be on the main thread - ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); - // We should've run all runnables on the worker thread - ASSERT_EQ(output, expected); -} - -TEST(ScheduledExecutorTests, ScheduleSucceeds) { - // Arrange - std::string expected(RUNNABLE_0_TEXT.c_str()); - - std::unique_ptr - submittableExecutor = - std::make_unique(); - std::string output = std::string(); - // Container to note threads that ran - std::unique_ptr> threadIds = - std::make_unique>(); - - threadIds->push_back(GetCurrentThreadId()); - - std::chrono::system_clock::time_point timeNow = - std::chrono::system_clock::now(); - std::chrono::system_clock::time_point timeExecuted; - - // Act - submittableExecutor->Schedule( - [&output, &threadIds, &timeExecuted]() { - timeExecuted = std::chrono::system_clock::now(); - threadIds->push_back(GetCurrentThreadId()); - output.append(RUNNABLE_0_TEXT.c_str()); - }, - absl::Milliseconds(50)); - - SleepEx(100, true); // Yield the thread - - submittableExecutor->Shutdown(); - - auto difference = std::chrono::duration_cast( - timeExecuted - timeNow) - .count(); - - // Assert - // We should've run 1 time on the main thread, and 1 times on the - // workerThread - ASSERT_TRUE(difference >= 50) << "difference was: " << difference; - ASSERT_TRUE(difference < 100) << "difference was: " << difference; - - ASSERT_EQ(threadIds->size(), 2); - // We should still be on the main thread - ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); - // We should've run all runnables on the worker thread - ASSERT_EQ(output, expected); -} - -TEST(ScheduledExecutorTests, CancelSucceeds) { - // Arrange - std::string expected(""); - - std::unique_ptr - submittableExecutor = - std::make_unique(); - std::string output = std::string(); - // Container to note threads that ran - std::unique_ptr> threadIds = - std::make_unique>(); - - threadIds->push_back(GetCurrentThreadId()); - - // Act - auto cancelable = submittableExecutor->Schedule( - [&output, &threadIds]() { - threadIds->push_back(GetCurrentThreadId()); - output.append(RUNNABLE_0_TEXT.c_str()); - }, - absl::Milliseconds(1000)); - - SleepEx(100, true); // Yield the thread - - auto actual = cancelable->Cancel(); - - submittableExecutor->Shutdown(); - - // Assert - ASSERT_TRUE(actual); - ASSERT_EQ(threadIds->size(), 1); - // We should still be on the main thread - ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); - // We should've run all runnables on the worker thread - ASSERT_EQ(output, expected); -} - -TEST(ScheduledExecutorTests, CancelAfterStartedFails) { - // Arrange - std::string expected(RUNNABLE_0_TEXT.c_str()); - - std::unique_ptr - submittableExecutor = - std::make_unique(); - std::string output = std::string(); - // Container to note threads that ran - std::unique_ptr> threadIds = - std::make_unique>(); - - threadIds->push_back(GetCurrentThreadId()); - - // Act - auto cancelable = submittableExecutor->Schedule( - [&output, &threadIds]() { - threadIds->push_back(GetCurrentThreadId()); - output.append(RUNNABLE_0_TEXT.c_str()); - }, - absl::Milliseconds(100)); - - SleepEx(1000, true); // Yield the thread - - auto actual = cancelable->Cancel(); - - submittableExecutor->Shutdown(); - - // Assert - ASSERT_FALSE(actual); - ASSERT_EQ(threadIds->size(), 2); - // We should still be on the main thread - ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); - // We should've run all runnables on the worker thread - ASSERT_EQ(output, expected); -} +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "platform/impl/windows/scheduled_executor.h" + +#include + +#include "platform/impl/windows/test_data.h" + +#include "gtest/gtest.h" + +TEST(ScheduledExecutorTests, ExecuteSucceeds) { + // Arrange + std::string expected(RUNNABLE_0_TEXT.c_str()); + + std::unique_ptr + submittableExecutor = + std::make_unique(); + std::string output = std::string(); + // Container to note threads that ran + std::unique_ptr> threadIds = + std::make_unique>(); + + threadIds->push_back(GetCurrentThreadId()); + + // Act + submittableExecutor->Execute([&output, &threadIds]() { + threadIds->push_back(GetCurrentThreadId()); + output.append(RUNNABLE_0_TEXT.c_str()); + }); + + submittableExecutor->Shutdown(); + + // Assert + // We should've run 1 time on the main thread, and 1 times on the + // workerThread + ASSERT_EQ(threadIds->size(), 2); + // We should still be on the main thread + ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); + // We should've run all runnables on the worker thread + ASSERT_EQ(output, expected); +} + +TEST(ScheduledExecutorTests, ScheduleSucceeds) { + // Arrange + std::string expected(RUNNABLE_0_TEXT.c_str()); + + std::unique_ptr + submittableExecutor = + std::make_unique(); + std::string output = std::string(); + // Container to note threads that ran + std::unique_ptr> threadIds = + std::make_unique>(); + + threadIds->push_back(GetCurrentThreadId()); + + std::chrono::system_clock::time_point timeNow = + std::chrono::system_clock::now(); + std::chrono::system_clock::time_point timeExecuted; + + // Act + submittableExecutor->Schedule( + [&output, &threadIds, &timeExecuted]() { + timeExecuted = std::chrono::system_clock::now(); + threadIds->push_back(GetCurrentThreadId()); + output.append(RUNNABLE_0_TEXT.c_str()); + }, + absl::Milliseconds(50)); + + SleepEx(100, true); // Yield the thread + + submittableExecutor->Shutdown(); + + auto difference = std::chrono::duration_cast( + timeExecuted - timeNow) + .count(); + + // Assert + // We should've run 1 time on the main thread, and 1 times on the + // workerThread + ASSERT_TRUE(difference >= 50) << "difference was: " << difference; + ASSERT_TRUE(difference < 100) << "difference was: " << difference; + + ASSERT_EQ(threadIds->size(), 2); + // We should still be on the main thread + ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); + // We should've run all runnables on the worker thread + ASSERT_EQ(output, expected); +} + +TEST(ScheduledExecutorTests, CancelSucceeds) { + // Arrange + std::string expected(""); + + std::unique_ptr + submittableExecutor = + std::make_unique(); + std::string output = std::string(); + // Container to note threads that ran + std::unique_ptr> threadIds = + std::make_unique>(); + + threadIds->push_back(GetCurrentThreadId()); + + // Act + auto cancelable = submittableExecutor->Schedule( + [&output, &threadIds]() { + threadIds->push_back(GetCurrentThreadId()); + output.append(RUNNABLE_0_TEXT.c_str()); + }, + absl::Milliseconds(1000)); + + SleepEx(100, true); // Yield the thread + + auto actual = cancelable->Cancel(); + + submittableExecutor->Shutdown(); + + // Assert + ASSERT_TRUE(actual); + ASSERT_EQ(threadIds->size(), 1); + // We should still be on the main thread + ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); + // We should've run all runnables on the worker thread + ASSERT_EQ(output, expected); +} + +TEST(ScheduledExecutorTests, CancelAfterStartedFails) { + // Arrange + std::string expected(RUNNABLE_0_TEXT.c_str()); + + std::unique_ptr + submittableExecutor = + std::make_unique(); + std::string output = std::string(); + // Container to note threads that ran + std::unique_ptr> threadIds = + std::make_unique>(); + + threadIds->push_back(GetCurrentThreadId()); + + // Act + auto cancelable = submittableExecutor->Schedule( + [&output, &threadIds]() { + threadIds->push_back(GetCurrentThreadId()); + output.append(RUNNABLE_0_TEXT.c_str()); + }, + absl::Milliseconds(100)); + + SleepEx(1000, true); // Yield the thread + + auto actual = cancelable->Cancel(); + + submittableExecutor->Shutdown(); + + // Assert + ASSERT_FALSE(actual); + ASSERT_EQ(threadIds->size(), 2); + // We should still be on the main thread + ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); + // We should've run all runnables on the worker thread + ASSERT_EQ(output, expected); +} diff --git a/cpp/platform/impl/windows/submittable_executor.cc b/cpp/platform/impl/windows/submittable_executor.cc index 4d857c45..ddba0e5a 100644 --- a/cpp/platform/impl/windows/submittable_executor.cc +++ b/cpp/platform/impl/windows/submittable_executor.cc @@ -1,65 +1,65 @@ -// Copyright 2021 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "platform/impl/windows/submittable_executor.h" - -#include "platform/impl/windows/executor.h" -#include "platform/public/logging.h" - -namespace location { -namespace nearby { -namespace windows { - -SubmittableExecutor::SubmittableExecutor() : SubmittableExecutor(1) {} - -SubmittableExecutor::SubmittableExecutor(int32_t max_concurrancy) - : executor_(std::make_unique(max_concurrancy)), - shut_down_(false) {} - -bool SubmittableExecutor::DoSubmit(Runnable&& wrapped_callable) { - if (!shut_down_) { - executor_->Execute(std::move(wrapped_callable)); - return true; - } - - NEARBY_LOGS(ERROR) << "Error: " << __func__ - << ": Attempt to DoSubmit on a shutdown executor."; - - return false; -} - -// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html#execute-java.lang.Runnable- -void SubmittableExecutor::Execute(Runnable&& runnable) { - if (!shut_down_) { - executor_->Execute(std::move(runnable)); - } else { - NEARBY_LOGS(ERROR) << "Error: " << __func__ - << ": Attempt to Execute on a shutdown executor."; - } -} - -// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#shutdown-- -void SubmittableExecutor::Shutdown() { - if (!shut_down_) { - executor_->Shutdown(); - shut_down_ = true; - } - - NEARBY_LOGS(ERROR) << "Error: " << __func__ - << ": Attempt to Shutdown on a shutdown executor."; -} - -} // namespace windows -} // namespace nearby -} // namespace location +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "platform/impl/windows/submittable_executor.h" + +#include "platform/impl/windows/executor.h" +#include "platform/public/logging.h" + +namespace location { +namespace nearby { +namespace windows { + +SubmittableExecutor::SubmittableExecutor() : SubmittableExecutor(1) {} + +SubmittableExecutor::SubmittableExecutor(int32_t max_concurrancy) + : executor_(std::make_unique(max_concurrancy)), + shut_down_(false) {} + +bool SubmittableExecutor::DoSubmit(Runnable&& wrapped_callable) { + if (!shut_down_) { + executor_->Execute(std::move(wrapped_callable)); + return true; + } + + NEARBY_LOGS(ERROR) << "Error: " << __func__ + << ": Attempt to DoSubmit on a shutdown executor."; + + return false; +} + +// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html#execute-java.lang.Runnable- +void SubmittableExecutor::Execute(Runnable&& runnable) { + if (!shut_down_) { + executor_->Execute(std::move(runnable)); + } else { + NEARBY_LOGS(ERROR) << "Error: " << __func__ + << ": Attempt to Execute on a shutdown executor."; + } +} + +// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#shutdown-- +void SubmittableExecutor::Shutdown() { + if (!shut_down_) { + executor_->Shutdown(); + shut_down_ = true; + } + + NEARBY_LOGS(ERROR) << "Error: " << __func__ + << ": Attempt to Shutdown on a shutdown executor."; +} + +} // namespace windows +} // namespace nearby +} // namespace location diff --git a/cpp/platform/impl/windows/submittable_executor_test.cc b/cpp/platform/impl/windows/submittable_executor_test.cc index 92e34047..779f5731 100644 --- a/cpp/platform/impl/windows/submittable_executor_test.cc +++ b/cpp/platform/impl/windows/submittable_executor_test.cc @@ -1,240 +1,240 @@ -// Copyright 2021 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#include "platform/impl/windows/submittable_executor.h" - -#include - -#include "platform/impl/windows/test_data.h" - -#include "gtest/gtest.h" - -TEST(SubmittableExecutorTests, SingleThreadedExecuteSucceeds) { - // Arrange - std::string expected(RUNNABLE_0_TEXT.c_str()); - - std::unique_ptr - submittableExecutor = - std::make_unique(); - std::string output = std::string(); - // Container to note threads that ran - std::unique_ptr> threadIds = - std::make_unique>(); - - threadIds->push_back(GetCurrentThreadId()); - - // Act - submittableExecutor->Execute([&output, &threadIds]() { - threadIds->push_back(GetCurrentThreadId()); - output.append(RUNNABLE_0_TEXT.c_str()); - }); - - submittableExecutor->Shutdown(); - - // Assert - // We should've run 1 time on the main thread, and 1 times on the - // workerThread - ASSERT_EQ(threadIds->size(), 2); - // We should still be on the main thread - ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); - // We should've run all runnables on the worker thread - ASSERT_EQ(output, expected); -} - -TEST(SubmittableExecutorTests, SingleThreadedExecuteAfterShutdownFails) { - // Arrange - std::string expected(""); - - std::unique_ptr - submittableExecutor = - std::make_unique(); - std::string output = std::string(); - // Container to note threads that ran - std::unique_ptr> threadIds = - std::make_unique>(); - - threadIds->push_back(GetCurrentThreadId()); - - submittableExecutor->Shutdown(); - - // Act - submittableExecutor->Execute([&output, &threadIds]() { - threadIds->push_back(GetCurrentThreadId()); - output.append(RUNNABLE_0_TEXT.c_str()); - }); - - // Assert - // We should've run 1 time on the main thread, and 0 times on the - // workerThread - ASSERT_EQ(threadIds->size(), 1); - // We should still be on the main thread - ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); - // We should've run all runnables on the worker thread - ASSERT_EQ(output, expected); -} - -TEST(SubmittableExecutorTests, SingleThreadedDoSubmitSucceeds) { - // Arrange - std::string expected(RUNNABLE_0_TEXT.c_str()); - - std::unique_ptr - submittableExecutor = - std::make_unique(); - std::string output = std::string(); - // Container to note threads that ran - std::unique_ptr> threadIds = - std::make_unique>(); - - threadIds->push_back(GetCurrentThreadId()); - - // Act - auto result = submittableExecutor->DoSubmit([&output, &threadIds]() { - threadIds->push_back(GetCurrentThreadId()); - output.append(RUNNABLE_0_TEXT.c_str()); - }); - - submittableExecutor->Shutdown(); - - // Assert - // We should've said we were going to run this one - ASSERT_TRUE(result); - // We should've run 1 time on the main thread, and 1 times on the - // workerThread - ASSERT_EQ(threadIds->size(), 2); - // We should still be on the main thread - ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); - // We should've run all runnables on the worker thread - ASSERT_EQ(output, expected); -} - -TEST(SubmittableExecutorTests, - SingleThreadedDoSubmitAfterShutdownReturnsFalse) { - // Arrange - std::string expected(""); - - std::unique_ptr - submittableExecutor = - std::make_unique(); - std::unique_ptr output = std::make_unique(); - // Container to note threads that ran - std::unique_ptr> threadIds = - std::make_unique>(); - - threadIds->push_back(GetCurrentThreadId()); - - submittableExecutor->Shutdown(); - - // Act - auto result = submittableExecutor->DoSubmit([&output, &threadIds]() { - threadIds->push_back(GetCurrentThreadId()); - output->append(RUNNABLE_0_TEXT.c_str()); - }); - - // Assert - // We should've said we were going to run this one - ASSERT_FALSE(result); - // We should've run 1 time on the main thread, and 1 times on the - // workerThread - ASSERT_EQ(threadIds->size(), 1); - // We should still be on the main thread - ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); - // We should've run all runnables on the worker thread - ASSERT_EQ(*output.get(), expected); -} - -TEST(SubmittableExecutorTests, SingleThreadedExecuteMultipleTasksSucceeds) { - // Arrange - std::string expected(RUNNABLE_ALL_TEXT.c_str()); - - std::unique_ptr - submittableExecutor = - std::make_unique(); - std::unique_ptr output = std::make_unique(); - // Container to note threads that ran - std::unique_ptr> threadIds = - std::make_unique>(); - - threadIds->push_back(GetCurrentThreadId()); - - // Act - for (int index = 0; index < 5; index++) { - submittableExecutor->Execute([&output, &threadIds, index]() { - threadIds->push_back(GetCurrentThreadId()); - char buffer[128]; - snprintf(buffer, sizeof(buffer), "%s%d, ", RUNNABLE_TEXT.c_str(), index); - output->append(std::string(buffer)); - }); - } - - submittableExecutor->Shutdown(); - - // Assert - // We should've run 1 time on the main thread, and 5 times on the - // workerThread - ASSERT_EQ(threadIds->size(), 6); - // We should still be on the main thread - ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); - // We should've run all runnables on the worker thread - auto workerThreadId = threadIds->at(1); - for (int index = 1; index < threadIds->size(); index++) { - ASSERT_EQ(threadIds->at(index), workerThreadId); - } - - // We should of run them in the order submitted - ASSERT_EQ(*output.get(), expected); -} - -TEST(SubmittableExecutorTests, SingleThreadedDoSubmitMultipleTasksSucceeds) { - // Arrange - std::string expected(RUNNABLE_ALL_TEXT.c_str()); - - std::unique_ptr - submittableExecutor = - std::make_unique(); - std::unique_ptr output = std::make_unique(); - // Container to note threads that ran - std::unique_ptr> threadIds = - std::make_unique>(); - - threadIds->push_back(GetCurrentThreadId()); - - // Act - bool result = true; - for (int index = 0; index < 5; index++) { - result &= submittableExecutor->DoSubmit([&output, &threadIds, index]() { - threadIds->push_back(GetCurrentThreadId()); - char buffer[128]; - snprintf(buffer, sizeof(buffer), "%s%d, ", RUNNABLE_TEXT.c_str(), index); - output->append(std::string(buffer)); - }); - } - - submittableExecutor->Shutdown(); - - // Assert - // All of these should have submitted - ASSERT_TRUE(result); - // We should've run 1 time on the main thread, and 5 times on the - // workerThread - ASSERT_EQ(threadIds->size(), 6); - // We should still be on the main thread - ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); - // We should've run all runnables on the worker thread - auto workerThreadId = threadIds->at(1); - for (int index = 1; index < threadIds->size(); index++) { - ASSERT_EQ(threadIds->at(index), workerThreadId); - } - - // We should of run them in the order submitted - ASSERT_EQ(*output.get(), expected); -} +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "platform/impl/windows/submittable_executor.h" + +#include + +#include "platform/impl/windows/test_data.h" + +#include "gtest/gtest.h" + +TEST(SubmittableExecutorTests, SingleThreadedExecuteSucceeds) { + // Arrange + std::string expected(RUNNABLE_0_TEXT.c_str()); + + std::unique_ptr + submittableExecutor = + std::make_unique(); + std::string output = std::string(); + // Container to note threads that ran + std::unique_ptr> threadIds = + std::make_unique>(); + + threadIds->push_back(GetCurrentThreadId()); + + // Act + submittableExecutor->Execute([&output, &threadIds]() { + threadIds->push_back(GetCurrentThreadId()); + output.append(RUNNABLE_0_TEXT.c_str()); + }); + + submittableExecutor->Shutdown(); + + // Assert + // We should've run 1 time on the main thread, and 1 times on the + // workerThread + ASSERT_EQ(threadIds->size(), 2); + // We should still be on the main thread + ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); + // We should've run all runnables on the worker thread + ASSERT_EQ(output, expected); +} + +TEST(SubmittableExecutorTests, SingleThreadedExecuteAfterShutdownFails) { + // Arrange + std::string expected(""); + + std::unique_ptr + submittableExecutor = + std::make_unique(); + std::string output = std::string(); + // Container to note threads that ran + std::unique_ptr> threadIds = + std::make_unique>(); + + threadIds->push_back(GetCurrentThreadId()); + + submittableExecutor->Shutdown(); + + // Act + submittableExecutor->Execute([&output, &threadIds]() { + threadIds->push_back(GetCurrentThreadId()); + output.append(RUNNABLE_0_TEXT.c_str()); + }); + + // Assert + // We should've run 1 time on the main thread, and 0 times on the + // workerThread + ASSERT_EQ(threadIds->size(), 1); + // We should still be on the main thread + ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); + // We should've run all runnables on the worker thread + ASSERT_EQ(output, expected); +} + +TEST(SubmittableExecutorTests, SingleThreadedDoSubmitSucceeds) { + // Arrange + std::string expected(RUNNABLE_0_TEXT.c_str()); + + std::unique_ptr + submittableExecutor = + std::make_unique(); + std::string output = std::string(); + // Container to note threads that ran + std::unique_ptr> threadIds = + std::make_unique>(); + + threadIds->push_back(GetCurrentThreadId()); + + // Act + auto result = submittableExecutor->DoSubmit([&output, &threadIds]() { + threadIds->push_back(GetCurrentThreadId()); + output.append(RUNNABLE_0_TEXT.c_str()); + }); + + submittableExecutor->Shutdown(); + + // Assert + // We should've said we were going to run this one + ASSERT_TRUE(result); + // We should've run 1 time on the main thread, and 1 times on the + // workerThread + ASSERT_EQ(threadIds->size(), 2); + // We should still be on the main thread + ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); + // We should've run all runnables on the worker thread + ASSERT_EQ(output, expected); +} + +TEST(SubmittableExecutorTests, + SingleThreadedDoSubmitAfterShutdownReturnsFalse) { + // Arrange + std::string expected(""); + + std::unique_ptr + submittableExecutor = + std::make_unique(); + std::unique_ptr output = std::make_unique(); + // Container to note threads that ran + std::unique_ptr> threadIds = + std::make_unique>(); + + threadIds->push_back(GetCurrentThreadId()); + + submittableExecutor->Shutdown(); + + // Act + auto result = submittableExecutor->DoSubmit([&output, &threadIds]() { + threadIds->push_back(GetCurrentThreadId()); + output->append(RUNNABLE_0_TEXT.c_str()); + }); + + // Assert + // We should've said we were going to run this one + ASSERT_FALSE(result); + // We should've run 1 time on the main thread, and 1 times on the + // workerThread + ASSERT_EQ(threadIds->size(), 1); + // We should still be on the main thread + ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); + // We should've run all runnables on the worker thread + ASSERT_EQ(*output.get(), expected); +} + +TEST(SubmittableExecutorTests, SingleThreadedExecuteMultipleTasksSucceeds) { + // Arrange + std::string expected(RUNNABLE_ALL_TEXT.c_str()); + + std::unique_ptr + submittableExecutor = + std::make_unique(); + std::unique_ptr output = std::make_unique(); + // Container to note threads that ran + std::unique_ptr> threadIds = + std::make_unique>(); + + threadIds->push_back(GetCurrentThreadId()); + + // Act + for (int index = 0; index < 5; index++) { + submittableExecutor->Execute([&output, &threadIds, index]() { + threadIds->push_back(GetCurrentThreadId()); + char buffer[128]; + snprintf(buffer, sizeof(buffer), "%s%d, ", RUNNABLE_TEXT.c_str(), index); + output->append(std::string(buffer)); + }); + } + + submittableExecutor->Shutdown(); + + // Assert + // We should've run 1 time on the main thread, and 5 times on the + // workerThread + ASSERT_EQ(threadIds->size(), 6); + // We should still be on the main thread + ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); + // We should've run all runnables on the worker thread + auto workerThreadId = threadIds->at(1); + for (int index = 1; index < threadIds->size(); index++) { + ASSERT_EQ(threadIds->at(index), workerThreadId); + } + + // We should of run them in the order submitted + ASSERT_EQ(*output.get(), expected); +} + +TEST(SubmittableExecutorTests, SingleThreadedDoSubmitMultipleTasksSucceeds) { + // Arrange + std::string expected(RUNNABLE_ALL_TEXT.c_str()); + + std::unique_ptr + submittableExecutor = + std::make_unique(); + std::unique_ptr output = std::make_unique(); + // Container to note threads that ran + std::unique_ptr> threadIds = + std::make_unique>(); + + threadIds->push_back(GetCurrentThreadId()); + + // Act + bool result = true; + for (int index = 0; index < 5; index++) { + result &= submittableExecutor->DoSubmit([&output, &threadIds, index]() { + threadIds->push_back(GetCurrentThreadId()); + char buffer[128]; + snprintf(buffer, sizeof(buffer), "%s%d, ", RUNNABLE_TEXT.c_str(), index); + output->append(std::string(buffer)); + }); + } + + submittableExecutor->Shutdown(); + + // Assert + // All of these should have submitted + ASSERT_TRUE(result); + // We should've run 1 time on the main thread, and 5 times on the + // workerThread + ASSERT_EQ(threadIds->size(), 6); + // We should still be on the main thread + ASSERT_EQ(GetCurrentThreadId(), threadIds->at(0)); + // We should've run all runnables on the worker thread + auto workerThreadId = threadIds->at(1); + for (int index = 1; index < threadIds->size(); index++) { + ASSERT_EQ(threadIds->at(index), workerThreadId); + } + + // We should of run them in the order submitted + ASSERT_EQ(*output.get(), expected); +} diff --git a/cpp/platform/impl/windows/test_data.h b/cpp/platform/impl/windows/test_data.h index 45780e2a..ce160520 100644 --- a/cpp/platform/impl/windows/test_data.h +++ b/cpp/platform/impl/windows/test_data.h @@ -1,34 +1,34 @@ -// Copyright 2021 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef PLATFORM_IMPL_WINDOWS_TEST_DATA_H_ -#define PLATFORM_IMPL_WINDOWS_TEST_DATA_H_ - -#define INVALID_ARGUMENT_TEXT "max_concurrency" -#define THREADPOOL_MAX_SIZE_TEXT "Thread pool max size exceeded." -#define RUNNABLE_TEXT std::string("runnable ") -#define RUNNABLE_0_TEXT RUNNABLE_TEXT + std::string("0") -#define RUNNABLE_1_TEXT RUNNABLE_TEXT + std::string("1") -#define RUNNABLE_2_TEXT RUNNABLE_TEXT + std::string("2") -#define RUNNABLE_3_TEXT RUNNABLE_TEXT + std::string("3") -#define RUNNABLE_4_TEXT RUNNABLE_TEXT + std::string("4") -#define RUNNABLE_SEPARATOR_TEXT std::string(", ") -#define RUNNABLE_ALL_TEXT \ - (RUNNABLE_0_TEXT + RUNNABLE_SEPARATOR_TEXT + RUNNABLE_1_TEXT + \ - RUNNABLE_SEPARATOR_TEXT + RUNNABLE_2_TEXT + RUNNABLE_SEPARATOR_TEXT + \ - RUNNABLE_3_TEXT + RUNNABLE_SEPARATOR_TEXT + RUNNABLE_4_TEXT + \ - RUNNABLE_SEPARATOR_TEXT) - -#endif // PLATFORM_IMPL_WINDOWS_TEST_DATA_H_ - +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef PLATFORM_IMPL_WINDOWS_TEST_DATA_H_ +#define PLATFORM_IMPL_WINDOWS_TEST_DATA_H_ + +#define INVALID_ARGUMENT_TEXT "max_concurrency" +#define THREADPOOL_MAX_SIZE_TEXT "Thread pool max size exceeded." +#define RUNNABLE_TEXT std::string("runnable ") +#define RUNNABLE_0_TEXT RUNNABLE_TEXT + std::string("0") +#define RUNNABLE_1_TEXT RUNNABLE_TEXT + std::string("1") +#define RUNNABLE_2_TEXT RUNNABLE_TEXT + std::string("2") +#define RUNNABLE_3_TEXT RUNNABLE_TEXT + std::string("3") +#define RUNNABLE_4_TEXT RUNNABLE_TEXT + std::string("4") +#define RUNNABLE_SEPARATOR_TEXT std::string(", ") +#define RUNNABLE_ALL_TEXT \ + (RUNNABLE_0_TEXT + RUNNABLE_SEPARATOR_TEXT + RUNNABLE_1_TEXT + \ + RUNNABLE_SEPARATOR_TEXT + RUNNABLE_2_TEXT + RUNNABLE_SEPARATOR_TEXT + \ + RUNNABLE_3_TEXT + RUNNABLE_SEPARATOR_TEXT + RUNNABLE_4_TEXT + \ + RUNNABLE_SEPARATOR_TEXT) + +#endif // PLATFORM_IMPL_WINDOWS_TEST_DATA_H_ + diff --git a/cpp/platform/impl/windows/test_utils.cc b/cpp/platform/impl/windows/test_utils.cc index 96ad7d42..9bd73b5e 100644 --- a/cpp/platform/impl/windows/test_utils.cc +++ b/cpp/platform/impl/windows/test_utils.cc @@ -1,57 +1,57 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "platform/impl/windows/test_utils.h" - -#include - -#include "absl/strings/str_cat.h" - -namespace test_utils { -std::wstring StringToWideString(const std::string& s) { - int len; - int slength = (int)s.length() + 1; - len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); - wchar_t* buf = new wchar_t[len]; - MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len); - std::wstring r(buf); - delete[] buf; - return r; -} - -std::string GetPayloadPath(location::nearby::PayloadId payload_id) { - PWSTR basePath; - - // Retrieves the full path of a known folder identified by the folder's - // KNOWNFOLDERID. - // https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetknownfolderpath - SHGetKnownFolderPath( - FOLDERID_Downloads, // rfid: A reference to the KNOWNFOLDERID that - // identifies the folder. - 0, // dwFlags: Flags that specify special retrieval options. - NULL, // hToken: An access token that represents a particular user. - &basePath); // ppszPath: When this method returns, contains the address - // of a pointer to a null-terminated Unicode string that - // specifies the path of the known folder. The calling - // process is responsible for freeing this resource once it - // is no longer needed by calling CoTaskMemFree, whether - // SHGetKnownFolderPath succeeds or not. - - char* fullpathUTF8 = new char((wcslen(basePath) + 1) * sizeof(char)); - wcstombs(fullpathUTF8, basePath, (wcslen(basePath) + 1) * sizeof(char)); - std::string fullPath = std::string(fullpathUTF8); - auto retval = absl::StrCat(fullPath += "/", payload_id); - return retval; -} -} // namespace test_utils +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "platform/impl/windows/test_utils.h" + +#include + +#include "absl/strings/str_cat.h" + +namespace test_utils { +std::wstring StringToWideString(const std::string& s) { + int len; + int slength = (int)s.length() + 1; + len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); + wchar_t* buf = new wchar_t[len]; + MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len); + std::wstring r(buf); + delete[] buf; + return r; +} + +std::string GetPayloadPath(location::nearby::PayloadId payload_id) { + PWSTR basePath; + + // Retrieves the full path of a known folder identified by the folder's + // KNOWNFOLDERID. + // https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetknownfolderpath + SHGetKnownFolderPath( + FOLDERID_Downloads, // rfid: A reference to the KNOWNFOLDERID that + // identifies the folder. + 0, // dwFlags: Flags that specify special retrieval options. + NULL, // hToken: An access token that represents a particular user. + &basePath); // ppszPath: When this method returns, contains the address + // of a pointer to a null-terminated Unicode string that + // specifies the path of the known folder. The calling + // process is responsible for freeing this resource once it + // is no longer needed by calling CoTaskMemFree, whether + // SHGetKnownFolderPath succeeds or not. + + char* fullpathUTF8 = new char((wcslen(basePath) + 1) * sizeof(char)); + wcstombs(fullpathUTF8, basePath, (wcslen(basePath) + 1) * sizeof(char)); + std::string fullPath = std::string(fullpathUTF8); + auto retval = absl::StrCat(fullPath += "/", payload_id); + return retval; +} +} // namespace test_utils diff --git a/cpp/platform/impl/windows/test_utils.h b/cpp/platform/impl/windows/test_utils.h index d8b8c32f..ef95b1d8 100644 --- a/cpp/platform/impl/windows/test_utils.h +++ b/cpp/platform/impl/windows/test_utils.h @@ -1,47 +1,47 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef PLATFORM_IMPL_WINDOWS_TEST_UTILS_H_ -#define PLATFORM_IMPL_WINDOWS_TEST_UTILS_H_ - -#include -#include - -#include -#include - -#include "platform/base/payload_id.h" - -#define TEST_BUFFER_SIZE 256 -#define TEST_PAYLOAD_ID 64l -#define TEST_STRING \ - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas " \ - "eleifend nisl at magna maximus, id finibus mauris ultrices. Mauris " \ - "interdum efficitur turpis eget auctor. Nullam commodo metus et ante " \ - "bibendum molestie. Donec iaculis ante nec diam rutrum egestas. Proin " \ - "maximus metus luctus rutrum congue. Integer et eros nunc. Etiam purus " \ - "neque, tincidunt eu elementum in, pharetra sit amet magna. Quisque " \ - "consequat aliquam aliquam. Vestibulum ante ipsum primis in faucibus orci " \ - "luctus et ultrices posuere cubilia curae; Maecenas a semper eros, a " \ - "auctor mi. In luctus diam sem, eu pretium nisi porttitor ac. Sed cursus, " \ - "arcu in bibendum feugiat, leo erat finibus massa, ut tincidunt magna nunc " \ - "eu tellus. Cras feugiat ornare vestibulum. Nullam at ipsum vestibulum " \ - "sapien luctus dictum ac vel ligula." - -namespace test_utils { -std::wstring StringToWideString(const std::string& s); -std::string GetPayloadPath(location::nearby::PayloadId payload_id); -} // namespace test_utils - -#endif // PLATFORM_IMPL_WINDOWS_TEST_UTILS_H_ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef PLATFORM_IMPL_WINDOWS_TEST_UTILS_H_ +#define PLATFORM_IMPL_WINDOWS_TEST_UTILS_H_ + +#include +#include + +#include +#include + +#include "platform/base/payload_id.h" + +#define TEST_BUFFER_SIZE 256 +#define TEST_PAYLOAD_ID 64l +#define TEST_STRING \ + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas " \ + "eleifend nisl at magna maximus, id finibus mauris ultrices. Mauris " \ + "interdum efficitur turpis eget auctor. Nullam commodo metus et ante " \ + "bibendum molestie. Donec iaculis ante nec diam rutrum egestas. Proin " \ + "maximus metus luctus rutrum congue. Integer et eros nunc. Etiam purus " \ + "neque, tincidunt eu elementum in, pharetra sit amet magna. Quisque " \ + "consequat aliquam aliquam. Vestibulum ante ipsum primis in faucibus orci " \ + "luctus et ultrices posuere cubilia curae; Maecenas a semper eros, a " \ + "auctor mi. In luctus diam sem, eu pretium nisi porttitor ac. Sed cursus, " \ + "arcu in bibendum feugiat, leo erat finibus massa, ut tincidunt magna nunc " \ + "eu tellus. Cras feugiat ornare vestibulum. Nullam at ipsum vestibulum " \ + "sapien luctus dictum ac vel ligula." + +namespace test_utils { +std::wstring StringToWideString(const std::string& s); +std::string GetPayloadPath(location::nearby::PayloadId payload_id); +} // namespace test_utils + +#endif // PLATFORM_IMPL_WINDOWS_TEST_UTILS_H_ diff --git a/cpp/platform/impl/windows/thread_pool.cc b/cpp/platform/impl/windows/thread_pool.cc index c60a8ced..963188cf 100644 --- a/cpp/platform/impl/windows/thread_pool.cc +++ b/cpp/platform/impl/windows/thread_pool.cc @@ -1,531 +1,531 @@ -// Copyright 2021 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "platform/impl/windows/thread_pool.h" - -#include - -#include -#include - -#include "platform/impl/windows/runner.h" -#include "platform/public/logging.h" - -namespace location { -namespace nearby { -namespace windows { - -#define POOL_NAME_BUFFER_SIZE 64 -#define EVENT_NAME_BUFFER_SIZE 64 - -__declspec(align(8)) volatile long ThreadPool::instance_ = // NOLINT - 0; // NOLINT because the Windows function takes a volatile long - -DWORD WINAPI ThreadPool::_ThreadProc(LPVOID pParam) { - DWORD wait; - ThreadPool* pool; - DWORD threadId = GetCurrentThreadId(); - HANDLE waits[2]; - std::unique_ptr runner; - - _ASSERT(pParam != NULL); - if (NULL == pParam) { - NEARBY_LOGS(ERROR) << __func__ << ": pParam must not be null."; - return -1; - } - - NEARBY_LOGS(VERBOSE) << "Info: " << __func__ - << ": Starting thread id: " << threadId; - - pool = static_cast(pParam); - waits[0] = pool->GetWaitHandle(threadId); - waits[1] = pool->GetShutdownHandle(); - -loop_here: - wait = WaitForMultipleObjects(2, waits, FALSE, INFINITE); - if (wait == 1) { - if (pool->CheckThreadStop()) { - if (pool->GetWorkingThreadCount() < 1) { - NEARBY_LOGS(VERBOSE) << "Info: " << __func__ - << ": Pool is being destroyed, and working thread " - "count is 0, thread exiting."; - - return 0; - } - } - } - - // a new function was added, go and get it - runner = nullptr; - - NEARBY_LOGS(VERBOSE) << "Info: " << __func__ << ": On thread id: " << threadId - << ", checking for work."; - - if (pool->GetThreadProc(threadId, std::move(runner))) { - pool->BusyNotify(threadId); - runner->Run(); - pool->FinishNotify(threadId); // tell the pool, i am now free - } - - goto loop_here; - - NEARBY_LOGS(VERBOSE) << "Info: " << __func__ << ": Thread shutdown occurred."; - - return 0; -} - -ThreadPool::ThreadPool(int nPoolSize, bool bCreateNow) - : function_list_(std::make_unique()), - thread_map_(std::make_unique()), - thread_handles_(nullptr), - wait_for_threads_to_die_ms_(500), - notify_shutdown_(nullptr) { - // The MAXIMUM_WAIT_OBJECTS is the limiting factor, currently - // windows has a max of 64. This means we can only wait on up - // to 64 threads, anything more gives undesirable results. - if (nPoolSize > 63) { - NEARBY_LOGS(ERROR) << __func__ << ": Thread pool max size exceeded."; - throw ThreadPoolException("Thread pool max size exceeded."); - } - - pool_state_ = State::Destroyed; - pool_size_ = nPoolSize; - - InitializeCriticalSection(&critical_section_); - - if (bCreateNow) { - if (!Create()) { - NEARBY_LOGS(ERROR) << __func__ << ": Thread pool creation failed."; - throw ThreadPoolException("Thread pool creation failed."); - } - } -} - -bool ThreadPool::Create() { - if (pool_state_ != State::Destroyed) { - // To create a new pool, destroy the existing one first - NEARBY_LOGS(ERROR) << __func__ - << ": Attempt to create a new thread pool before " - "destroying the old one."; - return false; - } - - char buffer[POOL_NAME_BUFFER_SIZE]; - snprintf(buffer, POOL_NAME_BUFFER_SIZE, "Pool%d", - (uint32_t)(InterlockedIncrement( - &ThreadPool::instance_))); // InterlockedIncrement done here - // since there's no access to the - // instance_ var except through the - // interlocked functions - pool_name_ = std::string(buffer); - - // create the event which will signal the threads to stop - std::string eventName; - notify_shutdown_ = CreateEvent(NULL, TRUE, FALSE, NULL); - _ASSERT(notify_shutdown_ != NULL); - if (!notify_shutdown_) { - NEARBY_LOGS(ERROR) << "Error: " << __func__ - << ": Failed to create thread shut down event."; - - return false; - } - - SYSTEM_INFO sysinfo; - GetSystemInfo(&sysinfo); - int numCPU = sysinfo.dwNumberOfProcessors; - - int threadsToCreate = 0; - - // We are going to initially allocate the first n - // threads based on the number of logical cores - if (pool_size_ > numCPU) { - threadsToCreate = STARTUP_THREAD_COUNT; - } else { - threadsToCreate = pool_size_; - } - - thread_handles_ = new HANDLE[pool_size_]; - - // create the threads - for (int index = 0; index < threadsToCreate; index++) { - CreateThreadPoolThread(&thread_handles_[index]); - } - - pool_state_ = State::Ready; - return true; -} - -ThreadPool::~ThreadPool() { - Destroy(); - ReleaseMemory(); - DeleteCriticalSection(&critical_section_); -} - -DWORD ThreadPool::CreateThreadPoolThread(HANDLE* handles) { - HANDLE thread; - DWORD threadId; - std::unique_ptr threadData = std::make_unique(); - - char buffer[EVENT_NAME_BUFFER_SIZE]; - - snprintf(buffer, EVENT_NAME_BUFFER_SIZE, "PID:%ld IID:%d TDX:%d", - GetCurrentProcessId(), - (uint32_t)(InterlockedAdd(&ThreadPool::instance_, 0)), - (int)thread_map_->size()); - - thread = CreateThread(NULL, 0, ThreadPool::_ThreadProc, this, - CREATE_SUSPENDED, &threadId); - - _ASSERT(NULL != thread); - - if (NULL == thread) { - NEARBY_LOGS(ERROR) << "Error: " << __func__ << ": Failed to create thread."; - return NULL; - } - - if (thread) { - // add the entry to the map of threads - EnterCriticalSection(&critical_section_); - - threadData->free = true; - threadData->wait_handle = CreateEventA(NULL, TRUE, FALSE, buffer); - - threadData->thread_handle = thread; - threadData->thread_id = threadId; - - thread_map_->insert(ThreadMap::value_type(threadId, std::move(threadData))); - *handles = thread; - LeaveCriticalSection(&critical_section_); - - ResumeThread(thread); - - NEARBY_LOGS(VERBOSE) << "Info: " << __func__ - << ": Thread created, handle: " << thread - << ", id: " << threadId; - - return threadId; - } else { - NEARBY_LOGS(ERROR) << "Error: " << __func__ << ": Failed to create thread."; - return NULL; - } -} - -void ThreadPool::ReleaseMemory() { - // empty all collections - EnterCriticalSection(&critical_section_); - - NEARBY_LOGS(VERBOSE) << "Info: " << __func__ - << ": Clearing the function list."; - - function_list_->clear(); - - NEARBY_LOGS(VERBOSE) << "Info: " << __func__ << ": Clearing the thread map."; - - thread_map_->clear(); - - LeaveCriticalSection(&critical_section_); -} - -void ThreadPool::Destroy() { - if (pool_state_ == State::Destroying || pool_state_ == State::Destroyed) - return; - - NEARBY_LOGS(VERBOSE) << "Info: " << __func__ << ": Destroying thread pool."; - - pool_state_ = State::Destroying; - - bool notDone = true; - - EnterCriticalSection(&critical_section_); - - ThreadMap::iterator iter = thread_map_->begin(); - int index = 0; - - // Build an array of handles - while (iter != thread_map_->end()) { - thread_handles_[index] = iter->second->thread_handle; - index++; - iter++; - } - - LeaveCriticalSection(&critical_section_); - - // tell all threads to shutdown. - _ASSERT(NULL != notify_shutdown_); - SetEvent(GetShutdownHandle()); - - NEARBY_LOGS(VERBOSE) << "Info: " << __func__ - << ": Setting waits for the threads to exit."; - - if (pool_size_ == 1) { - // Waits until the specified object is in the signaled state or the time-out - // interval elapses. - // https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitforsingleobject - auto wait = WaitForSingleObject( - thread_handles_[0], // A handle to the object - INFINITE // The time-out interval, in milliseconds. - ); - } else { - auto wait = - // Waits until one or all of the specified objects are in the signaled - // state or the time-out interval elapses. - // https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitformultipleobjects - WaitForMultipleObjects( - index, // The number of object handles in the array. - thread_handles_, // An array of object handles. - true, // If this parameter is TRUE, the function returns when the - // state of all objects in the handles array are signaled. - INFINITE // The time-out interval, in milliseconds. - ); - } - - NEARBY_LOGS(VERBOSE) << "Info: " << __func__ << ": All threads have exited."; - - delete[] thread_handles_; - - // close the shutdown event - CloseHandle(notify_shutdown_); - notify_shutdown_ = NULL; - - EnterCriticalSection(&critical_section_); - - ThreadMap::iterator threadMapIterator; - - // walk through the events and threads and close them all - for (threadMapIterator = thread_map_->begin(); - threadMapIterator != thread_map_->end(); threadMapIterator++) { - NEARBY_LOGS(VERBOSE) << "Info: " << __func__ << ": Closing thread handle: " - << threadMapIterator->second->thread_handle - << " thread id: " - << threadMapIterator->second->thread_id - << " wait_handle: " - << threadMapIterator->second->wait_handle; - - CloseHandle(threadMapIterator->second->wait_handle); - CloseHandle(threadMapIterator->second->thread_handle); - } - - LeaveCriticalSection(&critical_section_); - - NEARBY_LOGS(VERBOSE) << "Info: " << __func__ - << ": Sending the shutdown event."; - - ReleaseMemory(); // free any remaining UserPoolData objects - - InterlockedDecrement(&ThreadPool::instance_); - - pool_state_ = State::Destroyed; -} - -int ThreadPool::GetPoolSize() { return pool_size_; } - -void ThreadPool::SetPoolSize(int nSize) { - _ASSERT(nSize > 0); - - if (nSize <= 0) { - NEARBY_LOGS(ERROR) - << __func__ << ": 0 or negative value is not a valid thread pool size."; - return; - } - - pool_size_ = nSize; -} - -HANDLE ThreadPool::GetShutdownHandle() { return notify_shutdown_; } - -bool ThreadPool::GetThreadProc(DWORD threadId, - std::unique_ptr&& runner) { - // get the first function info in the function list - FunctionList::iterator functionListIterator; - bool haveAnotherRunner = false; - - EnterCriticalSection(&critical_section_); - - functionListIterator = function_list_->begin(); - - if (functionListIterator != function_list_->end()) { - runner = std::move(*functionListIterator); - - NEARBY_LOGS(VERBOSE) << "Info: " << __func__ - << ": popping runner from the front."; - - function_list_->pop_front(); // remove the function from the list - - haveAnotherRunner = true; - } else { - thread_map_->at(threadId)->free = true; - ResetEvent(thread_map_->at(threadId)->wait_handle); - } - - LeaveCriticalSection(&critical_section_); - - return haveAnotherRunner; -} - -void ThreadPool::FinishNotify(DWORD threadId) { - ThreadMap::iterator threadMapIterator; - - EnterCriticalSection(&critical_section_); - - threadMapIterator = thread_map_->find(threadId); - - if (threadMapIterator == thread_map_->end()) // if search found no elements - { - _ASSERT(!"No matching thread found."); - NEARBY_LOGS(ERROR) << __func__ << ": No matching thread found."; - } else { - thread_map_->at(threadId)->free = true; - - if (!function_list_->empty()) { - // there are some more functions that need servicing, lets do that. - // By not doing anything here we are letting the thread go back and - // check the function list and pick up a function and execute it. - thread_map_->at(threadId)->free = false; - } else { - ResetEvent(thread_map_->at(threadId)->wait_handle); - } - } - - LeaveCriticalSection(&critical_section_); -} - -void ThreadPool::BusyNotify(DWORD threadId) { - ThreadMap::iterator iter; - - EnterCriticalSection(&critical_section_); - - iter = thread_map_->find(threadId); - - if (iter == thread_map_->end()) // if search found no elements - { - _ASSERT(!"No matching thread found."); - } else { - thread_map_->at(threadId)->free = false; - } - - LeaveCriticalSection(&critical_section_); -} - -bool ThreadPool::Run(std::unique_ptr runner) { - if (pool_state_ == State::Destroying || pool_state_ == State::Destroyed) - return false; - - _ASSERT(runner != NULL); - - AddRunner(std::move(runner)); - - // See if any threads are free - ThreadMap::iterator iterator; - std::unique_ptr threadData; - - bool freeThreadFound = false; - - EnterCriticalSection(&critical_section_); - - for (iterator = thread_map_->begin(); iterator != thread_map_->end(); - iterator++) { - if (iterator->second->free) { - // here is a free thread, put it to work - iterator->second->free = false; - SetEvent(iterator->second->wait_handle); - // this thread will now call GetThreadProc() and pick up the next - // function in the list. - freeThreadFound = true; - break; - } - } - - if (!freeThreadFound && thread_map_->size() < pool_size_) { - // We haven't used up all of our threads, go ahead and spin up another one - DWORD threadId = - CreateThreadPoolThread(&thread_handles_[thread_map_->size()]); - thread_map_->at(threadId)->free = false; - SetEvent(thread_map_->at(threadId)->wait_handle); - } - - LeaveCriticalSection(&critical_section_); - - return true; -} - -void ThreadPool::AddRunner(std::unique_ptr runner) { - // add it to the list - runner->thread_pool_ = this; - - NEARBY_LOGS(VERBOSE) << "Info: " << __func__ - << ": pushing new runner to the back."; - - EnterCriticalSection(&critical_section_); - - function_list_->push_back(std::move(runner)); - - LeaveCriticalSection(&critical_section_); -} - -HANDLE ThreadPool::GetWaitHandle(DWORD dwThreadId) { - HANDLE hWait = NULL; - ThreadMap::iterator iter; - - EnterCriticalSection(&critical_section_); - - iter = thread_map_->find(dwThreadId); - - if (iter != thread_map_->end()) // if search found no elements - { - hWait = thread_map_->at(dwThreadId)->wait_handle; - } - - LeaveCriticalSection(&critical_section_); - - return hWait; -} - -bool ThreadPool::CheckThreadStop() { - EnterCriticalSection(&critical_section_); - - bool bRet = - (pool_state_ == State::Destroying || pool_state_ == State::Destroyed); - - LeaveCriticalSection(&critical_section_); - - return bRet; -} - -int ThreadPool::GetWorkingThreadCount() { - ThreadMap::iterator iter; - - int nCount = 0; - - EnterCriticalSection(&critical_section_); - - for (iter = thread_map_->begin(); iter != thread_map_->end(); iter++) { - if (function_list_->empty()) { - iter->second->free = true; - } - - if (!iter->second->free) { - nCount++; - } - } - - LeaveCriticalSection(&critical_section_); - - return nCount; -} - -State ThreadPool::GetState() { return pool_state_; } - -} // namespace windows -} // namespace nearby -} // namespace location +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "platform/impl/windows/thread_pool.h" + +#include + +#include +#include + +#include "platform/impl/windows/runner.h" +#include "platform/public/logging.h" + +namespace location { +namespace nearby { +namespace windows { + +#define POOL_NAME_BUFFER_SIZE 64 +#define EVENT_NAME_BUFFER_SIZE 64 + +__declspec(align(8)) volatile long ThreadPool::instance_ = // NOLINT + 0; // NOLINT because the Windows function takes a volatile long + +DWORD WINAPI ThreadPool::_ThreadProc(LPVOID pParam) { + DWORD wait; + ThreadPool* pool; + DWORD threadId = GetCurrentThreadId(); + HANDLE waits[2]; + std::unique_ptr runner; + + _ASSERT(pParam != NULL); + if (NULL == pParam) { + NEARBY_LOGS(ERROR) << __func__ << ": pParam must not be null."; + return -1; + } + + NEARBY_LOGS(VERBOSE) << "Info: " << __func__ + << ": Starting thread id: " << threadId; + + pool = static_cast(pParam); + waits[0] = pool->GetWaitHandle(threadId); + waits[1] = pool->GetShutdownHandle(); + +loop_here: + wait = WaitForMultipleObjects(2, waits, FALSE, INFINITE); + if (wait == 1) { + if (pool->CheckThreadStop()) { + if (pool->GetWorkingThreadCount() < 1) { + NEARBY_LOGS(VERBOSE) << "Info: " << __func__ + << ": Pool is being destroyed, and working thread " + "count is 0, thread exiting."; + + return 0; + } + } + } + + // a new function was added, go and get it + runner = nullptr; + + NEARBY_LOGS(VERBOSE) << "Info: " << __func__ << ": On thread id: " << threadId + << ", checking for work."; + + if (pool->GetThreadProc(threadId, std::move(runner))) { + pool->BusyNotify(threadId); + runner->Run(); + pool->FinishNotify(threadId); // tell the pool, i am now free + } + + goto loop_here; + + NEARBY_LOGS(VERBOSE) << "Info: " << __func__ << ": Thread shutdown occurred."; + + return 0; +} + +ThreadPool::ThreadPool(int nPoolSize, bool bCreateNow) + : function_list_(std::make_unique()), + thread_map_(std::make_unique()), + thread_handles_(nullptr), + wait_for_threads_to_die_ms_(500), + notify_shutdown_(nullptr) { + // The MAXIMUM_WAIT_OBJECTS is the limiting factor, currently + // windows has a max of 64. This means we can only wait on up + // to 64 threads, anything more gives undesirable results. + if (nPoolSize > 63) { + NEARBY_LOGS(ERROR) << __func__ << ": Thread pool max size exceeded."; + throw ThreadPoolException("Thread pool max size exceeded."); + } + + pool_state_ = State::Destroyed; + pool_size_ = nPoolSize; + + InitializeCriticalSection(&critical_section_); + + if (bCreateNow) { + if (!Create()) { + NEARBY_LOGS(ERROR) << __func__ << ": Thread pool creation failed."; + throw ThreadPoolException("Thread pool creation failed."); + } + } +} + +bool ThreadPool::Create() { + if (pool_state_ != State::Destroyed) { + // To create a new pool, destroy the existing one first + NEARBY_LOGS(ERROR) << __func__ + << ": Attempt to create a new thread pool before " + "destroying the old one."; + return false; + } + + char buffer[POOL_NAME_BUFFER_SIZE]; + snprintf(buffer, POOL_NAME_BUFFER_SIZE, "Pool%d", + (uint32_t)(InterlockedIncrement( + &ThreadPool::instance_))); // InterlockedIncrement done here + // since there's no access to the + // instance_ var except through the + // interlocked functions + pool_name_ = std::string(buffer); + + // create the event which will signal the threads to stop + std::string eventName; + notify_shutdown_ = CreateEvent(NULL, TRUE, FALSE, NULL); + _ASSERT(notify_shutdown_ != NULL); + if (!notify_shutdown_) { + NEARBY_LOGS(ERROR) << "Error: " << __func__ + << ": Failed to create thread shut down event."; + + return false; + } + + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + int numCPU = sysinfo.dwNumberOfProcessors; + + int threadsToCreate = 0; + + // We are going to initially allocate the first n + // threads based on the number of logical cores + if (pool_size_ > numCPU) { + threadsToCreate = STARTUP_THREAD_COUNT; + } else { + threadsToCreate = pool_size_; + } + + thread_handles_ = new HANDLE[pool_size_]; + + // create the threads + for (int index = 0; index < threadsToCreate; index++) { + CreateThreadPoolThread(&thread_handles_[index]); + } + + pool_state_ = State::Ready; + return true; +} + +ThreadPool::~ThreadPool() { + Destroy(); + ReleaseMemory(); + DeleteCriticalSection(&critical_section_); +} + +DWORD ThreadPool::CreateThreadPoolThread(HANDLE* handles) { + HANDLE thread; + DWORD threadId; + std::unique_ptr threadData = std::make_unique(); + + char buffer[EVENT_NAME_BUFFER_SIZE]; + + snprintf(buffer, EVENT_NAME_BUFFER_SIZE, "PID:%ld IID:%d TDX:%d", + GetCurrentProcessId(), + (uint32_t)(InterlockedAdd(&ThreadPool::instance_, 0)), + (int)thread_map_->size()); + + thread = CreateThread(NULL, 0, ThreadPool::_ThreadProc, this, + CREATE_SUSPENDED, &threadId); + + _ASSERT(NULL != thread); + + if (NULL == thread) { + NEARBY_LOGS(ERROR) << "Error: " << __func__ << ": Failed to create thread."; + return NULL; + } + + if (thread) { + // add the entry to the map of threads + EnterCriticalSection(&critical_section_); + + threadData->free = true; + threadData->wait_handle = CreateEventA(NULL, TRUE, FALSE, buffer); + + threadData->thread_handle = thread; + threadData->thread_id = threadId; + + thread_map_->insert(ThreadMap::value_type(threadId, std::move(threadData))); + *handles = thread; + LeaveCriticalSection(&critical_section_); + + ResumeThread(thread); + + NEARBY_LOGS(VERBOSE) << "Info: " << __func__ + << ": Thread created, handle: " << thread + << ", id: " << threadId; + + return threadId; + } else { + NEARBY_LOGS(ERROR) << "Error: " << __func__ << ": Failed to create thread."; + return NULL; + } +} + +void ThreadPool::ReleaseMemory() { + // empty all collections + EnterCriticalSection(&critical_section_); + + NEARBY_LOGS(VERBOSE) << "Info: " << __func__ + << ": Clearing the function list."; + + function_list_->clear(); + + NEARBY_LOGS(VERBOSE) << "Info: " << __func__ << ": Clearing the thread map."; + + thread_map_->clear(); + + LeaveCriticalSection(&critical_section_); +} + +void ThreadPool::Destroy() { + if (pool_state_ == State::Destroying || pool_state_ == State::Destroyed) + return; + + NEARBY_LOGS(VERBOSE) << "Info: " << __func__ << ": Destroying thread pool."; + + pool_state_ = State::Destroying; + + bool notDone = true; + + EnterCriticalSection(&critical_section_); + + ThreadMap::iterator iter = thread_map_->begin(); + int index = 0; + + // Build an array of handles + while (iter != thread_map_->end()) { + thread_handles_[index] = iter->second->thread_handle; + index++; + iter++; + } + + LeaveCriticalSection(&critical_section_); + + // tell all threads to shutdown. + _ASSERT(NULL != notify_shutdown_); + SetEvent(GetShutdownHandle()); + + NEARBY_LOGS(VERBOSE) << "Info: " << __func__ + << ": Setting waits for the threads to exit."; + + if (pool_size_ == 1) { + // Waits until the specified object is in the signaled state or the time-out + // interval elapses. + // https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitforsingleobject + auto wait = WaitForSingleObject( + thread_handles_[0], // A handle to the object + INFINITE // The time-out interval, in milliseconds. + ); + } else { + auto wait = + // Waits until one or all of the specified objects are in the signaled + // state or the time-out interval elapses. + // https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitformultipleobjects + WaitForMultipleObjects( + index, // The number of object handles in the array. + thread_handles_, // An array of object handles. + true, // If this parameter is TRUE, the function returns when the + // state of all objects in the handles array are signaled. + INFINITE // The time-out interval, in milliseconds. + ); + } + + NEARBY_LOGS(VERBOSE) << "Info: " << __func__ << ": All threads have exited."; + + delete[] thread_handles_; + + // close the shutdown event + CloseHandle(notify_shutdown_); + notify_shutdown_ = NULL; + + EnterCriticalSection(&critical_section_); + + ThreadMap::iterator threadMapIterator; + + // walk through the events and threads and close them all + for (threadMapIterator = thread_map_->begin(); + threadMapIterator != thread_map_->end(); threadMapIterator++) { + NEARBY_LOGS(VERBOSE) << "Info: " << __func__ << ": Closing thread handle: " + << threadMapIterator->second->thread_handle + << " thread id: " + << threadMapIterator->second->thread_id + << " wait_handle: " + << threadMapIterator->second->wait_handle; + + CloseHandle(threadMapIterator->second->wait_handle); + CloseHandle(threadMapIterator->second->thread_handle); + } + + LeaveCriticalSection(&critical_section_); + + NEARBY_LOGS(VERBOSE) << "Info: " << __func__ + << ": Sending the shutdown event."; + + ReleaseMemory(); // free any remaining UserPoolData objects + + InterlockedDecrement(&ThreadPool::instance_); + + pool_state_ = State::Destroyed; +} + +int ThreadPool::GetPoolSize() { return pool_size_; } + +void ThreadPool::SetPoolSize(int nSize) { + _ASSERT(nSize > 0); + + if (nSize <= 0) { + NEARBY_LOGS(ERROR) + << __func__ << ": 0 or negative value is not a valid thread pool size."; + return; + } + + pool_size_ = nSize; +} + +HANDLE ThreadPool::GetShutdownHandle() { return notify_shutdown_; } + +bool ThreadPool::GetThreadProc(DWORD threadId, + std::unique_ptr&& runner) { + // get the first function info in the function list + FunctionList::iterator functionListIterator; + bool haveAnotherRunner = false; + + EnterCriticalSection(&critical_section_); + + functionListIterator = function_list_->begin(); + + if (functionListIterator != function_list_->end()) { + runner = std::move(*functionListIterator); + + NEARBY_LOGS(VERBOSE) << "Info: " << __func__ + << ": popping runner from the front."; + + function_list_->pop_front(); // remove the function from the list + + haveAnotherRunner = true; + } else { + thread_map_->at(threadId)->free = true; + ResetEvent(thread_map_->at(threadId)->wait_handle); + } + + LeaveCriticalSection(&critical_section_); + + return haveAnotherRunner; +} + +void ThreadPool::FinishNotify(DWORD threadId) { + ThreadMap::iterator threadMapIterator; + + EnterCriticalSection(&critical_section_); + + threadMapIterator = thread_map_->find(threadId); + + if (threadMapIterator == thread_map_->end()) // if search found no elements + { + _ASSERT(!"No matching thread found."); + NEARBY_LOGS(ERROR) << __func__ << ": No matching thread found."; + } else { + thread_map_->at(threadId)->free = true; + + if (!function_list_->empty()) { + // there are some more functions that need servicing, lets do that. + // By not doing anything here we are letting the thread go back and + // check the function list and pick up a function and execute it. + thread_map_->at(threadId)->free = false; + } else { + ResetEvent(thread_map_->at(threadId)->wait_handle); + } + } + + LeaveCriticalSection(&critical_section_); +} + +void ThreadPool::BusyNotify(DWORD threadId) { + ThreadMap::iterator iter; + + EnterCriticalSection(&critical_section_); + + iter = thread_map_->find(threadId); + + if (iter == thread_map_->end()) // if search found no elements + { + _ASSERT(!"No matching thread found."); + } else { + thread_map_->at(threadId)->free = false; + } + + LeaveCriticalSection(&critical_section_); +} + +bool ThreadPool::Run(std::unique_ptr runner) { + if (pool_state_ == State::Destroying || pool_state_ == State::Destroyed) + return false; + + _ASSERT(runner != NULL); + + AddRunner(std::move(runner)); + + // See if any threads are free + ThreadMap::iterator iterator; + std::unique_ptr threadData; + + bool freeThreadFound = false; + + EnterCriticalSection(&critical_section_); + + for (iterator = thread_map_->begin(); iterator != thread_map_->end(); + iterator++) { + if (iterator->second->free) { + // here is a free thread, put it to work + iterator->second->free = false; + SetEvent(iterator->second->wait_handle); + // this thread will now call GetThreadProc() and pick up the next + // function in the list. + freeThreadFound = true; + break; + } + } + + if (!freeThreadFound && thread_map_->size() < pool_size_) { + // We haven't used up all of our threads, go ahead and spin up another one + DWORD threadId = + CreateThreadPoolThread(&thread_handles_[thread_map_->size()]); + thread_map_->at(threadId)->free = false; + SetEvent(thread_map_->at(threadId)->wait_handle); + } + + LeaveCriticalSection(&critical_section_); + + return true; +} + +void ThreadPool::AddRunner(std::unique_ptr runner) { + // add it to the list + runner->thread_pool_ = this; + + NEARBY_LOGS(VERBOSE) << "Info: " << __func__ + << ": pushing new runner to the back."; + + EnterCriticalSection(&critical_section_); + + function_list_->push_back(std::move(runner)); + + LeaveCriticalSection(&critical_section_); +} + +HANDLE ThreadPool::GetWaitHandle(DWORD dwThreadId) { + HANDLE hWait = NULL; + ThreadMap::iterator iter; + + EnterCriticalSection(&critical_section_); + + iter = thread_map_->find(dwThreadId); + + if (iter != thread_map_->end()) // if search found no elements + { + hWait = thread_map_->at(dwThreadId)->wait_handle; + } + + LeaveCriticalSection(&critical_section_); + + return hWait; +} + +bool ThreadPool::CheckThreadStop() { + EnterCriticalSection(&critical_section_); + + bool bRet = + (pool_state_ == State::Destroying || pool_state_ == State::Destroyed); + + LeaveCriticalSection(&critical_section_); + + return bRet; +} + +int ThreadPool::GetWorkingThreadCount() { + ThreadMap::iterator iter; + + int nCount = 0; + + EnterCriticalSection(&critical_section_); + + for (iter = thread_map_->begin(); iter != thread_map_->end(); iter++) { + if (function_list_->empty()) { + iter->second->free = true; + } + + if (!iter->second->free) { + nCount++; + } + } + + LeaveCriticalSection(&critical_section_); + + return nCount; +} + +State ThreadPool::GetState() { return pool_state_; } + +} // namespace windows +} // namespace nearby +} // namespace location diff --git a/cpp/platform/impl/windows/thread_pool.h b/cpp/platform/impl/windows/thread_pool.h index e7fcb4fc..d40efc0b 100644 --- a/cpp/platform/impl/windows/thread_pool.h +++ b/cpp/platform/impl/windows/thread_pool.h @@ -1,106 +1,106 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#ifndef PLATFORM_IMPL_WINDOWS_THREAD_POOL_H_ -#define PLATFORM_IMPL_WINDOWS_THREAD_POOL_H_ -#include - -#include -#include -#include -#include - -#include "platform/impl/windows/runner.h" -namespace location { -namespace nearby { -namespace windows { - -// This is the number of threads that will be started initially if the pool -// size is greater than 4, or if the pool size is greater than the number -// of cores present, including virtual cores -#define STARTUP_THREAD_COUNT 4 - -class ThreadPoolException : public std::runtime_error { - public: - ThreadPoolException() : std::runtime_error("") {} - ThreadPoolException(const std::string& message) - : std::runtime_error(message), message_(message) {} - virtual const char* what() const throw() { - return message_.c_str(); - } - - private: - const std::string message_; -}; - -// all functions passed in by clients will be initially stored in this list. -typedef std::list> FunctionList; -// info about threads in the pool will be saved using this struct. -typedef struct tagThreadData { - bool free; - HANDLE wait_handle; - HANDLE thread_handle; - DWORD thread_id; -} ThreadData; -// info about all threads belonging to this pool will be stored in this map -typedef std::map> - ThreadMap; -enum class State { - Ready, // has been created - Destroying, // in the process of getting destroyed, no request is processed / - // accepted - Destroyed // Destroyed, no threads are available, request can still be queued -}; -class ThreadPool { - public: - ThreadPool(int nPoolSize, bool bCreateNow); - virtual ~ThreadPool(); - bool Create(); // creates the thread pool - void Destroy(); // destroy the thread pool - int GetPoolSize(); - void SetPoolSize(int); - bool Run(std::unique_ptr runObject); - bool CheckThreadStop(); - int GetWorkingThreadCount(); - State GetState(); - - private: - static DWORD WINAPI _ThreadProc(LPVOID); - std::unique_ptr function_list_; - std::unique_ptr thread_map_; - HANDLE* thread_handles_ = nullptr; - int pool_size_; - int wait_for_threads_to_die_ms_; // In milli-seconds - std::string pool_name_; // To assist in logging and debug - HANDLE notify_shutdown_; // notifies threads that a new function - // is added - volatile State pool_state_; - static __declspec( - align(8)) volatile long instance_; // NOLINT Windows function takes - // volatile long - CRITICAL_SECTION critical_section_; - - bool GetThreadProc(DWORD dwThreadId, std::unique_ptr&& runner); - void FinishNotify(DWORD dwThreadId); - void BusyNotify(DWORD dwThreadId); - void ReleaseMemory(); - HANDLE GetWaitHandle(DWORD dwThreadId); - HANDLE GetShutdownHandle(); - void AddRunner(std::unique_ptr runner); - DWORD CreateThreadPoolThread(HANDLE* handles); -}; - -} // namespace windows -} // namespace nearby -} // namespace location -#endif // PLATFORM_IMPL_WINDOWS_THREAD_POOL_H_ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#ifndef PLATFORM_IMPL_WINDOWS_THREAD_POOL_H_ +#define PLATFORM_IMPL_WINDOWS_THREAD_POOL_H_ +#include + +#include +#include +#include +#include + +#include "platform/impl/windows/runner.h" +namespace location { +namespace nearby { +namespace windows { + +// This is the number of threads that will be started initially if the pool +// size is greater than 4, or if the pool size is greater than the number +// of cores present, including virtual cores +#define STARTUP_THREAD_COUNT 4 + +class ThreadPoolException : public std::runtime_error { + public: + ThreadPoolException() : std::runtime_error("") {} + ThreadPoolException(const std::string& message) + : std::runtime_error(message), message_(message) {} + virtual const char* what() const throw() { + return message_.c_str(); + } + + private: + const std::string message_; +}; + +// all functions passed in by clients will be initially stored in this list. +typedef std::list> FunctionList; +// info about threads in the pool will be saved using this struct. +typedef struct tagThreadData { + bool free; + HANDLE wait_handle; + HANDLE thread_handle; + DWORD thread_id; +} ThreadData; +// info about all threads belonging to this pool will be stored in this map +typedef std::map> + ThreadMap; +enum class State { + Ready, // has been created + Destroying, // in the process of getting destroyed, no request is processed / + // accepted + Destroyed // Destroyed, no threads are available, request can still be queued +}; +class ThreadPool { + public: + ThreadPool(int nPoolSize, bool bCreateNow); + virtual ~ThreadPool(); + bool Create(); // creates the thread pool + void Destroy(); // destroy the thread pool + int GetPoolSize(); + void SetPoolSize(int); + bool Run(std::unique_ptr runObject); + bool CheckThreadStop(); + int GetWorkingThreadCount(); + State GetState(); + + private: + static DWORD WINAPI _ThreadProc(LPVOID); + std::unique_ptr function_list_; + std::unique_ptr thread_map_; + HANDLE* thread_handles_ = nullptr; + int pool_size_; + int wait_for_threads_to_die_ms_; // In milli-seconds + std::string pool_name_; // To assist in logging and debug + HANDLE notify_shutdown_; // notifies threads that a new function + // is added + volatile State pool_state_; + static __declspec( + align(8)) volatile long instance_; // NOLINT Windows function takes + // volatile long + CRITICAL_SECTION critical_section_; + + bool GetThreadProc(DWORD dwThreadId, std::unique_ptr&& runner); + void FinishNotify(DWORD dwThreadId); + void BusyNotify(DWORD dwThreadId); + void ReleaseMemory(); + HANDLE GetWaitHandle(DWORD dwThreadId); + HANDLE GetShutdownHandle(); + void AddRunner(std::unique_ptr runner); + DWORD CreateThreadPoolThread(HANDLE* handles); +}; + +} // namespace windows +} // namespace nearby +} // namespace location +#endif // PLATFORM_IMPL_WINDOWS_THREAD_POOL_H_ diff --git a/cpp/platform/impl/windows/utils_test.cc b/cpp/platform/impl/windows/utils_test.cc index c639e857..96df927e 100644 --- a/cpp/platform/impl/windows/utils_test.cc +++ b/cpp/platform/impl/windows/utils_test.cc @@ -1,31 +1,31 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "platform/impl/windows/utils.h" - -#include "gtest/gtest.h" - -using location::nearby::windows::uint64_to_mac_address_string; - -TEST(UtilsTests, MacAddressToString) { - // Arrange - const uint64_t input = 0x000034363bc78c71; - std::string expected = "34:36:3B:C7:8C:71"; - - // Act - std::string result = uint64_to_mac_address_string(input); - - // Assert - EXPECT_EQ(result, expected); -} +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "platform/impl/windows/utils.h" + +#include "gtest/gtest.h" + +using location::nearby::windows::uint64_to_mac_address_string; + +TEST(UtilsTests, MacAddressToString) { + // Arrange + const uint64_t input = 0x000034363bc78c71; + std::string expected = "34:36:3B:C7:8C:71"; + + // Act + std::string result = uint64_to_mac_address_string(input); + + // Assert + EXPECT_EQ(result, expected); +} diff --git a/cpp/platform/public/core_config.h b/cpp/platform/public/core_config.h index 3afa60fc..9ccfa519 100644 --- a/cpp/platform/public/core_config.h +++ b/cpp/platform/public/core_config.h @@ -1,38 +1,38 @@ -// 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_CONFIG_H_ -#define CORE_CONFIG_H_ - -namespace location { -namespace nearby { -namespace connections { - -#ifdef _WIN32 // These storage class specifiers only matter to win32 dll - // builds. -#ifdef CORE_ADAPTER_DLL -#define DLL_API \ - __declspec(dllexport) // If we're building the core, we're exporting. -#else // !CORE_ADAPTER_DLL -#define DLL_API \ - __declspec(dllimport) // If we're not building the core, we're importing. -#endif // CORE_ADAPTER_DLL -#else // !_WIN32 -#define DLL_API // We're not building a win32 dll, leave the source unchanged. -#endif // _WIN32 - -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_CONFIG_H_ +// 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_CONFIG_H_ +#define CORE_CONFIG_H_ + +namespace location { +namespace nearby { +namespace connections { + +#ifdef _WIN32 // These storage class specifiers only matter to win32 dll + // builds. +#ifdef CORE_ADAPTER_DLL +#define DLL_API \ + __declspec(dllexport) // If we're building the core, we're exporting. +#else // !CORE_ADAPTER_DLL +#define DLL_API \ + __declspec(dllimport) // If we're not building the core, we're importing. +#endif // CORE_ADAPTER_DLL +#else // !_WIN32 +#define DLL_API // We're not building a win32 dll, leave the source unchanged. +#endif // _WIN32 + +} // namespace connections +} // namespace nearby +} // namespace location + +#endif // CORE_CONFIG_H_ diff --git a/proto/BUILD b/proto/BUILD index 0117405f..41050493 100644 --- a/proto/BUILD +++ b/proto/BUILD @@ -62,7 +62,7 @@ portable_proto_library( ], visibility = [ "//location/nearby/connections:__subpackages__", - "//third_party/nearby_connections:__subpackages__", + "//third_party/nearby:__subpackages__", ], ) diff --git a/proto/connections/BUILD b/proto/connections/BUILD index 87b14c9b..043a1c6b 100644 --- a/proto/connections/BUILD +++ b/proto/connections/BUILD @@ -55,9 +55,7 @@ portable_proto_library( ":offline_wire_formats_proto", ], visibility = [ - "//location/nearby/connections:__subpackages__", - "//nearby_connections:__subpackages__", - "//third_party/nearby_connections:__subpackages__", + "//third_party/nearby:__subpackages__", ], ) diff --git a/proto/connections/offline_wire_formats.proto b/proto/connections/offline_wire_formats.proto index ac588876..a86c53d6 100644 --- a/proto/connections/offline_wire_formats.proto +++ b/proto/connections/offline_wire_formats.proto @@ -72,7 +72,7 @@ message ConnectionRequestFrame { WEB_RTC = 9; BLE_L2CAP = 10; } - // LINT.ThenChange(//depot/google3/third_party/nearby_connections/proto/connections_enums.proto) + // LINT.ThenChange(//depot/google3/third_party/nearby/proto/connections_enums.proto) optional string endpoint_id = 1; optional string endpoint_name = 2; diff --git a/proto/connections_enums.proto b/proto/connections_enums.proto index 2efe8e6a..97ae20e5 100644 --- a/proto/connections_enums.proto +++ b/proto/connections_enums.proto @@ -86,7 +86,7 @@ enum Medium { // LINT.ThenChange( // //depot/google3/java/com/google/android/gmscore/integ/client/nearby/src/com/google/android/gms/nearby/connection/Medium.java, // //depot/google3/java/com/google/android/gms/nearby/internal/connection/api.proto, -// //depot/google3/third_party/nearby_connections/proto/connections/offline_wire_formats.proto +// //depot/google3/third_party/nearby/proto/connections/offline_wire_formats.proto // ) // The medium technologies used during the sharing. diff --git a/proto/errorcode/BUILD b/proto/errorcode/BUILD index 9cd74c39..0589c829 100644 --- a/proto/errorcode/BUILD +++ b/proto/errorcode/BUILD @@ -48,7 +48,7 @@ portable_proto_library( ":error_code_enums_proto", ], visibility = [ - "//third_party/nearby_connections:__subpackages__", + "//third_party/nearby:__subpackages__", ], ) diff --git a/proto/mediums/BUILD b/proto/mediums/BUILD index 0064d553..5001e2ea 100644 --- a/proto/mediums/BUILD +++ b/proto/mediums/BUILD @@ -85,7 +85,7 @@ cc_proto_library( ], visibility = [ "//location/nearby/connections:__subpackages__", - "//third_party/nearby_connections:__subpackages__", + "//third_party/nearby:__subpackages__", ], deps = [":web_rtc_signaling_frames_proto"], ) diff --git a/windows/advertising_options.cc b/windows/advertising_options.cc index e4cb45d3..d65a6bd5 100644 --- a/windows/advertising_options.cc +++ b/windows/advertising_options.cc @@ -1,72 +1,72 @@ -// Copyright 2021 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 "third_party/nearby_connections/windows/advertising_options.h" - -#include "core/options.h" -#include "core/strategy.h" -#include "platform/base/byte_array.h" -#include "platform/public/core_config.h" - -namespace location { -namespace nearby { -namespace connections { -namespace windows { - -AdvertisingOptions::AdvertisingOptions() - : impl_(new connections::ConnectionOptions(), - [](connections::ConnectionOptions *impl) { delete impl; }), - strategy(impl_->strategy), - allowed(impl_->allowed), - auto_upgrade_bandwidth(impl_->auto_upgrade_bandwidth), - enable_bluetooth_listening(impl_->enable_bluetooth_listening), - enable_webrtc_listening(impl_->enable_webrtc_listening), - low_power(impl_->low_power), - enforce_topology_constraints(impl_->enforce_topology_constraints), - is_out_of_band_connection(impl_->is_out_of_band_connection), - remote_bluetooth_mac_address(impl_->remote_bluetooth_mac_address), - fast_advertisement_service_uuid( - impl_->fast_advertisement_service_uuid.c_str()), - keep_alive_interval_millis(impl_->keep_alive_interval_millis), - keep_alive_timeout_millis(impl_->keep_alive_timeout_millis) {} - -AdvertisingOptions::operator connections::ConnectionOptions() const { - return *impl_.get(); -} - -// Verify if ConnectionOptions is in a not-initialized (Empty) state. -bool AdvertisingOptions::Empty() const { return impl_->Empty(); } - -// Bring ConnectionOptions to a not-initialized (Empty) state. -void AdvertisingOptions::Clear() {} - -// Returns a copy and normalizes allowed mediums: -// (1) If is_out_of_band_connection is true, verifies that there is only one -// medium allowed, defaulting to only Bluetooth if unspecified. -// (2) If no mediums are allowed, allow all mediums. -connections::ConnectionOptions AdvertisingOptions::CompatibleOptions() const { - return impl_->CompatibleOptions(); -} - -// This call follows the standard Microsoft calling pattern of calling first -// to get the size of the array. Caller then allocates memory for the array, -// and makes this call again to copy the array into the provided location. -void AdvertisingOptions::GetMediums( - location::nearby::proto::connections::Medium *mediums, - uint32_t *mediumsSize) {} - -} // namespace windows -} // namespace connections -} // namespace nearby -} // namespace location +// Copyright 2021 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 "third_party/nearby/windows/advertising_options.h" + +#include "core/options.h" +#include "core/strategy.h" +#include "platform/base/byte_array.h" +#include "platform/public/core_config.h" + +namespace location { +namespace nearby { +namespace connections { +namespace windows { + +AdvertisingOptions::AdvertisingOptions() + : impl_(new connections::ConnectionOptions(), + [](connections::ConnectionOptions *impl) { delete impl; }), + strategy(impl_->strategy), + allowed(impl_->allowed), + auto_upgrade_bandwidth(impl_->auto_upgrade_bandwidth), + enable_bluetooth_listening(impl_->enable_bluetooth_listening), + enable_webrtc_listening(impl_->enable_webrtc_listening), + low_power(impl_->low_power), + enforce_topology_constraints(impl_->enforce_topology_constraints), + is_out_of_band_connection(impl_->is_out_of_band_connection), + remote_bluetooth_mac_address(impl_->remote_bluetooth_mac_address), + fast_advertisement_service_uuid( + impl_->fast_advertisement_service_uuid.c_str()), + keep_alive_interval_millis(impl_->keep_alive_interval_millis), + keep_alive_timeout_millis(impl_->keep_alive_timeout_millis) {} + +AdvertisingOptions::operator connections::ConnectionOptions() const { + return *impl_.get(); +} + +// Verify if ConnectionOptions is in a not-initialized (Empty) state. +bool AdvertisingOptions::Empty() const { return impl_->Empty(); } + +// Bring ConnectionOptions to a not-initialized (Empty) state. +void AdvertisingOptions::Clear() {} + +// Returns a copy and normalizes allowed mediums: +// (1) If is_out_of_band_connection is true, verifies that there is only one +// medium allowed, defaulting to only Bluetooth if unspecified. +// (2) If no mediums are allowed, allow all mediums. +connections::ConnectionOptions AdvertisingOptions::CompatibleOptions() const { + return impl_->CompatibleOptions(); +} + +// This call follows the standard Microsoft calling pattern of calling first +// to get the size of the array. Caller then allocates memory for the array, +// and makes this call again to copy the array into the provided location. +void AdvertisingOptions::GetMediums( + location::nearby::proto::connections::Medium *mediums, + uint32_t *mediumsSize) {} + +} // namespace windows +} // namespace connections +} // namespace nearby +} // namespace location diff --git a/windows/advertising_options.h b/windows/advertising_options.h index 55642699..80b54e13 100644 --- a/windows/advertising_options.h +++ b/windows/advertising_options.h @@ -1,92 +1,92 @@ -// Copyright 2021 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 WINDOWS_START_ADVERTISING_OPTIONS_H_ -#define WINDOWS_START_ADVERTISING_OPTIONS_H_ - -#include - -#include - -#include "platform/public/core_config.h" - -namespace location { -namespace nearby { -class ByteArray; -namespace proto { -namespace connections { -enum Medium : int; -} // namespace connections -} // namespace proto -namespace connections { -struct ConnectionOptions; -class Strategy; -template -struct MediumSelector; - -using BooleanMediumSelector = MediumSelector; - -namespace windows { - -struct DLL_API AdvertisingOptions { - AdvertisingOptions(); - operator connections::ConnectionOptions() const; - - private: - std::unique_ptr - impl_; - - public: - connections::Strategy &strategy; - connections::BooleanMediumSelector &allowed; - - bool &auto_upgrade_bandwidth; - bool &enable_bluetooth_listening; - bool &enable_webrtc_listening; - bool &low_power; - bool &enforce_topology_constraints; - - // Whether this is intended to be used in conjunction with InjectEndpoint(). - bool &is_out_of_band_connection; - ByteArray &remote_bluetooth_mac_address; - const char *fast_advertisement_service_uuid; - int &keep_alive_interval_millis; - int &keep_alive_timeout_millis; - - // Verify if ConnectionOptions is in a not-initialized (Empty) state. - bool Empty() const; - - // Bring ConnectionOptions to a not-initialized (Empty) state. - void Clear(); - - // Returns a copy and normalizes allowed mediums: - // (1) If is_out_of_band_connection is true, verifies that there is only one - // medium allowed, defaulting to only Bluetooth if unspecified. - // (2) If no mediums are allowed, allow all mediums. - connections::ConnectionOptions CompatibleOptions() const; - - // This call follows the standard Microsoft calling pattern of calling first - // to get the size of the array. Caller then allocates memory for the array, - // and makes this call again to copy the array into the provided location. - void GetMediums(location::nearby::proto::connections::Medium *mediums, - uint32_t *mediumsSize); -}; - -} // namespace windows -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // WINDOWS_START_ADVERTISING_OPTIONS_H_ +// Copyright 2021 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 WINDOWS_START_ADVERTISING_OPTIONS_H_ +#define WINDOWS_START_ADVERTISING_OPTIONS_H_ + +#include + +#include + +#include "platform/public/core_config.h" + +namespace location { +namespace nearby { +class ByteArray; +namespace proto { +namespace connections { +enum Medium : int; +} // namespace connections +} // namespace proto +namespace connections { +struct ConnectionOptions; +class Strategy; +template +struct MediumSelector; + +using BooleanMediumSelector = MediumSelector; + +namespace windows { + +struct DLL_API AdvertisingOptions { + AdvertisingOptions(); + operator connections::ConnectionOptions() const; + + private: + std::unique_ptr + impl_; + + public: + connections::Strategy &strategy; + connections::BooleanMediumSelector &allowed; + + bool &auto_upgrade_bandwidth; + bool &enable_bluetooth_listening; + bool &enable_webrtc_listening; + bool &low_power; + bool &enforce_topology_constraints; + + // Whether this is intended to be used in conjunction with InjectEndpoint(). + bool &is_out_of_band_connection; + ByteArray &remote_bluetooth_mac_address; + const char *fast_advertisement_service_uuid; + int &keep_alive_interval_millis; + int &keep_alive_timeout_millis; + + // Verify if ConnectionOptions is in a not-initialized (Empty) state. + bool Empty() const; + + // Bring ConnectionOptions to a not-initialized (Empty) state. + void Clear(); + + // Returns a copy and normalizes allowed mediums: + // (1) If is_out_of_band_connection is true, verifies that there is only one + // medium allowed, defaulting to only Bluetooth if unspecified. + // (2) If no mediums are allowed, allow all mediums. + connections::ConnectionOptions CompatibleOptions() const; + + // This call follows the standard Microsoft calling pattern of calling first + // to get the size of the array. Caller then allocates memory for the array, + // and makes this call again to copy the array into the provided location. + void GetMediums(location::nearby::proto::connections::Medium *mediums, + uint32_t *mediumsSize); +}; + +} // namespace windows +} // namespace connections +} // namespace nearby +} // namespace location + +#endif // WINDOWS_START_ADVERTISING_OPTIONS_H_ diff --git a/windows/connection_options.cc b/windows/connection_options.cc index 79913f18..7d299454 100644 --- a/windows/connection_options.cc +++ b/windows/connection_options.cc @@ -1,74 +1,74 @@ -// Copyright 2021 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 "third_party/nearby_connections/windows/connection_options.h" - -#include "core/options.h" -#include "core/strategy.h" -#include "platform/base/byte_array.h" -#include "platform/public/core_config.h" - -namespace location { -namespace nearby { -namespace connections { -namespace windows { - -ConnectionOptions::ConnectionOptions() - : impl_(new connections::ConnectionOptions(), - [](connections::ConnectionOptions *impl) { delete impl; }), - strategy(impl_->strategy), - allowed(impl_->allowed), - auto_upgrade_bandwidth(impl_->auto_upgrade_bandwidth), - enable_bluetooth_listening(impl_->enable_bluetooth_listening), - enable_webrtc_listening(impl_->enable_webrtc_listening), - low_power(impl_->low_power), - enforce_topology_constraints(impl_->enforce_topology_constraints), - is_out_of_band_connection(impl_->is_out_of_band_connection), - remote_bluetooth_mac_address(impl_->remote_bluetooth_mac_address), - fast_advertisement_service_uuid( - impl_->fast_advertisement_service_uuid.c_str()), - keep_alive_interval_millis(impl_->keep_alive_interval_millis), - keep_alive_timeout_millis(impl_->keep_alive_timeout_millis) {} - -ConnectionOptions::operator connections::ConnectionOptions() const { - return *impl_.get(); -} - -// Verify if ConnectionOptions is in a not-initialized (Empty) state. -bool ConnectionOptions::Empty() const { return impl_->Empty(); } - -// Bring ConnectionOptions to a not-initialized (Empty) state. -void ConnectionOptions::Clear() {} - -// Returns a copy and normalizes allowed mediums: -// (1) If is_out_of_band_connection is true, verifies that there is only one -// medium allowed, defaulting to only Bluetooth if unspecified. -// (2) If no mediums are allowed, allow all mediums. -connections::ConnectionOptions ConnectionOptions::CompatibleOptions() const { - return impl_->CompatibleOptions(); -} - -// std::vector GetMediums() const; - -// This call follows the standard Microsoft calling pattern of calling first -// to get the size of the array. Caller then allocates memory for the array, -// and makes this call again to copy the array into the provided location. -void ConnectionOptions::GetMediums( - location::nearby::proto::connections::Medium *mediums, - uint32_t *mediumsSize) {} - -} // namespace windows -} // namespace connections -} // namespace nearby -} // namespace location +// Copyright 2021 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 "third_party/nearby/windows/connection_options.h" + +#include "core/options.h" +#include "core/strategy.h" +#include "platform/base/byte_array.h" +#include "platform/public/core_config.h" + +namespace location { +namespace nearby { +namespace connections { +namespace windows { + +ConnectionOptions::ConnectionOptions() + : impl_(new connections::ConnectionOptions(), + [](connections::ConnectionOptions *impl) { delete impl; }), + strategy(impl_->strategy), + allowed(impl_->allowed), + auto_upgrade_bandwidth(impl_->auto_upgrade_bandwidth), + enable_bluetooth_listening(impl_->enable_bluetooth_listening), + enable_webrtc_listening(impl_->enable_webrtc_listening), + low_power(impl_->low_power), + enforce_topology_constraints(impl_->enforce_topology_constraints), + is_out_of_band_connection(impl_->is_out_of_band_connection), + remote_bluetooth_mac_address(impl_->remote_bluetooth_mac_address), + fast_advertisement_service_uuid( + impl_->fast_advertisement_service_uuid.c_str()), + keep_alive_interval_millis(impl_->keep_alive_interval_millis), + keep_alive_timeout_millis(impl_->keep_alive_timeout_millis) {} + +ConnectionOptions::operator connections::ConnectionOptions() const { + return *impl_.get(); +} + +// Verify if ConnectionOptions is in a not-initialized (Empty) state. +bool ConnectionOptions::Empty() const { return impl_->Empty(); } + +// Bring ConnectionOptions to a not-initialized (Empty) state. +void ConnectionOptions::Clear() {} + +// Returns a copy and normalizes allowed mediums: +// (1) If is_out_of_band_connection is true, verifies that there is only one +// medium allowed, defaulting to only Bluetooth if unspecified. +// (2) If no mediums are allowed, allow all mediums. +connections::ConnectionOptions ConnectionOptions::CompatibleOptions() const { + return impl_->CompatibleOptions(); +} + +// std::vector GetMediums() const; + +// This call follows the standard Microsoft calling pattern of calling first +// to get the size of the array. Caller then allocates memory for the array, +// and makes this call again to copy the array into the provided location. +void ConnectionOptions::GetMediums( + location::nearby::proto::connections::Medium *mediums, + uint32_t *mediumsSize) {} + +} // namespace windows +} // namespace connections +} // namespace nearby +} // namespace location diff --git a/windows/connection_options.h b/windows/connection_options.h index f49fb431..6d7f0cfb 100644 --- a/windows/connection_options.h +++ b/windows/connection_options.h @@ -1,91 +1,91 @@ -// Copyright 2021 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 WINDOWS_REQUEST_CONNECTION_OPTIONS_H_ -#define WINDOWS_REQUEST_CONNECTION_OPTIONS_H_ - -#include - -#include - -#include "platform/public/core_config.h" - -namespace location { -namespace nearby { -class ByteArray; -namespace proto { -namespace connections { -enum Medium : int; -} -} // namespace proto -namespace connections { -struct ConnectionOptions; -class Strategy; -template -struct MediumSelector; - -using BooleanMediumSelector = MediumSelector; - -namespace windows { -struct DLL_API ConnectionOptions { - ConnectionOptions(); - operator connections::ConnectionOptions() const; - - private: - std::unique_ptr - impl_; - - public: - connections::Strategy &strategy; - connections::BooleanMediumSelector &allowed; - - bool &auto_upgrade_bandwidth; - bool &enable_bluetooth_listening; - bool &enable_webrtc_listening; - bool &low_power; - bool &enforce_topology_constraints; - - // Whether this is intended to be used in conjunction with InjectEndpoint(). - bool &is_out_of_band_connection; - ByteArray &remote_bluetooth_mac_address; - const char *fast_advertisement_service_uuid; - int &keep_alive_interval_millis; - int &keep_alive_timeout_millis; - - // Verify if ConnectionOptions is in a not-initialized (Empty) state. - bool Empty() const; - - // Bring ConnectionOptions to a not-initialized (Empty) state. - void Clear(); - - // Returns a copy and normalizes allowed mediums: - // (1) If is_out_of_band_connection is true, verifies that there is only one - // medium allowed, defaulting to only Bluetooth if unspecified. - // (2) If no mediums are allowed, allow all mediums. - connections::ConnectionOptions CompatibleOptions() const; - - // This call follows the standard Microsoft calling pattern of calling first - // to get the size of the array. Caller then allocates memory for the array, - // and makes this call again to copy the array into the provided location. - void GetMediums(location::nearby::proto::connections::Medium *mediums, - uint32_t *mediumsSize); -}; - -} // namespace windows -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // WINDOWS_REQUEST_CONNECTION_OPTIONS_H_ +// Copyright 2021 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 WINDOWS_REQUEST_CONNECTION_OPTIONS_H_ +#define WINDOWS_REQUEST_CONNECTION_OPTIONS_H_ + +#include + +#include + +#include "platform/public/core_config.h" + +namespace location { +namespace nearby { +class ByteArray; +namespace proto { +namespace connections { +enum Medium : int; +} +} // namespace proto +namespace connections { +struct ConnectionOptions; +class Strategy; +template +struct MediumSelector; + +using BooleanMediumSelector = MediumSelector; + +namespace windows { +struct DLL_API ConnectionOptions { + ConnectionOptions(); + operator connections::ConnectionOptions() const; + + private: + std::unique_ptr + impl_; + + public: + connections::Strategy &strategy; + connections::BooleanMediumSelector &allowed; + + bool &auto_upgrade_bandwidth; + bool &enable_bluetooth_listening; + bool &enable_webrtc_listening; + bool &low_power; + bool &enforce_topology_constraints; + + // Whether this is intended to be used in conjunction with InjectEndpoint(). + bool &is_out_of_band_connection; + ByteArray &remote_bluetooth_mac_address; + const char *fast_advertisement_service_uuid; + int &keep_alive_interval_millis; + int &keep_alive_timeout_millis; + + // Verify if ConnectionOptions is in a not-initialized (Empty) state. + bool Empty() const; + + // Bring ConnectionOptions to a not-initialized (Empty) state. + void Clear(); + + // Returns a copy and normalizes allowed mediums: + // (1) If is_out_of_band_connection is true, verifies that there is only one + // medium allowed, defaulting to only Bluetooth if unspecified. + // (2) If no mediums are allowed, allow all mediums. + connections::ConnectionOptions CompatibleOptions() const; + + // This call follows the standard Microsoft calling pattern of calling first + // to get the size of the array. Caller then allocates memory for the array, + // and makes this call again to copy the array into the provided location. + void GetMediums(location::nearby::proto::connections::Medium *mediums, + uint32_t *mediumsSize); +}; + +} // namespace windows +} // namespace connections +} // namespace nearby +} // namespace location + +#endif // WINDOWS_REQUEST_CONNECTION_OPTIONS_H_ diff --git a/windows/core_adapter.cc b/windows/core_adapter.cc index 8b09502b..436af081 100644 --- a/windows/core_adapter.cc +++ b/windows/core_adapter.cc @@ -11,7 +11,7 @@ // 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 "third_party/nearby_connections/windows/core_adapter.h" +#include "third_party/nearby/windows/core_adapter.h" #include "absl/strings/str_format.h" #include "core/core.h" diff --git a/windows/core_adapter.h b/windows/core_adapter.h index 826332a8..9882f270 100644 --- a/windows/core_adapter.h +++ b/windows/core_adapter.h @@ -19,9 +19,9 @@ // todo(jfcarroll) This cannot remain. It exposes stuff the client doesn't need. #include "core/internal/offline_service_controller.h" -#include "third_party/nearby_connections/windows/advertising_options.h" -#include "third_party/nearby_connections/windows/connection_options.h" -#include "third_party/nearby_connections/windows/discovery_options.h" +#include "third_party/nearby/windows/advertising_options.h" +#include "third_party/nearby/windows/connection_options.h" +#include "third_party/nearby/windows/discovery_options.h" #define DLL_EXPORT extern "C" __declspec(dllexport) diff --git a/windows/dart/core_adapter_dart.cc b/windows/dart/core_adapter_dart.cc index 0fb24903..2d12d60f 100644 --- a/windows/dart/core_adapter_dart.cc +++ b/windows/dart/core_adapter_dart.cc @@ -15,7 +15,7 @@ #include "third_party/dart_lang/v2/runtime/include/dart_api_dl.h" #include "third_party/dart_lang/v2/runtime/include/dart_native_api.h" #include "core/core.h" -#include "third_party/nearby_connections/windows/dart/core_adapter_dart.h" +#include "third_party/nearby/windows/dart/core_adapter_dart.h" namespace location { namespace nearby { diff --git a/windows/dart/core_adapter_dart.h b/windows/dart/core_adapter_dart.h index 91397270..5c7f521f 100644 --- a/windows/dart/core_adapter_dart.h +++ b/windows/dart/core_adapter_dart.h @@ -15,7 +15,7 @@ #ifndef LOCATION_NEARBY_CONNECTIONS_WINDOWS_DART_CORE_ADAPTER_DART_H_ #define LOCATION_NEARBY_CONNECTIONS_WINDOWS_DART_CORE_ADAPTER_DART_H_ -#include "third_party/nearby_connections/windows/core_adapter.h" +#include "third_party/nearby/windows/core_adapter.h" namespace location { namespace nearby { diff --git a/windows/discovery_options.cc b/windows/discovery_options.cc index 919b3381..caf1460c 100644 --- a/windows/discovery_options.cc +++ b/windows/discovery_options.cc @@ -1,72 +1,72 @@ -// Copyright 2021 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 "third_party/nearby_connections/windows/discovery_options.h" - -#include "core/options.h" -#include "core/strategy.h" -#include "platform/base/byte_array.h" -#include "platform/public/core_config.h" - -namespace location { -namespace nearby { -namespace connections { -namespace windows { - -DiscoveryOptions::DiscoveryOptions() - : impl_(new connections::ConnectionOptions(), - [](connections::ConnectionOptions *impl) { delete impl; }), - strategy(impl_->strategy), - allowed(impl_->allowed), - auto_upgrade_bandwidth(impl_->auto_upgrade_bandwidth), - enable_bluetooth_listening(impl_->enable_bluetooth_listening), - enable_webrtc_listening(impl_->enable_webrtc_listening), - low_power(impl_->low_power), - enforce_topology_constraints(impl_->enforce_topology_constraints), - is_out_of_band_connection(impl_->is_out_of_band_connection), - remote_bluetooth_mac_address(impl_->remote_bluetooth_mac_address), - fast_advertisement_service_uuid( - impl_->fast_advertisement_service_uuid.c_str()), - keep_alive_interval_millis(impl_->keep_alive_interval_millis), - keep_alive_timeout_millis(impl_->keep_alive_timeout_millis) {} - -DiscoveryOptions::operator connections::ConnectionOptions() const { - return *impl_.get(); -} - -// Verify if ConnectionOptions is in a not-initialized (Empty) state. -bool DiscoveryOptions::Empty() const { return impl_->Empty(); } - -// Bring ConnectionOptions to a not-initialized (Empty) state. -void DiscoveryOptions::Clear() {} - -// Returns a copy and normalizes allowed mediums: -// (1) If is_out_of_band_connection is true, verifies that there is only one -// medium allowed, defaulting to only Bluetooth if unspecified. -// (2) If no mediums are allowed, allow all mediums. -connections::ConnectionOptions DiscoveryOptions::CompatibleOptions() const { - return impl_->CompatibleOptions(); -} - -// This call follows the standard Microsoft calling pattern of calling first -// to get the size of the array. Caller then allocates memory for the array, -// and makes this call again to copy the array into the provided location. -void DiscoveryOptions::GetMediums( - location::nearby::proto::connections::Medium *mediums, - uint32_t *mediumsSize) {} - -} // namespace windows -} // namespace connections -} // namespace nearby -} // namespace location +// Copyright 2021 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 "third_party/nearby/windows/discovery_options.h" + +#include "core/options.h" +#include "core/strategy.h" +#include "platform/base/byte_array.h" +#include "platform/public/core_config.h" + +namespace location { +namespace nearby { +namespace connections { +namespace windows { + +DiscoveryOptions::DiscoveryOptions() + : impl_(new connections::ConnectionOptions(), + [](connections::ConnectionOptions *impl) { delete impl; }), + strategy(impl_->strategy), + allowed(impl_->allowed), + auto_upgrade_bandwidth(impl_->auto_upgrade_bandwidth), + enable_bluetooth_listening(impl_->enable_bluetooth_listening), + enable_webrtc_listening(impl_->enable_webrtc_listening), + low_power(impl_->low_power), + enforce_topology_constraints(impl_->enforce_topology_constraints), + is_out_of_band_connection(impl_->is_out_of_band_connection), + remote_bluetooth_mac_address(impl_->remote_bluetooth_mac_address), + fast_advertisement_service_uuid( + impl_->fast_advertisement_service_uuid.c_str()), + keep_alive_interval_millis(impl_->keep_alive_interval_millis), + keep_alive_timeout_millis(impl_->keep_alive_timeout_millis) {} + +DiscoveryOptions::operator connections::ConnectionOptions() const { + return *impl_.get(); +} + +// Verify if ConnectionOptions is in a not-initialized (Empty) state. +bool DiscoveryOptions::Empty() const { return impl_->Empty(); } + +// Bring ConnectionOptions to a not-initialized (Empty) state. +void DiscoveryOptions::Clear() {} + +// Returns a copy and normalizes allowed mediums: +// (1) If is_out_of_band_connection is true, verifies that there is only one +// medium allowed, defaulting to only Bluetooth if unspecified. +// (2) If no mediums are allowed, allow all mediums. +connections::ConnectionOptions DiscoveryOptions::CompatibleOptions() const { + return impl_->CompatibleOptions(); +} + +// This call follows the standard Microsoft calling pattern of calling first +// to get the size of the array. Caller then allocates memory for the array, +// and makes this call again to copy the array into the provided location. +void DiscoveryOptions::GetMediums( + location::nearby::proto::connections::Medium *mediums, + uint32_t *mediumsSize) {} + +} // namespace windows +} // namespace connections +} // namespace nearby +} // namespace location diff --git a/windows/discovery_options.h b/windows/discovery_options.h index 8993825f..a22e9836 100644 --- a/windows/discovery_options.h +++ b/windows/discovery_options.h @@ -1,92 +1,92 @@ -// Copyright 2021 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 WINDOWS_START_DISCOVERY_OPTIONS_H_ -#define WINDOWS_START_DISCOVERY_OPTIONS_H_ - -#include - -#include - -#include "platform/public/core_config.h" - -namespace location { -namespace nearby { -class ByteArray; -namespace proto { -namespace connections { -enum Medium : int; -} -} // namespace proto -namespace connections { - -struct ConnectionOptions; -class Strategy; -template -struct MediumSelector; - -using BooleanMediumSelector = MediumSelector; - -namespace windows { -struct DLL_API DiscoveryOptions { - DiscoveryOptions(); - operator connections::ConnectionOptions() const; - - private: - std::unique_ptr - impl_; - - public: - connections::Strategy &strategy; - connections::BooleanMediumSelector &allowed; - - bool &auto_upgrade_bandwidth; - bool &enable_bluetooth_listening; - bool &enable_webrtc_listening; - bool &low_power; - bool &enforce_topology_constraints; - - // Whether this is intended to be used in conjunction with InjectEndpoint(). - bool &is_out_of_band_connection; - ByteArray &remote_bluetooth_mac_address; - const char *fast_advertisement_service_uuid; - int &keep_alive_interval_millis; - int &keep_alive_timeout_millis; - - // Verify if ConnectionOptions is in a not-initialized (Empty) state. - bool Empty() const; - - // Bring ConnectionOptions to a not-initialized (Empty) state. - void Clear(); - - // Returns a copy and normalizes allowed mediums: - // (1) If is_out_of_band_connection is true, verifies that there is only one - // medium allowed, defaulting to only Bluetooth if unspecified. - // (2) If no mediums are allowed, allow all mediums. - connections::ConnectionOptions CompatibleOptions() const; - - // This call follows the standard Microsoft calling pattern of calling first - // to get the size of the array. Caller then allocates memory for the array, - // and makes this call again to copy the array into the provided location. - void GetMediums(location::nearby::proto::connections::Medium *mediums, - uint32_t *mediumsSize); -}; - -} // namespace windows -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // WINDOWS_START_DISCOVERY_OPTIONS_H_ +// Copyright 2021 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 WINDOWS_START_DISCOVERY_OPTIONS_H_ +#define WINDOWS_START_DISCOVERY_OPTIONS_H_ + +#include + +#include + +#include "platform/public/core_config.h" + +namespace location { +namespace nearby { +class ByteArray; +namespace proto { +namespace connections { +enum Medium : int; +} +} // namespace proto +namespace connections { + +struct ConnectionOptions; +class Strategy; +template +struct MediumSelector; + +using BooleanMediumSelector = MediumSelector; + +namespace windows { +struct DLL_API DiscoveryOptions { + DiscoveryOptions(); + operator connections::ConnectionOptions() const; + + private: + std::unique_ptr + impl_; + + public: + connections::Strategy &strategy; + connections::BooleanMediumSelector &allowed; + + bool &auto_upgrade_bandwidth; + bool &enable_bluetooth_listening; + bool &enable_webrtc_listening; + bool &low_power; + bool &enforce_topology_constraints; + + // Whether this is intended to be used in conjunction with InjectEndpoint(). + bool &is_out_of_band_connection; + ByteArray &remote_bluetooth_mac_address; + const char *fast_advertisement_service_uuid; + int &keep_alive_interval_millis; + int &keep_alive_timeout_millis; + + // Verify if ConnectionOptions is in a not-initialized (Empty) state. + bool Empty() const; + + // Bring ConnectionOptions to a not-initialized (Empty) state. + void Clear(); + + // Returns a copy and normalizes allowed mediums: + // (1) If is_out_of_band_connection is true, verifies that there is only one + // medium allowed, defaulting to only Bluetooth if unspecified. + // (2) If no mediums are allowed, allow all mediums. + connections::ConnectionOptions CompatibleOptions() const; + + // This call follows the standard Microsoft calling pattern of calling first + // to get the size of the array. Caller then allocates memory for the array, + // and makes this call again to copy the array into the provided location. + void GetMediums(location::nearby::proto::connections::Medium *mediums, + uint32_t *mediumsSize); +}; + +} // namespace windows +} // namespace connections +} // namespace nearby +} // namespace location + +#endif // WINDOWS_START_DISCOVERY_OPTIONS_H_