From e0b1dd8dfc08b9c5488c686c06b225a8fada6cc4 Mon Sep 17 00:00:00 2001 From: jfcarroll Date: Tue, 5 Oct 2021 16:26:41 -0700 Subject: [PATCH] Exporting symbols for consumers of the dll - and deleted old code PiperOrigin-RevId: 401098019 --- cpp/core/options.h | 39 ++++++++-- cpp/core/strategy.h | 24 ++++-- .../impl/windows/condition_variable.cc | 70 ------------------ cpp/platform/impl/windows/mutex.cc | 51 ------------- windows/core_adapter.cc | 74 ++++++++++--------- windows/core_adapter.h | 29 +++----- 6 files changed, 101 insertions(+), 186 deletions(-) delete mode 100644 cpp/platform/impl/windows/condition_variable.cc delete mode 100644 cpp/platform/impl/windows/mutex.cc diff --git a/cpp/core/options.h b/cpp/core/options.h index fad5ecf1..a0310c2a 100644 --- a/cpp/core/options.h +++ b/cpp/core/options.h @@ -11,10 +11,8 @@ // 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_OPTIONS_H_ #define CORE_OPTIONS_H_ - #include #include "core/strategy.h" @@ -25,7 +23,7 @@ namespace location { namespace nearby { namespace connections { -using Medium = ::location::nearby::proto::connections::Medium; +using Medium = location::nearby::proto::connections::Medium; // Generic type: allows definition of a feature T for every Medium. template @@ -38,7 +36,6 @@ struct MediumSelector { 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; @@ -89,7 +86,7 @@ enum class PowerLevel { // Connection Options: used for both Advertising and Discovery. // All fields are mutable, to make the type copy-assignable. -struct ConnectionOptions { +struct DLL_API ConnectionOptions { Strategy strategy; BooleanMediumSelector allowed{BooleanMediumSelector().SetAll(true)}; bool auto_upgrade_bandwidth; @@ -97,16 +94,20 @@ struct ConnectionOptions { bool low_power; bool enable_bluetooth_listening; bool enable_webrtc_listening; + // Whether this is intended to be used in conjunction with InjectEndpoint(). bool is_out_of_band_connection = false; ByteArray remote_bluetooth_mac_address; std::string fast_advertisement_service_uuid; int keep_alive_interval_millis = 0; int keep_alive_timeout_millis = 0; + // Verify if ConnectionOptions is in a not-initialized (Empty) state. bool Empty() const { return strategy.IsNone(); } + // Bring ConnectionOptions to a not-initialized (Empty) state. void Clear() { strategy.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. @@ -125,7 +126,6 @@ struct ConnectionOptions { result.allowed.SetAll(false); result.allowed.bluetooth = true; } - return result; } @@ -134,7 +134,34 @@ struct ConnectionOptions { if (!allowed.Any(true)) result.allowed.SetAll(true); return result; } + std::vector GetMediums() const { return allowed.GetMediums(true); } + + // 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) { + auto size = GetMediums().size(); + + // Caller is seeking the size of mediums + if (mediums == nullptr) { + *mediumsSize = size; + return; + } + + // Caller has not specified enough memory + if (*mediumsSize < size) { + mediums = nullptr; // ensure nullptr return + *mediumsSize = size; // update the size to indicate the correct size + return; + } + + for (uint32_t i = 0; i < size; i++) { + // Construct an array at the given location + mediums[i] = GetMediums().at(i); + } + } }; // Metadata injected to facilitate out-of-band connections. The medium field is diff --git a/cpp/core/strategy.h b/cpp/core/strategy.h index c3a4f55b..7f741572 100644 --- a/cpp/core/strategy.h +++ b/cpp/core/strategy.h @@ -11,40 +11,52 @@ // 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_STRATEGY_H_ #define CORE_STRATEGY_H_ #include +#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 location { namespace nearby { namespace connections { // Defines a copyable, comparable connection strategy type. // It is one of: kP2pCluster, kP2pStar, kP2pPointToPoint. -class Strategy { +class DLL_API Strategy { public: static const Strategy kNone; static const Strategy kP2pCluster; static const Strategy kP2pStar; static const Strategy kP2pPointToPoint; - constexpr Strategy() : Strategy(kNone) {} - constexpr Strategy(const Strategy&) = default; constexpr Strategy& operator=(const Strategy&) = default; // Returns true, if strategy is kNone, false otherwise. bool IsNone() const; + // Returns true, if a strategy is one of the supported strategies, // false otherwise. bool IsValid() const; + // Returns a string representing given strategy, for every valid strategy. std::string GetName() const; + // Undefine strategy. void Clear() { *this = kNone; } - friend bool operator==(const Strategy& lhs, const Strategy& rhs); friend bool operator!=(const Strategy& lhs, const Strategy& rhs); @@ -61,7 +73,6 @@ class Strategy { }; constexpr Strategy(ConnectionType connection_type, TopologyType topology_type) : connection_type_(connection_type), topology_type_(topology_type) {} - ConnectionType connection_type_; TopologyType topology_type_; }; @@ -69,5 +80,4 @@ class Strategy { } // namespace connections } // namespace nearby } // namespace location - #endif // CORE_STRATEGY_H_ diff --git a/cpp/platform/impl/windows/condition_variable.cc b/cpp/platform/impl/windows/condition_variable.cc deleted file mode 100644 index b3a0dcd1..00000000 --- a/cpp/platform/impl/windows/condition_variable.cc +++ /dev/null @@ -1,70 +0,0 @@ -// 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" - -namespace location { -namespace nearby { -namespace windows { - -// The ConditionVariable class is a synchronization primitive that can be used -// to block a thread, or multiple threads at the same time, until another thread -// both modifies a shared variable (the condition), and notifies the -// ConditionVariable. - -ConditionVariable::ConditionVariable(api::Mutex* mutex) - : mutex_(dynamic_cast(*mutex)) { - InitializeCriticalSection(&critical_section_); -} - -// Notifies all the waiters that condition state has changed. -// TODO(b/184975123): replace with real implementation. -void ConditionVariable::Notify() { - EnterCriticalSection(&critical_section_); - - condition_variable_actual_.notify_all(); - - LeaveCriticalSection(&critical_section_); -} - -// Waits indefinitely for Notify to be called. -// May return prematurely in case of interrupt, if supported by platform. -// Returns kSuccess, or kInterrupted on interrupt. -Exception ConditionVariable::Wait() { - std::unique_lock lock = - std::unique_lock(mutex_.GetWindowsMutex()); - condition_variable_actual_.wait(lock); - - return Exception{Exception::kSuccess}; -} - -// Waits while timeout has not expired for Notify to be called. -// May return prematurely in case of interrupt, if supported by platform. -// Returns kSuccess, or kInterrupted on interrupt. -Exception ConditionVariable::Wait(absl::Duration timeout) { - auto now = std::chrono::system_clock::now(); - std::unique_lock lock = - std::unique_lock(mutex_.GetWindowsMutex()); - if (condition_variable_actual_.wait_until( - lock, now + absl::ToChronoMilliseconds(timeout)) == - std::cv_status::timeout) { - return Exception{Exception::kInterrupted}; - } else { - return Exception{Exception::kSuccess}; - } -} - -} // namespace windows -} // namespace nearby -} // namespace location diff --git a/cpp/platform/impl/windows/mutex.cc b/cpp/platform/impl/windows/mutex.cc deleted file mode 100644 index 93d40799..00000000 --- a/cpp/platform/impl/windows/mutex.cc +++ /dev/null @@ -1,51 +0,0 @@ -// 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" - -namespace location { -namespace nearby { -namespace windows { - -// A lock is a tool for controlling access to a shared resource by multiple -// threads. -// -// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/Lock.html -Mutex::Mutex(Mutex::Mode mode) : mode_(mode) {} - -void Mutex::Lock() { - if (mode_ == Mutex::Mode::kRegular || mode_ == Mutex::Mode::kRegularNoCheck) { - mutex_impl_.lock(); - } else if (mode_ == Mutex::Mode::kRecursive) { - recursive_mutex_impl_.lock(); - } -} - -void Mutex::Unlock() { - if (mode_ == Mutex::Mode::kRegular || mode_ == Mutex::Mode::kRegularNoCheck) { - mutex_impl_.unlock(); - } else if (mode_ == Mutex::Mode::kRecursive) { - recursive_mutex_impl_.unlock(); - } -} - -std::mutex& Mutex::GetWindowsMutex() { return mutex_; } - -std::recursive_mutex& Mutex::GetWindowsRecursiveMutex() { - return recursive_mutex_; -} - -} // namespace windows -} // namespace nearby -} // namespace location diff --git a/windows/core_adapter.cc b/windows/core_adapter.cc index 9f537dde..37c0939e 100644 --- a/windows/core_adapter.cc +++ b/windows/core_adapter.cc @@ -11,7 +11,6 @@ // 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 "absl/strings/str_format.h" @@ -20,11 +19,11 @@ namespace location { namespace nearby { namespace connections { -Core* InitCore(ServiceControllerRouter* router) { +DLL_API Core* InitCore(ServiceControllerRouter* router) { return new Core(router); } -void CloseCore(Core* pCore) { +DLL_API void CloseCore(Core* pCore) { if (pCore) { pCore->StopAllEndpoints( {.result_cb = @@ -34,113 +33,120 @@ void CloseCore(Core* pCore) { } } -void StartAdvertising(Core* pCore, absl::string_view service_id, - ConnectionOptions options, ConnectionRequestInfo info, - ResultCallback callback) { +DLL_API void StartAdvertising(Core* pCore, const char* service_id, + ConnectionOptions options, + ConnectionRequestInfo info, + ResultCallback callback) { if (pCore) { pCore->StartAdvertising(service_id, options, info, callback); } } -void StopAdvertising(Core* pCore, ResultCallback callback) { +DLL_API void StopAdvertising(Core* pCore, ResultCallback callback) { if (pCore) { pCore->StopAdvertising(callback); } } -void StartDiscovery(Core* pCore, absl::string_view service_id, - ConnectionOptions options, DiscoveryListener listener, - ResultCallback callback) { +DLL_API void StartDiscovery(Core* pCore, const char* service_id, + ConnectionOptions options, + DiscoveryListener listener, + ResultCallback callback) { if (pCore) { pCore->StartDiscovery(service_id, options, listener, callback); } } -void StopDiscovery(Core* pCore, ResultCallback callback) { +DLL_API void StopDiscovery(Core* pCore, ResultCallback callback) { if (pCore) { pCore->StopDiscovery(callback); } } -void InjectEndpoint(Core* pCore, absl::string_view service_id, - OutOfBandConnectionMetadata metadata, - ResultCallback callback) { +DLL_API void InjectEndpoint(Core* pCore, char* service_id, + OutOfBandConnectionMetadata metadata, + ResultCallback callback) { if (pCore) { pCore->InjectEndpoint(service_id, metadata, callback); } } -void RequestConnection(Core* pCore, absl::string_view endpoint_id, - ConnectionRequestInfo info, ConnectionOptions options, - ResultCallback callback) { +DLL_API void RequestConnection(Core* pCore, char* endpoint_id, + ConnectionRequestInfo info, + ConnectionOptions options, + ResultCallback callback) { if (pCore) { pCore->RequestConnection(endpoint_id, info, options, callback); } } -void AcceptConnection(Core* pCore, absl::string_view endpoint_id, - PayloadListener listener, ResultCallback callback) { +DLL_API void AcceptConnection(Core* pCore, char* endpoint_id, + PayloadListener listener, + ResultCallback callback) { if (pCore) { pCore->AcceptConnection(endpoint_id, listener, callback); } } -void RejectConnection(Core* pCore, absl::string_view endpoint_id, - ResultCallback callback) { +DLL_API void RejectConnection(Core* pCore, char* endpoint_id, + ResultCallback callback) { if (pCore) { pCore->RejectConnection(endpoint_id, callback); } } -void SendPayload(Core* pCore, absl::Span endpoint_ids, - Payload payload, ResultCallback callback) { +DLL_API void SendPayload(Core* pCore, + // todo(jfcarroll) this is being exported, needs to be + // refactored to return a plain old c type + absl::Span endpoint_ids, + Payload payload, ResultCallback callback) { if (pCore) { pCore->SendPayload(endpoint_ids, std::move(payload), callback); } } -void CancelPayload(Core* pCore, std::int64_t payload_id, - ResultCallback callback) { +DLL_API void CancelPayload(Core* pCore, std::int64_t payload_id, + ResultCallback callback) { if (pCore) { pCore->CancelPayload(payload_id, callback); } } -void DisconnectFromEndpoint(Core* pCore, absl::string_view endpoint_id, - ResultCallback callback) { +DLL_API void DisconnectFromEndpoint(Core* pCore, char* endpoint_id, + ResultCallback callback) { if (pCore) { pCore->DisconnectFromEndpoint(endpoint_id, callback); } } -void StopAllEndpoints(Core* pCore, ResultCallback callback) { +DLL_API void StopAllEndpoints(Core* pCore, ResultCallback callback) { if (pCore) { pCore->StopAllEndpoints(callback); } } -void InitiateBandwidthUpgrade(Core* pCore, absl::string_view endpoint_id, - ResultCallback callback) { +DLL_API void InitiateBandwidthUpgrade(Core* pCore, char* endpoint_id, + ResultCallback callback) { if (pCore) { pCore->InitiateBandwidthUpgrade(endpoint_id, callback); } } -const char* GetLocalEndpointId(Core* pCore) { +DLL_API const char* GetLocalEndpointId(Core* pCore) { if (pCore) { std::string endpoint_id = pCore->GetLocalEndpointId(); - char * result = new char[endpoint_id.length() + 1]; + char* result = new char[endpoint_id.length() + 1]; absl::SNPrintF(result, endpoint_id.length() + 1, "%s", endpoint_id); return result; } return "Null-Core"; } -ServiceControllerRouter* InitServiceControllerRouter() { +DLL_API ServiceControllerRouter* InitServiceControllerRouter() { return new ServiceControllerRouter(); } -void CloseServiceControllerRouter(ServiceControllerRouter* pRouter) { +DLL_API void CloseServiceControllerRouter(ServiceControllerRouter* pRouter) { if (pRouter) { delete pRouter; } diff --git a/windows/core_adapter.h b/windows/core_adapter.h index 22b36528..578ec470 100644 --- a/windows/core_adapter.h +++ b/windows/core_adapter.h @@ -11,12 +11,12 @@ // 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 LOCATION_NEARBY_CONNECTIONS_WINDOWS_CORE_ADAPTER_H_ #define LOCATION_NEARBY_CONNECTIONS_WINDOWS_CORE_ADAPTER_H_ #include "absl/strings/string_view.h" #include "absl/types/span.h" + #include "core/core.h" #include "core/internal/client_proxy.h" #include "core/internal/offline_service_controller.h" @@ -26,7 +26,6 @@ #include "core/options.h" #include "core/params.h" -#define DLL_API extern "C" __declspec(dllexport) namespace location { namespace nearby { namespace connections { @@ -65,8 +64,7 @@ DLL_API void __stdcall CloseCore(Core* pCore); // Status::STATUS_ALREADY_ADVERTISING if the app is already advertising. // Status::STATUS_OUT_OF_ORDER_API_CALL if the app is currently // connected to remote endpoints; call StopAllEndpoints first. -DLL_API void __stdcall StartAdvertising(Core* pCore, - absl::string_view service_id, +DLL_API void __stdcall StartAdvertising(Core* pCore, const char* service_id, ConnectionOptions options, ConnectionRequestInfo info, ResultCallback callback); @@ -94,7 +92,7 @@ DLL_API void __stdcall StopAdvertising(Core* pCore, ResultCallback callback); // discovering the specified service. // Status::STATUS_OUT_OF_ORDER_API_CALL if the app is currently // connected to remote endpoints; call StopAllEndpoints first. -DLL_API void __stdcall StartDiscovery(Core* pCore, absl::string_view service_id, +DLL_API void __stdcall StartDiscovery(Core* pCore, const char* service_id, ConnectionOptions options, DiscoveryListener listener, ResultCallback callback); @@ -124,7 +122,7 @@ DLL_API void __stdcall StopDiscovery(Core* pCore, ResultCallback callback); // Status::kError if endpoint_id, endpoint_info, or // remote_bluetooth_mac_address are malformed. // Status::kOutOfOrderApiCall if the app is not discovering. -DLL_API void __stdcall InjectEndpoint(Core* pCore, absl::string_view service_id, +DLL_API void __stdcall InjectEndpoint(Core* pCore, char* service_id, OutOfBandConnectionMetadata metadata, ResultCallback callback); @@ -147,8 +145,7 @@ DLL_API void __stdcall InjectEndpoint(Core* pCore, absl::string_view service_id, // Status::STATUS_RADIO_ERROR if we failed to connect because of an // issue with Bluetooth/WiFi. // Status::STATUS_ERROR if we failed to connect for any other reason. -DLL_API void __stdcall RequestConnection(Core* pCore, - absl::string_view endpoint_id, +DLL_API void __stdcall RequestConnection(Core* pCore, char* endpoint_id, ConnectionRequestInfo info, ConnectionOptions options, ResultCallback callback); @@ -165,8 +162,7 @@ DLL_API void __stdcall RequestConnection(Core* pCore, // Status::STATUS_OK if the connection request was accepted. // Status::STATUS_ALREADY_CONNECTED_TO_ENDPOINT if the app already. // has a connection to the specified endpoint. -DLL_API void __stdcall AcceptConnection(Core* pCore, - absl::string_view endpoint_id, +DLL_API void __stdcall AcceptConnection(Core* pCore, char* endpoint_id, PayloadListener listener, ResultCallback callback); @@ -180,8 +176,7 @@ DLL_API void __stdcall AcceptConnection(Core* pCore, // Status::STATUS_OK} if the connection request was rejected. // Status::STATUS_ALREADY_CONNECTED_TO_ENDPOINT} if the app already // has a connection to the specified endpoint. -DLL_API void __stdcall RejectConnection(Core* pCore, - absl::string_view endpoint_id, +DLL_API void __stdcall RejectConnection(Core* pCore, char* endpoint_id, ResultCallback callback); // Sends a Payload to a remote endpoint. Payloads can only be sent to remote @@ -213,7 +208,7 @@ DLL_API void __stdcall SendPayload(Core* pCore, // result_cb - to access the status of the operation when available. // Possible status codes include: // Status::STATUS_OK if none of the above errors occurred. -DLL_API void __stdcall CancelPayload(Core* pCore, std::int64_t payload_id, +DLL_API void __stdcall CancelPayload(Core* pCore, int64_t payload_id, ResultCallback callback); // Disconnects from a remote endpoint. {@link Payload}s can no longer be sent @@ -223,8 +218,7 @@ DLL_API void __stdcall CancelPayload(Core* pCore, std::int64_t payload_id, // result_cb - to access the status of the operation when available. // Possible status codes include: // Status::STATUS_OK - finished successfully. -DLL_API void __stdcall DisconnectFromEndpoint(Core* pCore, - absl::string_view endpoint_id, +DLL_API void __stdcall DisconnectFromEndpoint(Core* pCore, char* endpoint_id, ResultCallback callback); // Disconnects from, and removes all traces of, all connected and/or @@ -247,8 +241,7 @@ DLL_API void __stdcall StopAllEndpoints(Core* pCore, ResultCallback callback); // result_cb - to access the status of the operation when available. // Possible status codes include: // Status::STATUS_OK - finished successfully. -DLL_API void __stdcall InitiateBandwidthUpgrade(Core* pCore, - absl::string_view endpoint_id, +DLL_API void __stdcall InitiateBandwidthUpgrade(Core* pCore, char* endpoint_id, ResultCallback callback); // Gets the local endpoint generated by Nearby Connections. @@ -262,8 +255,8 @@ DLL_API ServiceControllerRouter* __stdcall InitServiceControllerRouter(); // Close a ServiceControllerRouter instance. DLL_API void __stdcall CloseServiceControllerRouter( ServiceControllerRouter* pRouter); + } // namespace connections } // namespace nearby } // namespace location - #endif // LOCATION_NEARBY_CONNECTIONS_WINDOWS_CORE_ADAPTER_H_