diff --git a/cpp/core/internal/base_pcp_handler.cc b/cpp/core/internal/base_pcp_handler.cc index 1cddd548..d8b78697 100644 --- a/cpp/core/internal/base_pcp_handler.cc +++ b/cpp/core/internal/base_pcp_handler.cc @@ -233,6 +233,8 @@ EncryptionRunner::ResultListener BasePcpHandler::GetResultListener() { .on_failure_cb = [this](const std::string& endpoint_id, EndpointChannel* channel) { RunOnPcpHandlerThread([this, endpoint_id, channel]() { + NEARBY_LOG(ERROR, "Encryption failed for %s on medium %d", + endpoint_id.c_str(), channel->GetMedium()); OnEncryptionFailureRunnable(endpoint_id, channel); }); }, @@ -563,12 +565,15 @@ void BasePcpHandler::ProcessPreConnectionInitiationFailure( channel->Close(); } - pending_connections_.erase(endpoint_id); - if (result != nullptr) { NEARBY_LOG(INFO, "Connection failed; aborting future"); result->Set(status); } + + // result is hold inside a swapper, and saved in PendingConnectionInfo. + // PendingConnectionInfo destructor will clear the memory of SettableFuture + // shared_ptr for result. + pending_connections_.erase(endpoint_id); } void BasePcpHandler::ProcessPreConnectionResultFailure( diff --git a/cpp/platform/base/BUILD b/cpp/platform/base/BUILD index 48225e1a..ac91f09a 100644 --- a/cpp/platform/base/BUILD +++ b/cpp/platform/base/BUILD @@ -27,6 +27,7 @@ cc_library( "byte_array.h", "callable.h", "exception.h", + "feature_flags.h", "input_stream.h", "listeners.h", "nsd_service_info.h", @@ -48,6 +49,7 @@ cc_library( "//absl/meta:type_traits", "//absl/strings", "//absl/strings:str_format", + "//absl/synchronization", "//absl/time", ], ) @@ -145,10 +147,13 @@ cc_test( srcs = [ "bluetooth_utils_test.cc", "byte_array_test.cc", + "feature_flags_test.cc", "prng_test.cc", ], deps = [ ":base", + ":test_util", + "//platform/impl/g3", # build_cleaner: keep "//testing/base/public:gunit_main", ], ) diff --git a/cpp/platform/base/feature_flags.h b/cpp/platform/base/feature_flags.h new file mode 100644 index 00000000..f42e4210 --- /dev/null +++ b/cpp/platform/base/feature_flags.h @@ -0,0 +1,44 @@ +#ifndef PLATFORM_BASE_FEATURE_FLAGS_H_ +#define PLATFORM_BASE_FEATURE_FLAGS_H_ + +#include "absl/synchronization/mutex.h" + +namespace location { +namespace nearby { + +// Global flags that control feature availability. This may be used to gating +// features in development, QA testing and releasing. +class FeatureFlags { + public: + // Holds for all the feature flags. + struct Flags { + bool enable_cancellation_flags = false; + }; + + static const FeatureFlags& GetInstance() { + static const FeatureFlags* instance = new FeatureFlags(); + return *instance; + } + + const Flags& GetFlags() const ABSL_LOCKS_EXCLUDED(mutex_) { + absl::ReaderMutexLock lock(&mutex_); + return flags_; + } + + private: + FeatureFlags() = default; + + // MediumEnvironment is testing uitl class. Use friend class here to enable + // SetFlags for feature controlling need in test environment. + friend class MediumEnvironment; + void SetFlags(const Flags& flags) ABSL_LOCKS_EXCLUDED(mutex_) { + absl::MutexLock lock(&mutex_); + flags_ = flags; + } + Flags flags_ ABSL_GUARDED_BY(mutex_); + mutable absl::Mutex mutex_; +}; +} // namespace nearby +} // namespace location + +#endif // PLATFORM_BASE_FEATURE_FLAGS_H_ diff --git a/cpp/platform/base/feature_flags_test.cc b/cpp/platform/base/feature_flags_test.cc new file mode 100644 index 00000000..dbe4b4a1 --- /dev/null +++ b/cpp/platform/base/feature_flags_test.cc @@ -0,0 +1,26 @@ +#include "platform/base/feature_flags.h" + +#include "platform/base/medium_environment.h" +#include "gtest/gtest.h" + +namespace location { +namespace nearby { +namespace { + +FeatureFlags::Flags kTestFeatureFlags{.enable_cancellation_flags = true}; + +TEST(FeatureFlagsTest, ToStringWorks) { + const FeatureFlags& features = FeatureFlags::GetInstance(); + EXPECT_FALSE(features.GetFlags().enable_cancellation_flags); + + MediumEnvironment& medium_environment = MediumEnvironment::Instance(); + medium_environment.SetFeatureFlags(kTestFeatureFlags); + EXPECT_TRUE(features.GetFlags().enable_cancellation_flags); + + const FeatureFlags& another_features_ref = FeatureFlags::GetInstance(); + EXPECT_TRUE(another_features_ref.GetFlags().enable_cancellation_flags); +} + +} // namespace +} // namespace nearby +} // namespace location diff --git a/cpp/platform/base/medium_environment.cc b/cpp/platform/base/medium_environment.cc index 219c4503..497007cb 100644 --- a/cpp/platform/base/medium_environment.cc +++ b/cpp/platform/base/medium_environment.cc @@ -23,6 +23,7 @@ #include "platform/api/bluetooth_adapter.h" #include "platform/api/bluetooth_classic.h" #include "platform/api/wifi_lan.h" +#include "platform/base/feature_flags.h" #include "platform/base/logging.h" #include "platform/public/count_down_latch.h" @@ -199,19 +200,19 @@ void MediumEnvironment::OnBlePeripheralStateChanged( &peripheral, &info, service_id.c_str(), enable_notifications_.load()); if (!enable_notifications_) return; - RunOnMediumEnvironmentThread([&info, enabled, &peripheral, service_id, - fast_advertisement]() { - NEARBY_LOG(INFO, - "G3 [Run] OnBlePeripheralStateChanged [peripheral impl=%p]; " - "context=%p; service_id=%s; enabled=%d", - &peripheral, &info, service_id.c_str(), enabled); - if (enabled) { - info.discovery_callback.peripheral_discovered_cb(peripheral, service_id, - fast_advertisement); - } else { - info.discovery_callback.peripheral_lost_cb(peripheral, service_id); - } - }); + RunOnMediumEnvironmentThread( + [&info, enabled, &peripheral, service_id, fast_advertisement]() { + NEARBY_LOG(INFO, + "G3 [Run] OnBlePeripheralStateChanged [peripheral impl=%p]; " + "context=%p; service_id=%s; enabled=%d", + &peripheral, &info, service_id.c_str(), enabled); + if (enabled) { + info.discovery_callback.peripheral_discovered_cb( + peripheral, service_id, fast_advertisement); + } else { + info.discovery_callback.peripheral_lost_cb(peripheral, service_id); + } + }); } void MediumEnvironment::OnWifiLanServiceStateChanged( @@ -225,24 +226,24 @@ void MediumEnvironment::OnWifiLanServiceStateChanged( &wifi_lan_service, &info, service_id.c_str(), enable_notifications_.load()); if (!enable_notifications_) return; - RunOnMediumEnvironmentThread([&info, enabled, &wifi_lan_service, - service_id]() { - NEARBY_LOG( - INFO, - "G3 [Run] OnWifiLanServiceStateChanged [wifi_lan_service impl=%p]; " - "context=%p; service_id=%s; enabled=%d", - &wifi_lan_service, &info, service_id.c_str(), enabled); - auto service_id_context = info.services.find(service_id); - if (service_id_context == info.services.end()) return; + RunOnMediumEnvironmentThread( + [&info, enabled, &wifi_lan_service, service_id]() { + NEARBY_LOG( + INFO, + "G3 [Run] OnWifiLanServiceStateChanged [wifi_lan_service impl=%p]; " + "context=%p; service_id=%s; enabled=%d", + &wifi_lan_service, &info, service_id.c_str(), enabled); + auto service_id_context = info.services.find(service_id); + if (service_id_context == info.services.end()) return; - if (enabled) { - service_id_context->second.discovery_callback.service_discovered_cb( - wifi_lan_service, service_id); - } else { - service_id_context->second.discovery_callback.service_lost_cb( - wifi_lan_service, service_id); - } - }); + if (enabled) { + service_id_context->second.discovery_callback.service_discovered_cb( + wifi_lan_service, service_id); + } else { + service_id_context->second.discovery_callback.service_lost_cb( + wifi_lan_service, service_id); + } + }); } void MediumEnvironment::RunOnMediumEnvironmentThread( @@ -324,34 +325,33 @@ void MediumEnvironment::UpdateBleMediumForAdvertising( api::BleMedium& medium, api::BlePeripheral& peripheral, const std::string& service_id, bool fast_advertisement, bool enabled) { if (!enabled_) return; - RunOnMediumEnvironmentThread( - [this, &medium, &peripheral, service_id, fast_advertisement, enabled]() { - auto item = ble_mediums_.find(&medium); - if (item == ble_mediums_.end()) { - NEARBY_LOG(INFO, - "UpdateBleMediumForAdvertising failed. There is no medium " - "registered."); - return; - } - auto& context = item->second; - context.ble_peripheral = &peripheral; - context.advertising = enabled; - context.fast_advertisement = fast_advertisement; - NEARBY_LOG( - INFO, - "Update Ble medium for advertising: this=%p; medium=%p; " - "service_id=%s; name=%s; fast_advertisement=%d; enabled=%d; ", - this, &medium, service_id.c_str(), peripheral.GetName().c_str(), - fast_advertisement, enabled); - for (auto& medium_info : ble_mediums_) { - auto& local_medium = medium_info.first; - auto& info = medium_info.second; - // Do not send notification to the same medium. - if (local_medium == &medium) continue; - OnBlePeripheralStateChanged(info, peripheral, service_id, - fast_advertisement, enabled); - } - }); + RunOnMediumEnvironmentThread([this, &medium, &peripheral, service_id, + fast_advertisement, enabled]() { + auto item = ble_mediums_.find(&medium); + if (item == ble_mediums_.end()) { + NEARBY_LOG(INFO, + "UpdateBleMediumForAdvertising failed. There is no medium " + "registered."); + return; + } + auto& context = item->second; + context.ble_peripheral = &peripheral; + context.advertising = enabled; + context.fast_advertisement = fast_advertisement; + NEARBY_LOG(INFO, + "Update Ble medium for advertising: this=%p; medium=%p; " + "service_id=%s; name=%s; fast_advertisement=%d; enabled=%d; ", + this, &medium, service_id.c_str(), peripheral.GetName().c_str(), + fast_advertisement, enabled); + for (auto& medium_info : ble_mediums_) { + auto& local_medium = medium_info.first; + auto& info = medium_info.second; + // Do not send notification to the same medium. + if (local_medium == &medium) continue; + OnBlePeripheralStateChanged(info, peripheral, service_id, + fast_advertisement, enabled); + } + }); } void MediumEnvironment::UpdateBleMediumForScanning( @@ -359,37 +359,36 @@ void MediumEnvironment::UpdateBleMediumForScanning( const std::string& fast_advertisement_service_uuid, BleDiscoveredPeripheralCallback callback, bool enabled) { if (!enabled_) return; - RunOnMediumEnvironmentThread( - [this, &medium, service_id, fast_advertisement_service_uuid, - callback = std::move(callback), enabled]() { - auto item = ble_mediums_.find(&medium); - if (item == ble_mediums_.end()) { - NEARBY_LOG(INFO, - "UpdateBleMediumFoScanning failed. There is no medium " - "registered."); - return; - } - auto& context = item->second; - context.discovery_callback = std::move(callback); - NEARBY_LOG( - INFO, - "Update Ble medium for scanning: this=%p; medium=%p; " - "service_id=%s; fast_advertisement_service_uuid=%s; enabled=%d ;", - this, &medium, service_id.c_str(), - fast_advertisement_service_uuid.c_str(), enabled); - for (auto& medium_info : ble_mediums_) { - auto& local_medium = medium_info.first; - auto& info = medium_info.second; - // Do not send notification to the same medium. - if (local_medium == &medium) continue; - // Search advertising mediums and send notification. - if (info.advertising && enabled) { - OnBlePeripheralStateChanged(context, *(info.ble_peripheral), - service_id, info.fast_advertisement, - enabled); - } - } - }); + RunOnMediumEnvironmentThread([this, &medium, service_id, + fast_advertisement_service_uuid, + callback = std::move(callback), enabled]() { + auto item = ble_mediums_.find(&medium); + if (item == ble_mediums_.end()) { + NEARBY_LOG(INFO, + "UpdateBleMediumFoScanning failed. There is no medium " + "registered."); + return; + } + auto& context = item->second; + context.discovery_callback = std::move(callback); + NEARBY_LOG( + INFO, + "Update Ble medium for scanning: this=%p; medium=%p; " + "service_id=%s; fast_advertisement_service_uuid=%s; enabled=%d ;", + this, &medium, service_id.c_str(), + fast_advertisement_service_uuid.c_str(), enabled); + for (auto& medium_info : ble_mediums_) { + auto& local_medium = medium_info.first; + auto& info = medium_info.second; + // Do not send notification to the same medium. + if (local_medium == &medium) continue; + // Search advertising mediums and send notification. + if (info.advertising && enabled) { + OnBlePeripheralStateChanged(context, *(info.ble_peripheral), service_id, + info.fast_advertisement, enabled); + } + } + }); } void MediumEnvironment::UpdateBleMediumForAcceptedConnection( @@ -644,23 +643,26 @@ api::WifiLanService* MediumEnvironment::GetWifiLanService( const std::string& ip_address, int port) { api::WifiLanService* remote_wifi_lan_service = nullptr; CountDownLatch latch(1); - RunOnMediumEnvironmentThread( - [this, &remote_wifi_lan_service, &ip_address, port, &latch]() { - for (auto& item : wifi_lan_mediums_) { - auto* wifi_lan_service = item.second.wifi_lan_service; - if (!wifi_lan_service) continue; - auto addr = - remote_wifi_lan_service->GetServiceInfo().GetServiceAddress(); - if (addr.first == ip_address && addr.second == port) { - remote_wifi_lan_service = wifi_lan_service; - break; - } - } - latch.CountDown(); - }); + RunOnMediumEnvironmentThread([this, &remote_wifi_lan_service, &ip_address, + port, &latch]() { + for (auto& item : wifi_lan_mediums_) { + auto* wifi_lan_service = item.second.wifi_lan_service; + if (!wifi_lan_service) continue; + auto addr = remote_wifi_lan_service->GetServiceInfo().GetServiceAddress(); + if (addr.first == ip_address && addr.second == port) { + remote_wifi_lan_service = wifi_lan_service; + break; + } + } + latch.CountDown(); + }); latch.Await(); return remote_wifi_lan_service; } +void MediumEnvironment::SetFeatureFlags(const FeatureFlags::Flags& flags) { + const_cast(FeatureFlags::GetInstance()).SetFlags(flags); +} + } // namespace nearby } // namespace location diff --git a/cpp/platform/base/medium_environment.h b/cpp/platform/base/medium_environment.h index b511ca11..e215bffc 100644 --- a/cpp/platform/base/medium_environment.h +++ b/cpp/platform/base/medium_environment.h @@ -21,6 +21,7 @@ #include "platform/api/bluetooth_classic.h" #include "platform/api/webrtc.h" #include "platform/base/byte_array.h" +#include "platform/base/feature_flags.h" #include "platform/base/listeners.h" #include "platform/base/nsd_service_info.h" #include "platform/public/single_thread_executor.h" @@ -230,6 +231,8 @@ class MediumEnvironment { api::WifiLanService* GetWifiLanService(const std::string& ip_address, int port); + void SetFeatureFlags(const FeatureFlags::Flags& flags); + private: struct BluetoothMediumContext { BluetoothDiscoveryCallback callback; diff --git a/proto/BUILD b/proto/BUILD index 87d2bd6d..880147c8 100644 --- a/proto/BUILD +++ b/proto/BUILD @@ -124,6 +124,11 @@ proto_library( ], ) +java_proto_library( + name = "nearby_client_enums_java_proto", + deps = [":nearby_client_enums_proto"], +) + java_lite_proto_library( name = "nearby_client_enums_java_proto_lite", deps = [":nearby_client_enums_proto"],