From 8725391822b8901784b379a4573ab8828e7091d3 Mon Sep 17 00:00:00 2001 From: hai007 Date: Sun, 3 Sep 2023 19:11:35 -0700 Subject: [PATCH 001/683] [Sharing] add EstablishConection log on receiver side. PiperOrigin-RevId: 562424397 --- proto/sharing_enums.proto | 1 + 1 file changed, 1 insertion(+) diff --git a/proto/sharing_enums.proto b/proto/sharing_enums.proto index 89a8faf2..8a8a85cd 100644 --- a/proto/sharing_enums.proto +++ b/proto/sharing_enums.proto @@ -289,6 +289,7 @@ enum EstablishConnectionStatus { CONNECTION_STATUS_FAILED_NULL_CONNECTION = 7; CONNECTION_STATUS_FAILED_NO_TRANSFER_UPDATE_CALLBACK = 8; CONNECTION_STATUS_LOST_CONNECTIVITY = 9; + CONNECTION_STATUS_INVALID_ADVERTISEMENT = 10; } // The status of sending and receiving attachments. Used by SEND_ATTACHMENTS. From 197d3f84766dfc39b2486505126dd17174d3e663 Mon Sep 17 00:00:00 2001 From: Nick Bourdakos Date: Wed, 6 Sep 2023 12:37:42 -0700 Subject: [PATCH 002/683] Fix weave bug for payloads that exceed the maximum write length PiperOrigin-RevId: 563185164 --- .../platform/implementation/apple/Mediums/Ble/Sockets/BUILD | 2 -- .../Ble/Sockets/Source/Central/GNSCentralPeerManager.m | 6 +++++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/internal/platform/implementation/apple/Mediums/Ble/Sockets/BUILD b/internal/platform/implementation/apple/Mediums/Ble/Sockets/BUILD index 255b6a1b..a4154f22 100644 --- a/internal/platform/implementation/apple/Mediums/Ble/Sockets/BUILD +++ b/internal/platform/implementation/apple/Mediums/Ble/Sockets/BUILD @@ -32,9 +32,7 @@ objc_library( deps = [ ":Shared", "//third_party/apple_frameworks:CoreBluetooth", - "//third_party/apple_frameworks:CoreFoundation", "//third_party/apple_frameworks:Foundation", - "//third_party/apple_frameworks:QuartzCore", "//third_party/objective_c/google_toolbox_for_mac:GTM_Logger", ], ) diff --git a/internal/platform/implementation/apple/Mediums/Ble/Sockets/Source/Central/GNSCentralPeerManager.m b/internal/platform/implementation/apple/Mediums/Ble/Sockets/Source/Central/GNSCentralPeerManager.m index e53475b8..4e481a3c 100644 --- a/internal/platform/implementation/apple/Mediums/Ble/Sockets/Source/Central/GNSCentralPeerManager.m +++ b/internal/platform/implementation/apple/Mediums/Ble/Sockets/Source/Central/GNSCentralPeerManager.m @@ -728,7 +728,11 @@ static NSString *PeripheralStateString(CBPeripheralState state) { packet.version); [_connectionConfirmTimer invalidate]; _connectionConfirmTimer = nil; - _socket.packetSize = packet.packetSize; + // Weave is using `CBCharacteristicWriteWithResponse` for writes, so we must query max value since + // it can have a smaller value than the `GNSWeaveConnectionConfirmPacket` size. + NSUInteger maxWriteLength = + [_socket.peerAsPeripheral maximumWriteValueLengthForType:CBCharacteristicWriteWithResponse]; + _socket.packetSize = MIN(packet.packetSize, maxWriteLength); [_socket didConnect]; if (packet.data) { // According to the Weave BLE protocol the data received during the connection handshake should From 981ad214cdae0de7c1443a3bb9a8f2408058ab9c Mon Sep 17 00:00:00 2001 From: Nick Bourdakos Date: Wed, 6 Sep 2023 13:39:11 -0700 Subject: [PATCH 003/683] Add BLEv2 as an option for `point-to-point` and `star` strategies (currently this is only supported by `cluster`) PiperOrigin-RevId: 563202701 --- connections/implementation/BUILD | 2 -- .../p2p_point_to_point_pcp_handler.cc | 14 ++++++++++++-- connections/implementation/p2p_star_pcp_handler.cc | 13 +++++++++++-- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/connections/implementation/BUILD b/connections/implementation/BUILD index 649b57f2..73c38704 100644 --- a/connections/implementation/BUILD +++ b/connections/implementation/BUILD @@ -130,7 +130,6 @@ cc_library( "//internal/platform:util", "//internal/platform/implementation:comm", "//internal/platform/implementation:platform", - "//internal/platform/implementation/shared:file", "//internal/proto/analytics:connections_log_cc_proto", "//proto:connections_enums_cc_proto", "@com_google_absl//absl/base:core_headers", @@ -139,7 +138,6 @@ cc_library( "@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/functional:bind_front", - "@com_google_absl//absl/log:check", "@com_google_absl//absl/memory", "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", diff --git a/connections/implementation/p2p_point_to_point_pcp_handler.cc b/connections/implementation/p2p_point_to_point_pcp_handler.cc index 1aa15b79..e6614b25 100644 --- a/connections/implementation/p2p_point_to_point_pcp_handler.cc +++ b/connections/implementation/p2p_point_to_point_pcp_handler.cc @@ -16,6 +16,9 @@ #include +#include "connections/implementation/flags/nearby_connections_feature_flags.h" +#include "internal/flags/nearby_flags.h" + namespace nearby { namespace connections { @@ -46,8 +49,15 @@ P2pPointToPointPcpHandler::GetConnectionMediumsByPriority() { if (mediums_->GetBluetoothClassic().IsAvailable()) { mediums.push_back(location::nearby::proto::connections::BLUETOOTH); } - if (mediums_->GetBle().IsAvailable()) { - mediums.push_back(location::nearby::proto::connections::BLE); + if (NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_connections_feature::kEnableBleV2)) { + if (mediums_->GetBleV2().IsAvailable()) { + mediums.push_back(location::nearby::proto::connections::BLE); + } + } else { + if (mediums_->GetBle().IsAvailable()) { + mediums.push_back(location::nearby::proto::connections::BLE); + } } return mediums; } diff --git a/connections/implementation/p2p_star_pcp_handler.cc b/connections/implementation/p2p_star_pcp_handler.cc index 2af6f0ad..0582cc28 100644 --- a/connections/implementation/p2p_star_pcp_handler.cc +++ b/connections/implementation/p2p_star_pcp_handler.cc @@ -16,6 +16,8 @@ #include +#include "connections/implementation/flags/nearby_connections_feature_flags.h" +#include "internal/flags/nearby_flags.h" #include "internal/platform/logging.h" namespace nearby { @@ -49,8 +51,15 @@ P2pStarPcpHandler::GetConnectionMediumsByPriority() { if (mediums_->GetBluetoothClassic().IsAvailable()) { mediums.push_back(location::nearby::proto::connections::BLUETOOTH); } - if (mediums_->GetBle().IsAvailable()) { - mediums.push_back(location::nearby::proto::connections::BLE); + if (NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_connections_feature::kEnableBleV2)) { + if (mediums_->GetBleV2().IsAvailable()) { + mediums.push_back(location::nearby::proto::connections::BLE); + } + } else { + if (mediums_->GetBle().IsAvailable()) { + mediums.push_back(location::nearby::proto::connections::BLE); + } } return mediums; } From e186ef62326159e88b22cd77125382ba4ee50547 Mon Sep 17 00:00:00 2001 From: hai007 Date: Wed, 6 Sep 2023 20:49:29 +0000 Subject: [PATCH 004/683] Internal refactor PiperOrigin-RevId: 563205643 --- presence/proto/presence_frame.proto | 1 + 1 file changed, 1 insertion(+) diff --git a/presence/proto/presence_frame.proto b/presence/proto/presence_frame.proto index 5b4ba2ff..0ebb96a2 100644 --- a/presence/proto/presence_frame.proto +++ b/presence/proto/presence_frame.proto @@ -120,6 +120,7 @@ message UwbControleeCapabilities { repeated int32 supported_ranging_update_rates = 16 [packed = true]; optional int32 chip_count = 17 [default = 1]; repeated UwbMultiChipInfo multi_chip_info = 18; + optional bool is_background_ranging_supported = 19 [default = false]; } /* A frame containing info needed per chip in a multi-chip environment. */ From fcee99d7ee7a831a3f3e22bb2601af0137dd5e60 Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Wed, 6 Sep 2023 19:06:25 -0700 Subject: [PATCH 005/683] Added MacOS into OS type PiperOrigin-RevId: 563279974 --- proto/sharing_enums.proto | 1 + 1 file changed, 1 insertion(+) diff --git a/proto/sharing_enums.proto b/proto/sharing_enums.proto index 8a8a85cd..ce06d0da 100644 --- a/proto/sharing_enums.proto +++ b/proto/sharing_enums.proto @@ -448,6 +448,7 @@ enum OSType { CHROME_OS = 2; IOS = 3; WINDOWS = 4; + MACOS = 5; } // Relationship of remote device to sender device. From c51830a97f0e67168bf2fbc0ff9e59ada8ac2b00 Mon Sep 17 00:00:00 2001 From: hai007 Date: Wed, 6 Sep 2023 21:31:21 -0700 Subject: [PATCH 006/683] Port Intel PIE DLL, so we can query and control Intel WIFI directly PiperOrigin-RevId: 563303511 --- .../platform/implementation/windows/BUILD | 3 + .../implementation/windows/generated/BUILD | 1 + .../implementation/windows/wifi_intel.cc | 576 ++++++++++++++++++ .../implementation/windows/wifi_intel.h | 64 ++ 4 files changed, 644 insertions(+) create mode 100644 internal/platform/implementation/windows/wifi_intel.cc create mode 100644 internal/platform/implementation/windows/wifi_intel.h diff --git a/internal/platform/implementation/windows/BUILD b/internal/platform/implementation/windows/BUILD index 8f615664..218b43de 100644 --- a/internal/platform/implementation/windows/BUILD +++ b/internal/platform/implementation/windows/BUILD @@ -102,6 +102,7 @@ cc_library( "wifi.h", "wifi_direct.h", "wifi_hotspot.h", + "wifi_intel.h", "wifi_lan.h", ], visibility = ["//visibility:private"], @@ -113,6 +114,7 @@ cc_library( "//internal/platform/implementation:comm", "//internal/platform/implementation:types", "//internal/platform/implementation/windows/generated:types", + "//third_party/intel/pie", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/container:flat_hash_set", @@ -179,6 +181,7 @@ cc_library( "wifi_hotspot_medium.cc", "wifi_hotspot_server_socket.cc", "wifi_hotspot_socket.cc", + "wifi_intel.cc", "wifi_lan_medium.cc", "wifi_lan_server_socket.cc", "wifi_lan_socket.cc", diff --git a/internal/platform/implementation/windows/generated/BUILD b/internal/platform/implementation/windows/generated/BUILD index 39e0a2b2..ae01ef37 100644 --- a/internal/platform/implementation/windows/generated/BUILD +++ b/internal/platform/implementation/windows/generated/BUILD @@ -19,6 +19,7 @@ cc_library( "wininet.lib", "advapi32.lib", "bcrypt.lib", + "cfgmgr32.lib", "comdlg32.lib", "gdi32.lib", "kernel32.lib", diff --git a/internal/platform/implementation/windows/wifi_intel.cc b/internal/platform/implementation/windows/wifi_intel.cc new file mode 100644 index 00000000..800b37bc --- /dev/null +++ b/internal/platform/implementation/windows/wifi_intel.cc @@ -0,0 +1,576 @@ +// Copyright 2022 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 "internal/platform/implementation/windows/wifi_intel.h" + +// clang-format off +#include // NOLINT +#include +#include +#include +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include +// clang-format on + +#include +#include +#include +#include +#include + +#include "absl/strings/str_format.h" +#include "third_party/intel/pie/include/PieApiTypes.h" +#include "third_party/intel/pie/include/PieDefinitions.h" +#include "third_party/intel/pie/include/PieErrorMacro.h" +#include "internal/platform/logging.h" + +namespace nearby { +namespace windows { +namespace { + +#define SAFEDELETE(x) \ + { \ + try { \ + if (x) { \ + delete x; \ + x = nullptr; \ + } \ + } catch (...) { \ + NEARBY_LOGS(INFO) << absl::StrFormat( \ + "Exception while delete memory at 0x%p ", (void*)x); \ + } \ + } + +#define SAFEDELETEARRAY(x) \ + { \ + try { \ + if (x) { \ + delete[] x; \ + x = nullptr; \ + } \ + } catch (...) { \ + NEARBY_LOGS(INFO) << absl::StrFormat( \ + "Exception while delete memory at 0x%p ", (void*)x); \ + } \ + } + +#define SAFEFREELIBRARY(x) \ + { \ + try { \ + if (x) { \ + FreeLibrary(x); \ + x = nullptr; \ + } \ + } catch (...) { \ + NEARBY_LOGS(INFO) << absl::StrFormat( \ + "Exception while freeing library at 0x%p ", (void*)x); \ + } \ + } + +#define PIE_API_DLL L"\\MurocApi.dll" +#define ERROR_ +const wchar_t PIE_HW_ID_[] = L"SWC\\VID_8086&PID_PIE&SID_0001\0"; +const wchar_t PIE_DLL_PATH_HINT[] = L"PiePathHint"; +} // namespace + +typedef MUROC_RET(APIENTRY* WIFIGETADAPTERLIST)( // NOLINT + PINTEL_WIFI_HEADER pHeader, void** pAdapterList); +typedef MUROC_RET(APIENTRY* REGISTERINTELCB)( + MurocDefs::PINTEL_CALLBACK pIntelCallback); +typedef MUROC_RET(APIENTRY* GETRADIOSTATE)(HADAPTER hAdapter, bool* bEnabled); +typedef MUROC_RET(APIENTRY* WIFIPANQUERYPREFFEDCHANNELSETTING)( + HADAPTER hAdapter, PINTEL_WIFI_HEADER pHeader, + void* pOutQueryPreferredChannel); +typedef MUROC_RET(APIENTRY* DEREGISTERINTELCB)( + MurocDefs::INTEL_EVENT_CALLBACK fnCallbac); +typedef MUROC_RET(APIENTRY* FREELISTMEMORY)(void* pList); + +// Forward declarations of the internal private functions +wchar_t* GetEntireRegistryDeviceList(); +bool IsHwIdMatching(DEVINST devInst, const wchar_t* expecedHwId); +DEVINST SearchForDeviceInstance(wchar_t* pEntireDeviceList); +void CloseRegKeyHandle(HKEY softwareKey); // NOLINT +void OpenRegKeyHandle(DEVINST devInst, HKEY& softwareKey); +DWORD GetRegKeyWCHARValue(DEVINST deviceInstance, LPCWSTR keyName, // NOLINT + wchar_t* valOut, PDWORD pValLen, // NOLINT + PDWORD pDataType); // NOLINT +DWORD GetFullDllLoadPathFromPieRegistry(DEVINST pieDeviceInstance, + PWCHAR* ppDllPathValue); // NOLINT +HADAPTER WifiGetAdapterList(HINSTANCE murocApiDllHandle, // NOLINT + PINTEL_ADAPTER_LIST_V120* ppAllAdapters); +void RegisterIntelCallback(HINSTANCE murocApiDllHandle, + MurocDefs::PINTEL_CALLBACK pIntelEventCbHandle); +void DeregisterIntelCallback(HINSTANCE murocApiDllHandle, + MurocDefs::INTEL_EVENT_CALLBACK fnCallback); +void FreeMemoryList(HINSTANCE murocApiDllHandle, void* ptr); + +void WINAPI IntelEventHandler(MurocDefs::INTEL_EVENT iEvent, // NOLINT + void* pContext); +// g_intel_event_cb_handle must be the address of a global and not on the stack +// because the CB comes from another thread +MurocDefs::INTEL_CALLBACK g_intel_event_cb_handle = {IntelEventHandler, + nullptr}; + +WifiIntel& WifiIntel::GetInstance() { + static std::aligned_storage_t storage; + static WifiIntel* instance = new (&storage) WifiIntel(); + return *instance; +} + +void WifiIntel::Start() { + NEARBY_LOGS(INFO) << "WifiIntel::Start()"; + muroc_api_dll_handle_ = PIEDllLoader(); + if ((muroc_api_dll_handle_ != nullptr)) { + NEARBY_LOGS(INFO) << "Load PIE_API_DLL completed successfully"; + + wifi_adapter_handle_ = + WifiGetAdapterList(muroc_api_dll_handle_, &p_all_adapters_); + if (wifi_adapter_handle_ != INVALID_HADAPTER) { + intel_wifi_valid_ = true; + RegisterIntelCallback(muroc_api_dll_handle_, &g_intel_event_cb_handle); + } else { + SAFEFREELIBRARY(muroc_api_dll_handle_); + } + } +} + +void WifiIntel::Stop() { + NEARBY_LOGS(INFO) << "WifiIntel::Stop()"; + if (intel_wifi_valid_) { + NEARBY_LOGS(INFO) << "Deregister Intel Callback, free Adapters Memory " + "List, free Muroc Api Dll handler."; + DeregisterIntelCallback(muroc_api_dll_handle_, IntelEventHandler); + FreeMemoryList(muroc_api_dll_handle_, p_all_adapters_); + SAFEFREELIBRARY(muroc_api_dll_handle_); + } +} + +uint8_t WifiIntel::GetGOChannel() { + WIFIPANQUERYPREFFEDCHANNELSETTING WifiPanQueryPreferredChannelSettingFunc = + nullptr; + uint8_t channel = 0; + DWORD dwError = ERROR_SUCCESS; // NOLINT + MUROC_RET murocApiRetVal = IWLAN_E_FAILURE; // NOLINT + INTEL_WIFI_HEADER intelWifiHeader; + MurocDefs::INTEL_GO_OPERATION_CHANNEL_SETTING intelGOChan; + + if (!intel_wifi_valid_) return channel; + + WifiPanQueryPreferredChannelSettingFunc = + (WIFIPANQUERYPREFFEDCHANNELSETTING)GetProcAddress( // NOLINT + muroc_api_dll_handle_, + "WifiPanQueryPreferredChannelSetting"); + + if (WifiPanQueryPreferredChannelSettingFunc == nullptr) { + dwError = GetLastError(); // NOLINT + NEARBY_LOGS(INFO) + << "GetProcAddress WifiPanQueryPreferredChannelSetting error: " + << dwError; + return channel; + } + NEARBY_LOGS(VERBOSE) + << "Load WifiPanQueryPreferredChannelSetting API completed successfully"; + + murocApiRetVal = WifiPanQueryPreferredChannelSettingFunc( + wifi_adapter_handle_, &intelWifiHeader, (void*)&intelGOChan); + + if (murocApiRetVal == IWLAN_E_SUCCESS) { // NOLINT + NEARBY_LOGS(INFO) + << "Calling WifiPanQueryPreferredChannelSetting API succeeded"; + if (intelGOChan.goState == MurocDefs::INTEL_GO_CURRENT_CHANNEL_ACTIVE) { + channel = intelGOChan.channel; + } else { + NEARBY_LOGS(INFO) << "No active GO found, return 0"; + } + } else { + NEARBY_LOGS(INFO) << "Calling WifiPanQueryPreferredChannelSetting API " + "failed with error: " + << murocApiRetVal; + } + + return channel; +} + +wchar_t* GetEntireRegistryDeviceList() { + CONFIGRET configRet = CR_SUCCESS; + wchar_t* pDeviceList = nullptr; + ULONG deviceListLength = 0; // NOLINT + + // retrieves the buffer size required to hold a list of device instance IDs + // for the local machine's device instances. + configRet = CM_Get_Device_ID_List_SizeW(&deviceListLength, nullptr, + CM_GETIDLIST_FILTER_PRESENT); + + if (configRet == CR_SUCCESS) { + // Allocates a block of memory from a heap.for the Devices List + pDeviceList = + (wchar_t*)new BYTE[deviceListLength * sizeof(wchar_t)]; // NOLINT + if (nullptr != pDeviceList) { + // retrieves a list of device instance IDs for the local computer's device + // instances + configRet = CM_Get_Device_ID_ListW(nullptr, pDeviceList, deviceListLength, + CM_GETIDLIST_FILTER_PRESENT); + if (configRet != CR_SUCCESS) { + NEARBY_LOGS(INFO) + << "Unexpected error! CM_Get_Device_ID_List return Value of " + << configRet; + SAFEDELETEARRAY(pDeviceList); + } + } else { + configRet = CR_OUT_OF_MEMORY; + NEARBY_LOGS(INFO) + << "Unexpected error! failed to allocate memory to the device list"; + } + } else { + NEARBY_LOGS(INFO) + << "Unexpected error! CM_Get_Device_ID_List_Size return Value of " + << configRet; + } + + return pDeviceList; +} + +bool IsHwIdMatching(DEVINST devInst, const wchar_t* expecedHwId) { + bool isHwIdFound = false; + DEVPROPTYPE propertyType = DEVPROP_TYPE_STRING_LIST; + CONFIGRET configRet; + wchar_t currentDeviceHwId[MAX_DEVICE_ID_LEN] = {0}; + ULONG propertySize; + + // Query the Hardware ID property of the device instance + propertySize = sizeof(currentDeviceHwId); + configRet = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_Device_HardwareIds, + &propertyType, (BYTE*)currentDeviceHwId, + &propertySize, 0); + if (configRet == CR_SUCCESS) { + // Compare to given HW ID + wchar_t* pdest = wcsstr(currentDeviceHwId, expecedHwId); // NOLINT + if (nullptr != pdest) { + std::wcout << "wifi_intel.cc" + << ":" << __LINE__ + << "] Intel WIFI hwId is found: " << expecedHwId << std::endl; + isHwIdFound = true; + } + } + return isHwIdFound; +} + +DEVINST SearchForDeviceInstance(wchar_t* pEntireDeviceList) { + DEVINST devInst = NULL; // NOLINT + + if (pEntireDeviceList != nullptr) { + bool isMatchingDeviceFound = false; + wchar_t* currentDevice = nullptr; + CONFIGRET configRet = CR_SUCCESS; + + // Loop - over the devices List and Find PIE device by HW ID + for (currentDevice = pEntireDeviceList; + (0 != *currentDevice) && (!isMatchingDeviceFound); + currentDevice += wcslen(currentDevice) + 1) { // NOLINT + // If the list of devices also includes non-present devices, + // CM_LOCATE_DEVNODE_PHANTOM should be used in place of + // CM_LOCATE_DEVNODE_NORMAL. + configRet = + CM_Locate_DevNodeW(&devInst, currentDevice, CM_LOCATE_DEVNODE_NORMAL); + if (configRet != CR_SUCCESS) { + NEARBY_LOGS(INFO) + << "Unexpected error! CM_Locate_DevNode return Value of " + << configRet; + devInst = NULL; + break; + } + isMatchingDeviceFound = IsHwIdMatching(devInst, PIE_HW_ID_); + if (isMatchingDeviceFound) { + NEARBY_LOGS(INFO) << "Intel WIFI Device is found!"; + break; + } else { + devInst = NULL; + } + } + } + + return devInst; +} + +void CloseRegKeyHandle(HKEY softwareKey) { + // close the registry + RegCloseKey(softwareKey); +} + +void OpenRegKeyHandle(DEVINST devInst, HKEY& softwareKey) { + CONFIGRET configRet = CR_SUCCESS; + + if (devInst != NULL) { + // opens a registry key for device-specific configuration information. + configRet = CM_Open_DevNode_Key(devInst, KEY_READ, 0, // NOLINT + RegDisposition_OpenExisting, + &softwareKey, CM_REGISTRY_SOFTWARE); + + NEARBY_LOGS(VERBOSE) << absl::StrFormat("softwareKey %p ", softwareKey); + + if (configRet != CR_SUCCESS) { + NEARBY_LOGS(INFO) + << "Unexpected error! CM_Open_DevNode_Key return Value of " + << configRet; + } + } else { + NEARBY_LOGS(INFO) << "devInst is NULL"; + } +} + +DWORD GetRegKeyWCHARValue(DEVINST deviceInstance, LPCWSTR keyName, + wchar_t* valOut, PDWORD pValLen, PDWORD pDataType) { + HKEY softwareKey; + DWORD ret = ERROR_SUCCESS; + + if (deviceInstance != NULL) { + OpenRegKeyHandle(deviceInstance, softwareKey); + + ret = RegQueryValueExW(softwareKey, keyName, nullptr, pDataType, + (LPBYTE)valOut, pValLen); // NOLINT + + CloseRegKeyHandle(softwareKey); + } else { + NEARBY_LOGS(INFO) << "Couldn't find dev instacne for device :-( "; + ret = ERROR_NOT_FOUND; // NOLINT + } + return ret; +} + +DWORD GetFullDllLoadPathFromPieRegistry(DEVINST pieDeviceInstance, + PWCHAR* ppDllPathValue) { + DWORD status = ERROR_SUCCESS; + DWORD dllPathBufferLen = 0; + DWORD regKeyDataType = 0; + DWORD dllFullPathLen = 0; + PWCHAR pLoadPathString = nullptr; + std::wstring pathString = {}; + + // Get the buffer size to allocate the dll load path + status = GetRegKeyWCHARValue(pieDeviceInstance, PIE_DLL_PATH_HINT, nullptr, + &dllPathBufferLen, ®KeyDataType); + if (status != ERROR_SUCCESS) { + NEARBY_LOGS(INFO) + << "Unexpected error! GetRegKeyWCHARValue return Value of " << status; + return status; + } else { + NEARBY_LOGS(VERBOSE) << "Queried key length successfully!"; + } + + dllFullPathLen = (dllPathBufferLen + sizeof(PIE_API_DLL)); + NEARBY_LOGS(VERBOSE) << "dll Full Path Length = " << dllFullPathLen; + + pLoadPathString = new wchar_t[dllFullPathLen]; + SecureZeroMemory(pLoadPathString, dllFullPathLen); // NOLINT + + // Get the load path + status = + GetRegKeyWCHARValue(pieDeviceInstance, PIE_DLL_PATH_HINT, pLoadPathString, + &dllPathBufferLen, ®KeyDataType); + if (status != ERROR_SUCCESS) { + NEARBY_LOGS(INFO) + << "Unexpected error! GetRegKeyWCHARValue return Value of " << status; + SAFEDELETEARRAY(pLoadPathString); + return status; + } else { + pathString = pLoadPathString; + NEARBY_LOGS(VERBOSE) << "Queried key successfully!"; + } + + std::wstring fullString = pathString + PIE_API_DLL; + + wcscpy_s(pLoadPathString, dllFullPathLen, fullString.c_str()); // NOLINT + + std::wcout << "wifi_intel.cc" + << ":" << __LINE__ + << "] PIE Dll Path and Name = " << pLoadPathString << std::endl; + + if (ppDllPathValue != nullptr) { + *ppDllPathValue = pLoadPathString; + } else { + SAFEDELETEARRAY(pLoadPathString); + } + return status; +} + +HINSTANCE WifiIntel::PIEDllLoader() { + wchar_t* pEntireDeviceList = nullptr; + DEVINST pieRegDeviceInstance = 0; + PWCHAR pDllPathValue = nullptr; + HINSTANCE murocApiDllHandle = nullptr; + DWORD ret = ERROR_SUCCESS; + + pEntireDeviceList = GetEntireRegistryDeviceList(); + pieRegDeviceInstance = SearchForDeviceInstance(pEntireDeviceList); + SAFEDELETEARRAY(pEntireDeviceList); + + ret = GetFullDllLoadPathFromPieRegistry(pieRegDeviceInstance, &pDllPathValue); + + if (ret == ERROR_SUCCESS) { + NEARBY_LOGS(INFO) << "Found and trying to load MurocApi.dll"; + + // load the library and get the handle + murocApiDllHandle = LoadLibraryW(pDllPathValue); // NOLINT + + NEARBY_LOGS(INFO) << absl::StrFormat("Muroc Api Dll Handle is 0x%p ", + murocApiDllHandle); + } else { + NEARBY_LOGS(INFO) << "GetFullDllLoadPathFromPieRegistry fails eith error: " + << ret; + } + + SAFEDELETEARRAY(pDllPathValue); + + return murocApiDllHandle; +} + +HADAPTER WifiGetAdapterList(HINSTANCE murocApiDllHandle, + PINTEL_ADAPTER_LIST_V120* ppAllAdapters) { + HADAPTER firstAdapterOnTheList = INVALID_HADAPTER; + WIFIGETADAPTERLIST WifiGetAdapterListFunction = nullptr; + DWORD dwError; + + // Use Muroc APIs - First - Get Adapter List + WifiGetAdapterListFunction = (WIFIGETADAPTERLIST)GetProcAddress( + murocApiDllHandle, "WifiGetAdapterList"); + + if (WifiGetAdapterListFunction == nullptr) { + dwError = GetLastError(); + NEARBY_LOGS(INFO) << "GetProcAddress for WifiGetAdapterListFunction API " + "fails with error: " + << dwError; + return INVALID_HADAPTER; + } + + NEARBY_LOGS(INFO) << "GetProcAddress for WifiGetAdapterListFunction API " + "completed successfully"; + INTEL_WIFI_HEADER intelHeader = {INTEL_STRUCT_VERSION_V156, // NOLINT + sizeof(MurocDefs::INTEL_ADAPTER_LIST_V120)}; + MUROC_RET murocApiRetVal = IWLAN_E_FAILURE; + + murocApiRetVal = + WifiGetAdapterListFunction(&intelHeader, (void**)ppAllAdapters); + + if (murocApiRetVal != IWLAN_E_SUCCESS) { + NEARBY_LOGS(INFO) + << "Calling WifiGetAdapterListFunction API fails with error:" + << murocApiRetVal; + return INVALID_HADAPTER; + } + + firstAdapterOnTheList = (*ppAllAdapters)->adapter[0].hAdapter; + NEARBY_LOGS(INFO) << "Return WIFI Adapter: " << firstAdapterOnTheList; + + return firstAdapterOnTheList; +} + +void RegisterIntelCallback( + HINSTANCE murocApiDllHandle, + const MurocDefs::PINTEL_CALLBACK pIntelEventCbHandle) { + REGISTERINTELCB registerIntelCBFunc = nullptr; + DWORD dwError = ERROR_SUCCESS; + + registerIntelCBFunc = (REGISTERINTELCB)GetProcAddress( + murocApiDllHandle, "RegisterIntelCallback"); + if (registerIntelCBFunc == nullptr) { + dwError = GetLastError(); + NEARBY_LOGS(INFO) + << "GetProcAddress of RegisterIntelCallback API fails with error:" + << dwError; + return; + } + + NEARBY_LOGS(VERBOSE) << "Load RegisterIntelCallback API successfully"; + MUROC_RET murocApiRetVal = IWLAN_E_FAILURE; + + murocApiRetVal = registerIntelCBFunc(pIntelEventCbHandle); + + if (murocApiRetVal == IWLAN_E_SUCCESS) { + NEARBY_LOGS(INFO) << "Calling RegisterIntelCallback API succeeded."; + } else { + NEARBY_LOGS(INFO) << "Calling RegisterIntelCallback API fails with error:" + << murocApiRetVal; + } +} + +void DeregisterIntelCallback(HINSTANCE murocApiDllHandle, + MurocDefs::INTEL_EVENT_CALLBACK fnCallback) { + DEREGISTERINTELCB deregisterIntelCBFunc = nullptr; + DWORD dwError = ERROR_SUCCESS; + + deregisterIntelCBFunc = (DEREGISTERINTELCB)GetProcAddress( + murocApiDllHandle, "DeregisterIntelCallback"); + + if (deregisterIntelCBFunc == nullptr) { + dwError = GetLastError(); + NEARBY_LOGS(INFO) + << "GetProcAddress of DeregisterIntelCallback API failed with error: ", + dwError; + return; + } + + { + NEARBY_LOGS(VERBOSE) << "Load DeregisterIntelCallback API successfully"; + MUROC_RET murocApiRetVal = IWLAN_E_FAILURE; + + murocApiRetVal = deregisterIntelCBFunc(fnCallback); + + if (murocApiRetVal == IWLAN_E_SUCCESS) { + NEARBY_LOGS(INFO) << "Calling DeregisterIntelCallback API succeeded."; + } else { + NEARBY_LOGS(INFO) + << "Calling DeregisterIntelCallback API fails with error:" + << murocApiRetVal; + } + } +} + +void WINAPI IntelEventHandler(MurocDefs::INTEL_EVENT iEvent, void* pContext) { + NEARBY_LOGS(INFO) << "Received Intel Event id: %d" << iEvent.eType; +} + +void FreeMemoryList(HINSTANCE murocApiDllHandle, void* ptr) { + FREELISTMEMORY freeMemoryListFunction = nullptr; + DWORD dwError = ERROR_SUCCESS; + + freeMemoryListFunction = + (FREELISTMEMORY)GetProcAddress(murocApiDllHandle, "FreeListMemory"); + + if (freeMemoryListFunction == nullptr) { + dwError = GetLastError(); + NEARBY_LOGS(INFO) + << "GetProcAddress of FreeListMemory API failed with error: " + << dwError; + } + + if ((freeMemoryListFunction != nullptr)) { + NEARBY_LOGS(VERBOSE) << "Load FreeListMemory API successfully"; + MUROC_RET murocApiRetVal = IWLAN_E_FAILURE; + + murocApiRetVal = freeMemoryListFunction(ptr); + + if (murocApiRetVal == IWLAN_E_SUCCESS) { + NEARBY_LOGS(INFO) << "Calling FreeListMemory API succeeded."; + } else { + NEARBY_LOGS(INFO) << "Calling FreeListMemory API failed with error: " + << murocApiRetVal; + } + } +} + +} // namespace windows +} // namespace nearby diff --git a/internal/platform/implementation/windows/wifi_intel.h b/internal/platform/implementation/windows/wifi_intel.h new file mode 100644 index 00000000..c7995aad --- /dev/null +++ b/internal/platform/implementation/windows/wifi_intel.h @@ -0,0 +1,64 @@ +// Copyright 2022-2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef PLATFORM_IMPL_WINDOWS_WIFI_INTEL_H_ +#define PLATFORM_IMPL_WINDOWS_WIFI_INTEL_H_ + +// clang-format off +#include +#include +// clang-format on + +// Intel WIFI PIE headers +#include "third_party/intel/pie/include/IntelSdkVersionInfo.h" +#include "third_party/intel/pie/include/PieApiErrors.h" +#include "third_party/intel/pie/include/PieDefinitions.h" +#include "internal/platform/logging.h" + +namespace nearby { +namespace windows { + +using ::MurocDefs::PINTEL_ADAPTER_LIST_V120; + +// Container of Intel WIFI to utilize Intel PIE SDK API +class WifiIntel { + public: + WifiIntel(const WifiIntel&) = delete; + WifiIntel& operator=(const WifiIntel&) = delete; + + static WifiIntel& GetInstance(); + bool IsValid() const { return intel_wifi_valid_; } + void Start(); + void Stop(); + uint8_t GetGOChannel(); + private: + // This is a singleton object, for which destructor will never be called. + // Constructor will be invoked once from Instance() static method. + // Object is create in-place (with a placement new) to guarantee that + // destructor is not scheduled for execution at exit. + WifiIntel() = default; + ~WifiIntel() = default; + + HINSTANCE PIEDllLoader(); + + bool intel_wifi_valid_ = false; + HINSTANCE muroc_api_dll_handle_ = nullptr; + HADAPTER wifi_adapter_handle_ = 0; + PINTEL_ADAPTER_LIST_V120 p_all_adapters_ = nullptr; +}; + +} // namespace windows +} // namespace nearby + +#endif // PLATFORM_IMPL_WINDOWS_WIFI_INTEL_H_ From ad6ac4b4a49e613169d01843f677bbd09b3bb0d3 Mon Sep 17 00:00:00 2001 From: Anay Wadhera Date: Fri, 8 Sep 2023 13:25:28 -0700 Subject: [PATCH 007/683] include missing str_cat header in ed25519 crypto PiperOrigin-RevId: 563836632 --- internal/crypto/BUILD | 3 +-- internal/crypto/ed25519.cc | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/crypto/BUILD b/internal/crypto/BUILD index d301d989..702688cb 100644 --- a/internal/crypto/BUILD +++ b/internal/crypto/BUILD @@ -32,9 +32,8 @@ cc_library( "@boringssl//:crypto", "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", + "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", - "@com_google_absl//absl/types:optional", - "@com_google_absl//absl/types:span", ], ) diff --git a/internal/crypto/ed25519.cc b/internal/crypto/ed25519.cc index 88d8b79b..fcea00c8 100644 --- a/internal/crypto/ed25519.cc +++ b/internal/crypto/ed25519.cc @@ -20,6 +20,7 @@ #include #include "absl/status/status.h" +#include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "internal/crypto_cros/random.h" #include From 71e2555d50b49420642f6fbcadefb120e752a142 Mon Sep 17 00:00:00 2001 From: Anay Wadhera Date: Fri, 8 Sep 2023 18:39:30 -0700 Subject: [PATCH 008/683] silly season PiperOrigin-RevId: 563903303 --- presence/presence_service.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/presence/presence_service.h b/presence/presence_service.h index acef7b46..b9189f8b 100644 --- a/presence/presence_service.h +++ b/presence/presence_service.h @@ -1,4 +1,4 @@ -// Copyright 2020 Google LLC +// Copyright 2020-2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. From 533e1450974a7165532110d6c8c8ed95fe5721a4 Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Mon, 11 Sep 2023 15:12:59 -0700 Subject: [PATCH 009/683] Added more logs for Wi-Fi socket PiperOrigin-RevId: 564514790 --- .../implementation/windows/wifi_lan_socket.cc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/internal/platform/implementation/windows/wifi_lan_socket.cc b/internal/platform/implementation/windows/wifi_lan_socket.cc index 12a06370..20c71471 100644 --- a/internal/platform/implementation/windows/wifi_lan_socket.cc +++ b/internal/platform/implementation/windows/wifi_lan_socket.cc @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include @@ -79,7 +80,8 @@ ExceptionOr WifiLanSocket::SocketInputStream::Read( input_stream_.ReadAsync(buffer, size, InputStreamOptions::None).get(); if (ibuffer.Length() != size) { - NEARBY_LOGS(WARNING) << "Only got part of data of needed."; + NEARBY_LOGS(WARNING) << "Only read partial of data: [" << ibuffer.Length() + << "/" << size << "]."; } ByteArray data((char*)ibuffer.data(), ibuffer.Length()); @@ -146,7 +148,12 @@ Exception WifiLanSocket::SocketOutputStream::Write(const ByteArray& data) { Buffer buffer = Buffer(data.size()); std::memcpy(buffer.data(), data.data(), data.size()); buffer.Length(data.size()); - output_stream_.WriteAsync(buffer).get(); + uint32_t wrote_bytes = output_stream_.WriteAsync(buffer).get(); + if (wrote_bytes != data.size()) { + NEARBY_LOGS(WARNING) << "Only wrote partial of data:[" << wrote_bytes + << "/" << data.size() << "]."; + } + return {Exception::kSuccess}; } catch (std::exception exception) { NEARBY_LOGS(ERROR) << __func__ << ": Exception: " << exception.what(); From 52c3360bd31596bd95d3e2e745fb934e36b0217b Mon Sep 17 00:00:00 2001 From: Janusz Sobczak Date: Mon, 11 Sep 2023 15:46:59 -0700 Subject: [PATCH 010/683] Use AnyInvocable in DiscoveredPeripheralCallback PiperOrigin-RevId: 564523999 --- connections/implementation/mediums/ble_v2/BUILD | 2 +- .../ble_v2/discovered_peripheral_callback.h | 14 +++++++------- .../ble_v2/discovered_peripheral_tracker.cc | 13 ++++++------- .../mediums/ble_v2/discovered_peripheral_tracker.h | 2 +- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/connections/implementation/mediums/ble_v2/BUILD b/connections/implementation/mediums/ble_v2/BUILD index 17241f9e..c07c66da 100644 --- a/connections/implementation/mediums/ble_v2/BUILD +++ b/connections/implementation/mediums/ble_v2/BUILD @@ -39,7 +39,6 @@ cc_library( "//connections/implementation:__subpackages__", ], deps = [ - "//connections:core_types", "//connections/implementation/flags:connections_flags", "//connections/implementation/mediums:utils", "//internal/flags:nearby_flags", @@ -53,6 +52,7 @@ cc_library( "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/container:flat_hash_set", + "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/numeric:int128", "@com_google_absl//absl/status:statusor", "@com_google_absl//absl/strings", diff --git a/connections/implementation/mediums/ble_v2/discovered_peripheral_callback.h b/connections/implementation/mediums/ble_v2/discovered_peripheral_callback.h index 5a190282..6d39fa4c 100644 --- a/connections/implementation/mediums/ble_v2/discovered_peripheral_callback.h +++ b/connections/implementation/mediums/ble_v2/discovered_peripheral_callback.h @@ -15,9 +15,9 @@ #ifndef CORE_INTERNAL_MEDIUMS_BLE_V2_DISCOVERED_PERIPHERAL_CALLBACK_H_ #define CORE_INTERNAL_MEDIUMS_BLE_V2_DISCOVERED_PERIPHERAL_CALLBACK_H_ -#include #include +#include "absl/functional/any_invocable.h" #include "internal/platform/ble_v2.h" #include "internal/platform/byte_array.h" @@ -27,14 +27,14 @@ namespace mediums { // Callback that is invoked when a {@link BlePeripheral} is discovered. struct DiscoveredPeripheralCallback { - std::function + absl::AnyInvocable peripheral_discovered_cb = [](BleV2Peripheral, const std::string&, const ByteArray&, bool) {}; - std::function + absl::AnyInvocable peripheral_lost_cb = [](BleV2Peripheral, const std::string&, const ByteArray&, bool) {}; }; diff --git a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.cc b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.cc index 806cf3dc..024d6c62 100644 --- a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.cc +++ b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.cc @@ -28,6 +28,7 @@ #include "connections/implementation/mediums/ble_v2/ble_advertisement_header.h" #include "connections/implementation/mediums/ble_v2/ble_utils.h" #include "connections/implementation/mediums/ble_v2/bloom_filter.h" +#include "connections/implementation/mediums/ble_v2/discovered_peripheral_callback.h" #include "internal/flags/nearby_flags.h" #include "internal/platform/ble_v2.h" #include "internal/platform/byte_array.h" @@ -66,7 +67,7 @@ DiscoveredPeripheralTracker::~DiscoveredPeripheralTracker() { void DiscoveredPeripheralTracker::StartTracking( const std::string& service_id, - const DiscoveredPeripheralCallback& discovered_peripheral_callback, + DiscoveredPeripheralCallback discovered_peripheral_callback, const Uuid& fast_advertisement_service_uuid) { MutexLock lock(&mutex_); @@ -129,11 +130,9 @@ void DiscoveredPeripheralTracker::ProcessFoundBleAdvertisement( void DiscoveredPeripheralTracker::ProcessLostGattAdvertisements() { MutexLock lock(&mutex_); - for (const auto& it : service_id_infos_) { + for (auto& it : service_id_infos_) { const std::string& service_id = it.first; - const ServiceIdInfo& service_id_info = it.second; - DiscoveredPeripheralCallback discovered_peripheral_callback = - service_id_info.discovered_peripheral_callback; + ServiceIdInfo& service_id_info = it.second; BleAdvertisementSet lost_gatt_advertisements = service_id_info.lost_entity_tracker->ComputeLostEntities(); @@ -145,7 +144,7 @@ void DiscoveredPeripheralTracker::ProcessLostGattAdvertisements() { BleV2Peripheral lost_peripheral = it->second.peripheral; if (lost_peripheral.IsValid()) { lost_peripheral.SetId(ByteArray(gatt_advertisement)); - discovered_peripheral_callback.peripheral_lost_cb( + service_id_info.discovered_peripheral_callback.peripheral_lost_cb( std::move(lost_peripheral), service_id, gatt_advertisement.GetData(), gatt_advertisement.IsFastAdvertisement()); @@ -525,7 +524,7 @@ void DiscoveredPeripheralTracker::HandleAdvertisementHeader( ByteArray advertisement_data{advertisement_header}; if (fetching_advertisements_.contains(advertisement_data)) { NEARBY_LOGS(VERBOSE) << ": Ignore the advertisement header due to it " - "is already in fetcing."; + "is already in fetching."; return; } diff --git a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h index fcd59951..380d6bd5 100644 --- a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h +++ b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h @@ -79,7 +79,7 @@ class DiscoveredPeripheralTracker { // advertisement. void StartTracking( const std::string& service_id, - const DiscoveredPeripheralCallback& discovered_peripheral_callback, + DiscoveredPeripheralCallback discovered_peripheral_callback, const Uuid& fast_advertisement_service_uuid) ABSL_LOCKS_EXCLUDED(mutex_); // Stops tracking discoveries for a particular service Id. From 82c8970535bf754b5ffd620b4bb0fd0b73e4b7b9 Mon Sep 17 00:00:00 2001 From: hai007 Date: Mon, 11 Sep 2023 17:55:46 -0700 Subject: [PATCH 011/683] [Sharing][Analytics] Adding logging for permission auto access UI. PiperOrigin-RevId: 564554884 --- proto/sharing_enums.proto | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/proto/sharing_enums.proto b/proto/sharing_enums.proto index ce06d0da..3d1d9f87 100644 --- a/proto/sharing_enums.proto +++ b/proto/sharing_enums.proto @@ -30,7 +30,7 @@ option objc_class_prefix = "GNSHP"; // in NearbyClearcutLogger (for android, or clearcut_event_logger as the // equivalence for Windows) for all events (may exclude settings), and // session_id for a pair of events (start and end of a session). -// Next id: 65 +// Next id: 66 enum EventType { UNKNOWN_EVENT_TYPE = 0; @@ -238,6 +238,9 @@ enum EventType { // Decrypt certificate failure DECRYPT_CERTIFICATE_FAILURE = 64; + // Show allow permission auto access UI + SHOW_ALLOW_PERMISSION_AUTO_ACCESS = 65; + // LINT.ThenChange(//depot/google3/location/nearby/proto/nearby_event_codes.proto:SharingEventCode) } From fe9c9f90b6b86181d5322759b2b596aefc628019 Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Tue, 12 Sep 2023 13:20:14 -0700 Subject: [PATCH 012/683] Refactored Bluetooth classic medium PiperOrigin-RevId: 564813626 --- .../windows/bluetooth_classic_medium.cc | 256 ++++++++++-------- .../windows/bluetooth_classic_medium.h | 112 ++------ 2 files changed, 166 insertions(+), 202 deletions(-) diff --git a/internal/platform/implementation/windows/bluetooth_classic_medium.cc b/internal/platform/implementation/windows/bluetooth_classic_medium.cc index 9daaa8d7..f1f98264 100644 --- a/internal/platform/implementation/windows/bluetooth_classic_medium.cc +++ b/internal/platform/implementation/windows/bluetooth_classic_medium.cc @@ -1,4 +1,4 @@ -// Copyright 2020 Google LLC +// Copyright 2020-2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,11 +14,9 @@ #include "internal/platform/implementation/windows/bluetooth_classic_medium.h" -#include #include #include -#include #include #include #include @@ -31,6 +29,8 @@ #include "internal/platform/cancellation_flag.h" #include "internal/platform/cancellation_flag_listener.h" #include "internal/platform/exception.h" +#include "internal/platform/feature_flags.h" +#include "internal/platform/implementation/bluetooth_adapter.h" #include "internal/platform/implementation/bluetooth_classic.h" #include "internal/platform/implementation/windows/bluetooth_adapter.h" #include "internal/platform/implementation/windows/bluetooth_classic_device.h" @@ -49,12 +49,31 @@ namespace nearby { namespace windows { namespace { -using winrt::Windows::Foundation::IInspectable; -using winrt::Windows::Foundation::Collections::IMapView; +using ::winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommDeviceService; +using ::winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommServiceId; +using ::winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommServiceProvider; +using ::winrt::Windows::Devices::Enumeration::DeviceAccessInformation; +using ::winrt::Windows::Devices::Enumeration::DeviceAccessStatus; +using ::winrt::Windows::Devices::Enumeration::DeviceInformation; +using ::winrt::Windows::Devices::Enumeration::DeviceInformationKind; +using ::winrt::Windows::Devices::Enumeration::DeviceInformationUpdate; +using ::winrt::Windows::Devices::Enumeration::DeviceWatcher; +using ::winrt::Windows::Devices::Enumeration::DeviceWatcherStatus; +using ::winrt::Windows::Foundation::IInspectable; +using ::winrt::Windows::Foundation::Collections::IMapView; +using ::winrt::Windows::Storage::Streams::DataReader; +using ::winrt::Windows::Storage::Streams::DataWriter; +using ::winrt::Windows::Storage::Streams::UnicodeEncoding; -// Used to cntrol the dump output for device information. It is only for debug +// Used to control the dump output for device information. It is only for debug // purpose. constexpr bool kEnableDumpDeviceInfomation = false; +// The maximum length of Bluetooth device name Android can discover. +constexpr int kAndroidDiscoverableBluetoothNameMaxLength = 37; // bytes +// Used to select bluetooth devices. +constexpr wchar_t kBluetoothSelector[] = + L"System.Devices.Aep.ProtocolId:=\"{e0cbf06c-cd8b-4647-bb8a-263b43f0f974}" + L"\""; void DumpDeviceInformation( const IMapView& properties) { @@ -88,11 +107,9 @@ void DumpDeviceInformation( } // namespace -constexpr uint8_t kAndroidDiscoverableBluetoothNameMaxLength = 37; // bytes - BluetoothClassicMedium::BluetoothClassicMedium( - api::BluetoothAdapter& bluetoothAdapter) - : bluetooth_adapter_(dynamic_cast(bluetoothAdapter)) { + api::BluetoothAdapter& bluetooth_adapter) + : bluetooth_adapter_(dynamic_cast(bluetooth_adapter)) { InitializeDeviceWatcher(); bluetooth_adapter_.RestoreRadioNameIfNecessary(); @@ -103,17 +120,17 @@ BluetoothClassicMedium::BluetoothClassicMedium( BluetoothClassicMedium::~BluetoothClassicMedium() {} void BluetoothClassicMedium::OnScanModeChanged( - BluetoothAdapter::ScanMode scanMode) { + BluetoothAdapter::ScanMode scan_mode) { NEARBY_LOGS(INFO) << __func__ << ": OnScanModeChanged is called with scanMode: " - << static_cast(scanMode); + << static_cast(scan_mode); - if (scanMode == scan_mode_) { + if (scan_mode == scan_mode_) { NEARBY_LOGS(INFO) << __func__ << ": No change of scan mode."; return; } - scan_mode_ = scanMode; + scan_mode_ = scan_mode; bool radio_discoverable = scan_mode_ == BluetoothAdapter::ScanMode::kConnectableDiscoverable; @@ -130,7 +147,7 @@ void BluetoothClassicMedium::OnScanModeChanged( } if (rfcomm_provider_ == nullptr) { - NEARBY_LOGS(INFO) << __func__ << ": No advertising."; + NEARBY_LOGS(WARNING) << __func__ << ": No advertising."; return; } @@ -184,14 +201,14 @@ bool BluetoothClassicMedium::StopDiscovery() { void BluetoothClassicMedium::InitializeDeviceWatcher() { try { // create watcher - const winrt::param::iterable RequestedProperties = + const winrt::param::iterable requested_properties = winrt::single_threaded_vector( {winrt::to_hstring("System.Devices.Aep.IsPresent"), winrt::to_hstring("System.Devices.Aep.DeviceAddress")}); device_watcher_ = DeviceInformation::CreateWatcher( - BLUETOOTH_SELECTOR, // aqsFilter - RequestedProperties, // additionalProperties + kBluetoothSelector, // aqsFilter + requested_properties, // additionalProperties DeviceInformationKind::AssociationEndpoint); // kind // An app must subscribe to all of the added, removed, and updated events @@ -258,49 +275,18 @@ std::unique_ptr BluetoothClassicMedium::ConnectToService( return nullptr; } - remote_device_to_connect_ = - std::make_unique(remote_device.GetMacAddress()); + auto remote_device_to_connect_ = dynamic_cast( + GetRemoteDevice(remote_device.GetMacAddress())); - // First try, check if the remote device that we want to request connection - // to has already been discovered by the Bluetooth Classic Device Watcher - // beforehand inside the discovered_devices_by_id_ map - std::map>::const_iterator - it = discovered_devices_by_id_.find( - winrt::to_hstring(remote_device_to_connect_->GetId())); - - std::unique_ptr device = nullptr; - BluetoothDevice* current_device = nullptr; - - if (it != discovered_devices_by_id_.end()) { - current_device = it->second.get(); - } else { - // The remote device was not discovered by the Bluetooth Classic Device - // Watcher beforehand. - // Second try, request Windows to scan for nearby - // bluetooth devices that has this static mac address again in this - // instance - auto remote_bluetooth_device_from_mac_address = - winrt::Windows::Devices::Bluetooth::BluetoothDevice:: - FromBluetoothAddressAsync( - mac_address_string_to_uint64(remote_device.GetMacAddress())) - .get(); - if (remote_bluetooth_device_from_mac_address == nullptr) { - NEARBY_LOGS(ERROR) << __func__ - << ": Windows failed to get remote bluetooth device " - "from static mac address."; - return nullptr; - } - device = std::make_unique( - remote_bluetooth_device_from_mac_address); - current_device = device.get(); - } - - if (current_device == nullptr) { - NEARBY_LOGS(ERROR) << __func__ << ": Failed to get current device."; + if (remote_device_to_connect_ == nullptr || + remote_device_to_connect_->GetId().empty()) { + NEARBY_LOGS(ERROR) << __func__ + << ": Failed to get remote device from MAC address."; return nullptr; } - winrt::hstring device_id = winrt::to_hstring(current_device->GetId()); + winrt::hstring device_id = + winrt::to_hstring(remote_device_to_connect_->GetId()); if (!HaveAccess(device_id)) { NEARBY_LOGS(ERROR) << __func__ << ": Failed to gain access to device: " @@ -309,7 +295,7 @@ std::unique_ptr BluetoothClassicMedium::ConnectToService( } RfcommDeviceService requested_service( - GetRequestedService(current_device, service)); + GetRequestedService(remote_device_to_connect_, service)); if (!FeatureFlags::GetInstance() .GetFlags() @@ -420,31 +406,32 @@ bool BluetoothClassicMedium::HaveAccess(winrt::hstring device_id) { RfcommDeviceService BluetoothClassicMedium::GetRequestedService( BluetoothDevice* device, winrt::guid service) { - RfcommServiceId rfcommServiceId = RfcommServiceId::FromUuid(service); - return device->GetRfcommServiceForIdAsync(rfcommServiceId); + RfcommServiceId rfcomm_service_id = RfcommServiceId::FromUuid(service); + return device->GetRfcommServiceForIdAsync(rfcomm_service_id); } -bool BluetoothClassicMedium::CheckSdp(RfcommDeviceService requestedService) { +bool BluetoothClassicMedium::CheckSdp(RfcommDeviceService requested_service) { // 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 try { - if (requestedService == nullptr) { + if (requested_service == nullptr) { + NEARBY_LOGS(WARNING) << __func__ << ": Request service is empty."; return false; } - auto attributes = requestedService.GetSdpRawAttributesAsync().get(); + auto attributes = requested_service.GetSdpRawAttributesAsync().get(); if (!attributes.HasKey(Constants::SdpServiceNameAttributeId)) { NEARBY_LOGS(ERROR) << __func__ << ": Missing SdpServiceNameAttributeId."; return false; } - auto attributeReader = DataReader::FromBuffer( + auto attribute_reader = DataReader::FromBuffer( attributes.Lookup(Constants::SdpServiceNameAttributeId)); - auto attributeType = attributeReader.ReadByte(); + auto attribute_type = attribute_reader.ReadByte(); - if (attributeType != Constants::SdpServiceNameAttributeType) { + if (attribute_type != Constants::SdpServiceNameAttributeType) { NEARBY_LOGS(ERROR) << __func__ << ": Missing SdpServiceNameAttributeType."; return false; @@ -503,7 +490,22 @@ BluetoothClassicMedium::ListenForService(const std::string& service_name, api::BluetoothDevice* BluetoothClassicMedium::GetRemoteDevice( const std::string& mac_address) { - return new BluetoothDevice(mac_address); + auto it = mac_address_to_bluetooth_device_map_.find(mac_address); + + if (it == mac_address_to_bluetooth_device_map_.end()) { + NEARBY_LOGS(WARNING) << __func__ << ": Bluetooth device " << mac_address + << " is not in list. create it"; + auto bluetooth_device = std::make_unique(mac_address); + + mac_address_to_bluetooth_device_map_[mac_address] = + std::move(bluetooth_device); + return mac_address_to_bluetooth_device_map_[mac_address].get(); + } + + NEARBY_LOGS(INFO) << __func__ << ": Bluetooth device " << mac_address + << " is in cache"; + + return it->second.get(); } bool BluetoothClassicMedium::StartScanning() { @@ -515,7 +517,7 @@ bool BluetoothClassicMedium::StartScanning() { return false; } - discovered_devices_by_id_.clear(); + mac_address_to_bluetooth_device_map_.clear(); // The Start method can only be called when the DeviceWatcher is in the // Created, Stopped or Aborted state. @@ -548,9 +550,9 @@ bool BluetoothClassicMedium::StopScanning() { } winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Added( - DeviceWatcher sender, DeviceInformation deviceInfo) { - NEARBY_LOGS(INFO) << "Device added " << winrt::to_string(deviceInfo.Id()); - IMapView properties = deviceInfo.Properties(); + DeviceWatcher sender, DeviceInformation device_info) { + NEARBY_LOGS(INFO) << "Device added " << winrt::to_string(device_info.Id()); + IMapView properties = device_info.Properties(); DumpDeviceInformation(properties); if (!IsWatcherStarted()) { @@ -560,14 +562,14 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Added( // If device no item name, ignore it. if (!properties.HasKey(L"System.ItemNameDisplay")) { NEARBY_LOGS(WARNING) << __func__ << ": Ignore the Bluetooth device " - << winrt::to_string(deviceInfo.Id()) + << winrt::to_string(device_info.Id()) << " due to no name."; return winrt::fire_and_forget(); } if (properties.Lookup(L"System.ItemNameDisplay") == nullptr) { NEARBY_LOGS(WARNING) << __func__ << ": Ignore the Bluetooth device " - << winrt::to_string(deviceInfo.Id()) + << winrt::to_string(device_info.Id()) << " due to empty name."; return winrt::fire_and_forget(); } @@ -575,7 +577,7 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Added( // If device doesn't support pair, ignore it. if (!properties.HasKey(L"System.Devices.Aep.CanPair")) { NEARBY_LOGS(WARNING) << __func__ << ": Ignore the Bluetooth device " - << winrt::to_string(deviceInfo.Id()) + << winrt::to_string(device_info.Id()) << " due to no pair property."; return winrt::fire_and_forget(); } @@ -583,61 +585,72 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Added( if (!InspectableReader::ReadBoolean( properties.Lookup(L"System.Devices.Aep.CanPair"))) { NEARBY_LOGS(WARNING) << __func__ << ": Ignore the Bluetooth device " - << winrt::to_string(deviceInfo.Id()) + << winrt::to_string(device_info.Id()) << " due to not support pair."; return winrt::fire_and_forget(); } + // Create a bluetooth device out of this id + auto native_bluetooth_device = + ::winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromIdAsync( + device_info.Id()) + .get(); + + std::string mac_address = + uint64_to_mac_address_string(native_bluetooth_device.BluetoothAddress()); + // Create an iterator for the internal list - std::map>::const_iterator - it = discovered_devices_by_id_.find(deviceInfo.Id()); + auto it = mac_address_to_bluetooth_device_map_.find(mac_address); // Add to our internal list if necessary - if (it != discovered_devices_by_id_.end()) { + if (it != mac_address_to_bluetooth_device_map_.end()) { // We're already tracking this one - NEARBY_LOGS(WARNING) << __func__ << ": Bluetooth device " - << winrt::to_string(deviceInfo.Id()) + NEARBY_LOGS(WARNING) << __func__ << ": Bluetooth device " << mac_address << " is alreay added."; return winrt::fire_and_forget(); } - // Create a bluetooth device out of this id - auto bluetoothDevice = - winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromIdAsync( - deviceInfo.Id()) - .get(); - auto bluetoothDeviceP = std::make_unique(bluetoothDevice); + auto bluetooth_device = + std::make_unique(native_bluetooth_device); - discovered_devices_by_id_[deviceInfo.Id()] = std::move(bluetoothDeviceP); + mac_address_to_bluetooth_device_map_[mac_address] = + std::move(bluetooth_device); - NEARBY_LOGS(INFO) << __func__ << ": Notifying bluetooth device added"; + NEARBY_LOGS(INFO) << __func__ << ": Notifying bluetooth device " + << mac_address << " added"; if (discovery_callback_.device_discovered_cb != nullptr) { discovery_callback_.device_discovered_cb( - *discovered_devices_by_id_[deviceInfo.Id()]); + *mac_address_to_bluetooth_device_map_[mac_address]); } for (auto& observer : observers_.GetObservers()) { - observer->DeviceAdded(*discovered_devices_by_id_[deviceInfo.Id()]); + observer->DeviceAdded(*mac_address_to_bluetooth_device_map_[mac_address]); } return winrt::fire_and_forget(); } winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Updated( - DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate) { - auto it = discovered_devices_by_id_.find(deviceInfoUpdate.Id()); + DeviceWatcher sender, DeviceInformationUpdate device_update_info) { + auto native_bluetooth_device = + ::winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromIdAsync( + device_update_info.Id()) + .get(); + std::string mac_address = + uint64_to_mac_address_string(native_bluetooth_device.BluetoothAddress()); - if (it == discovered_devices_by_id_.end()) { - NEARBY_LOGS(WARNING) << __func__ << ": Bluetooth device " - << winrt::to_string(deviceInfoUpdate.Id()) + auto it = mac_address_to_bluetooth_device_map_.find(mac_address); + + if (it == mac_address_to_bluetooth_device_map_.end()) { + NEARBY_LOGS(WARNING) << __func__ << ": Bluetooth device " << mac_address << " is not in list."; return winrt::fire_and_forget(); } NEARBY_LOGS(INFO) << "Device updated name: " - << discovered_devices_by_id_[deviceInfoUpdate.Id()]->GetName() << " (" - << winrt::to_string(deviceInfoUpdate.Id()) << ")"; + << mac_address_to_bluetooth_device_map_[mac_address]->GetName() << " (" + << mac_address << ")"; IMapView properties = - deviceInfoUpdate.Properties(); + device_update_info.Properties(); DumpDeviceInformation(properties); if (!IsWatcherStarted()) { @@ -659,10 +672,10 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Updated( NEARBY_LOGS(INFO) << "Updated device name:" - << discovered_devices_by_id_[deviceInfoUpdate.Id()]->GetName(); + << mac_address_to_bluetooth_device_map_[mac_address]->GetName(); discovery_callback_.device_name_changed_cb( - *discovered_devices_by_id_[deviceInfoUpdate.Id()]); + *mac_address_to_bluetooth_device_map_[mac_address]); } } @@ -675,7 +688,8 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Updated( << new_paired_status; for (auto& observer : observers_.GetObservers()) { observer->DevicePairedChanged( - *discovered_devices_by_id_[deviceInfoUpdate.Id()], new_paired_status); + *mac_address_to_bluetooth_device_map_[mac_address], + new_paired_status); } } @@ -683,19 +697,25 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Updated( } winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Removed( - DeviceWatcher sender, DeviceInformationUpdate deviceInfo) { - auto it = discovered_devices_by_id_.find(deviceInfo.Id()); + DeviceWatcher sender, DeviceInformationUpdate device_update_info) { + auto native_bluetooth_device = + ::winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromIdAsync( + device_update_info.Id()) + .get(); + std::string mac_address = + uint64_to_mac_address_string(native_bluetooth_device.BluetoothAddress()); + auto it = mac_address_to_bluetooth_device_map_.find(mac_address); - if (it == discovered_devices_by_id_.end()) { - NEARBY_LOGS(WARNING) << __func__ << ": Bluetooth device " - << winrt::to_string(deviceInfo.Id()) + if (it == mac_address_to_bluetooth_device_map_.end()) { + NEARBY_LOGS(WARNING) << __func__ << ": Bluetooth device " << mac_address << " is not in list."; return winrt::fire_and_forget(); } - NEARBY_LOGS(INFO) << "Device removed " - << discovered_devices_by_id_[deviceInfo.Id()]->GetName() - << " (" << winrt::to_string(deviceInfo.Id()) << ")"; + NEARBY_LOGS(INFO) + << "Device removed " + << mac_address_to_bluetooth_device_map_[mac_address]->GetName() << " (" + << mac_address << ")"; if (!IsWatcherStarted()) { return winrt::fire_and_forget(); @@ -704,14 +724,14 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Removed( NEARBY_LOGS(INFO) << __func__ << ": Notifying bluetooth device removed"; if (discovery_callback_.device_lost_cb != nullptr) { discovery_callback_.device_lost_cb( - *discovered_devices_by_id_[deviceInfo.Id()]); + *mac_address_to_bluetooth_device_map_[mac_address]); } for (auto& observer : observers_.GetObservers()) { - observer->DeviceRemoved(*discovered_devices_by_id_[deviceInfo.Id()]); + observer->DeviceRemoved(*mac_address_to_bluetooth_device_map_[mac_address]); } - discovered_devices_by_id_.erase(deviceInfo.Id()); + mac_address_to_bluetooth_device_map_.erase(mac_address); return winrt::fire_and_forget(); } @@ -870,21 +890,21 @@ bool BluetoothClassicMedium::StopAdvertising() { bool BluetoothClassicMedium::InitializeServiceSdpAttributes( RfcommServiceProvider rfcomm_provider, std::string service_name) { try { - auto sdpWriter = DataWriter(); + auto sdp_writer = DataWriter(); // Write the Service Name Attribute. - sdpWriter.WriteByte(Constants::SdpServiceNameAttributeType); + sdp_writer.WriteByte(Constants::SdpServiceNameAttributeType); // The length of the UTF-8 encoded Service Name SDP Attribute. - sdpWriter.WriteByte(service_name.size()); + sdp_writer.WriteByte(service_name.size()); // The UTF-8 encoded Service Name value. - sdpWriter.UnicodeEncoding(UnicodeEncoding::Utf8); - sdpWriter.WriteString(winrt::to_hstring(service_name)); + sdp_writer.UnicodeEncoding(UnicodeEncoding::Utf8); + sdp_writer.WriteString(winrt::to_hstring(service_name)); // Set the SDP Attribute on the RFCOMM Service Provider. rfcomm_provider.SdpRawAttributes().Insert( - Constants::SdpServiceNameAttributeId, sdpWriter.DetachBuffer()); + Constants::SdpServiceNameAttributeId, sdp_writer.DetachBuffer()); return true; } catch (...) { diff --git a/internal/platform/implementation/windows/bluetooth_classic_medium.h b/internal/platform/implementation/windows/bluetooth_classic_medium.h index 44f62d06..9465f83d 100644 --- a/internal/platform/implementation/windows/bluetooth_classic_medium.h +++ b/internal/platform/implementation/windows/bluetooth_classic_medium.h @@ -1,4 +1,4 @@ -// Copyright 2020 Google LLC +// Copyright 2020-2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,6 +20,8 @@ #include #include "internal/base/observer_list.h" +#include "internal/platform/cancellation_flag.h" +#include "internal/platform/implementation/bluetooth_adapter.h" #include "internal/platform/implementation/bluetooth_classic.h" #include "internal/platform/implementation/windows/bluetooth_adapter.h" #include "internal/platform/implementation/windows/bluetooth_classic_device.h" @@ -32,76 +34,11 @@ 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; - -// 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; - -// 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; - -// 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; - -// 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: - explicit BluetoothClassicMedium(api::BluetoothAdapter& bluetoothAdapter); - + explicit BluetoothClassicMedium(api::BluetoothAdapter& bluetooth_adapter); ~BluetoothClassicMedium() override; // https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#startDiscovery() @@ -166,56 +103,63 @@ class BluetoothClassicMedium : public api::BluetoothClassicMedium { bool StopScanning(); bool StartAdvertising(bool radio_discoverable); bool StopAdvertising(); - bool InitializeServiceSdpAttributes(RfcommServiceProvider rfcomm_provider, - std::string service_name); + bool InitializeServiceSdpAttributes( + ::winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommServiceProvider + rfcomm_provider, + std::string service_name); bool IsWatcherStarted(); bool IsWatcherRunning(); void InitializeDeviceWatcher(); - void OnScanModeChanged(BluetoothAdapter::ScanMode scanMode); + void OnScanModeChanged(BluetoothAdapter::ScanMode scan_mode); // 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_Added( + ::winrt::Windows::Devices::Enumeration::DeviceWatcher sender, + ::winrt::Windows::Devices::Enumeration::DeviceInformation device_info); winrt::fire_and_forget DeviceWatcher_Updated( - DeviceWatcher sender, DeviceInformationUpdate deviceInfo); + ::winrt::Windows::Devices::Enumeration::DeviceWatcher sender, + ::winrt::Windows::Devices::Enumeration::DeviceInformationUpdate + device_update_info); winrt::fire_and_forget DeviceWatcher_Removed( - DeviceWatcher sender, DeviceInformationUpdate deviceInfo); + ::winrt::Windows::Devices::Enumeration::DeviceWatcher sender, + ::winrt::Windows::Devices::Enumeration::DeviceInformationUpdate + device_update_info); // Check to make sure we can connect if we try - bool HaveAccess(winrt::hstring deviceId); + bool HaveAccess(::winrt::hstring device_id); // Get the service requested RfcommDeviceService GetRequestedService(BluetoothDevice* device, - winrt::guid service); + ::winrt::guid service); // Check to see that the device actually handles the requested service - bool CheckSdp(RfcommDeviceService requestedService); + bool CheckSdp(RfcommDeviceService requested_service); BluetoothClassicMedium::DiscoveryCallback discovery_callback_; - DeviceWatcher device_watcher_ = nullptr; + ::winrt::Windows::Devices::Enumeration::DeviceWatcher device_watcher_ = + nullptr; std::unique_ptr bluetooth_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> - discovered_devices_by_id_; + // Map MAC address to bluetooth device. + std::map> + mac_address_to_bluetooth_device_map_; BluetoothAdapter& bluetooth_adapter_; BluetoothAdapter::ScanMode scan_mode_ = BluetoothAdapter::ScanMode::kUnknown; - std::unique_ptr remote_device_to_connect_; // Used for advertising. - RfcommServiceProvider rfcomm_provider_ = nullptr; + ::winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommServiceProvider + rfcomm_provider_ = nullptr; std::unique_ptr server_socket_ = nullptr; BluetoothServerSocket* raw_server_socket_ = nullptr; bool is_radio_discoverable_ = false; From 8be118a3d0d52300b35db7d9eb7748ceec087f95 Mon Sep 17 00:00:00 2001 From: Juliet Levesque Date: Wed, 13 Sep 2023 06:58:13 -0700 Subject: [PATCH 013/683] [Nearby Connections] Plumb remote device information much deeper into the stack This will be needed for the authentication transport as the verifier will need the information about the remote device. This CL is based on logic from awadhera@ in cl/539175992 with additional unit test coverage. PiperOrigin-RevId: 565037849 --- connections/implementation/BUILD | 3 +- .../implementation/base_pcp_handler.cc | 174 ++++++++- connections/implementation/base_pcp_handler.h | 11 + .../implementation/base_pcp_handler_test.cc | 332 +++++++++++++++++- connections/implementation/mock_device.h | 37 ++ .../implementation/mock_service_controller.h | 7 + .../offline_service_controller.cc | 13 + .../offline_service_controller.h | 5 + .../offline_service_controller_test.cc | 21 ++ .../implementation/offline_simulation_user.cc | 25 ++ .../implementation/offline_simulation_user.h | 7 + connections/implementation/pcp_handler.h | 6 + connections/implementation/pcp_manager.cc | 14 + connections/implementation/pcp_manager.h | 5 + .../implementation/pcp_manager_test.cc | 25 ++ .../implementation/service_controller.h | 6 + .../service_controller_router.cc | 19 +- .../service_controller_router_test.cc | 4 +- connections/implementation/simulation_user.cc | 24 ++ connections/implementation/simulation_user.h | 7 + 20 files changed, 712 insertions(+), 33 deletions(-) create mode 100644 connections/implementation/mock_device.h diff --git a/connections/implementation/BUILD b/connections/implementation/BUILD index 73c38704..4a42d633 100644 --- a/connections/implementation/BUILD +++ b/connections/implementation/BUILD @@ -170,6 +170,7 @@ cc_library( hdrs = [ "fake_bwu_handler.h", "fake_endpoint_channel.h", + "mock_device.h", "mock_service_controller.h", "mock_service_controller_router.h", "offline_simulation_user.h", @@ -184,8 +185,8 @@ cc_library( "//connections/implementation/flags:connections_flags", "//connections/v3:v3_types", "//internal/flags:nearby_flags", + "//internal/interop:device", "//internal/platform:base", - "//internal/platform:test_util", "//internal/platform:types", "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/functional:bind_front", diff --git a/connections/implementation/base_pcp_handler.cc b/connections/implementation/base_pcp_handler.cc index 085121d8..41218bbe 100644 --- a/connections/implementation/base_pcp_handler.cc +++ b/connections/implementation/base_pcp_handler.cc @@ -613,27 +613,140 @@ Status BasePcpHandler::RequestConnection( result]() RUN_ON_PCP_HANDLER_THREAD() { absl::Time start_time = SystemClock::ElapsedRealtime(); - // If we already have a pending connection, then we shouldn't allow any - // more outgoing connections to this endpoint. - if (pending_connections_.count(endpoint_id)) { + DiscoveredEndpoint* endpoint = GetDiscoveredEndpoint(endpoint_id); + if (endpoint == nullptr) { NEARBY_LOGS(INFO) - << "In requestConnection(), connection requested with " - "endpoint(id=" - << endpoint_id - << "), but we already have a pending connection with them."; - result->Set({Status::kAlreadyConnectedToEndpoint}); + << "Discovered endpoint not found: endpoint_id=" << endpoint_id; + result->Set({Status::kEndpointUnknown}); return; } - // If our child class says we can't send any more outgoing connections, - // listen to them. - if (client->ShouldEnforceTopologyConstraints() && - !CanSendOutgoingConnection(client)) { + auto remote_bluetooth_mac_address = BluetoothUtils::ToString( + connection_options.remote_bluetooth_mac_address); + if (!remote_bluetooth_mac_address.empty()) { + if (AppendRemoteBluetoothMacAddressEndpoint( + endpoint_id, remote_bluetooth_mac_address, + client->GetDiscoveryOptions())) + NEARBY_LOGS(INFO) + << "Appended remote Bluetooth MAC Address endpoint [" + << remote_bluetooth_mac_address << "]"; + } + + if (AppendWebRTCEndpoint(endpoint_id, client->GetDiscoveryOptions())) + NEARBY_LOGS(INFO) << "Appended Web RTC endpoint."; + + auto discovered_endpoints = GetDiscoveredEndpoints(endpoint_id); + std::unique_ptr channel; + ConnectImplResult connect_impl_result; + + for (auto connect_endpoint : discovered_endpoints) { + if (!MediumSupportedByClientOptions(connect_endpoint->medium, + connection_options)) + continue; + connect_impl_result = ConnectImpl(client, connect_endpoint); + if (connect_impl_result.status.Ok()) { + channel = std::move(connect_impl_result.endpoint_channel); + break; + } + } + + Medium channel_medium = + channel ? channel->GetMedium() : Medium::UNKNOWN_MEDIUM; + if (channel == nullptr) { NEARBY_LOGS(INFO) - << "In requestConnection(), client=" << client->GetClientId() - << " attempted a connection with endpoint(id=" << endpoint_id - << "), but outgoing connections are disallowed"; - result->Set({Status::kOutOfOrderApiCall}); + << "Endpoint channel not available: endpoint_id=" << endpoint_id; + ProcessPreConnectionInitiationFailure( + client, channel_medium, endpoint_id, channel.get(), + /* is_incoming = */ false, start_time, connect_impl_result.status, + result.get()); + return; + } + + NEARBY_LOGS(INFO) + << "In requestConnection(), wrote ConnectionRequestFrame " + "to endpoint_id=" + << endpoint_id; + + ConnectionInfo connection_info = + FillConnectionInfo(client, info, connection_options); + + const NearbyDevice* local_device = client->GetLocalDevice(); + Exception write_exception = WriteConnectionRequestFrame( + local_device->GetType(), local_device->ToProtoBytes(), + connection_info, channel.get()); + + if (!write_exception.Ok()) { + NEARBY_LOGS(INFO) << "Failed to send connection request: endpoint_id=" + << endpoint_id; + ProcessPreConnectionInitiationFailure( + client, channel_medium, endpoint_id, channel.get(), + /* is_incoming = */ false, start_time, {Status::kEndpointIoError}, + result.get()); + return; + } + + NEARBY_LOGS(INFO) << "Adding connection to pending set: endpoint_id=" + << endpoint_id; + + // We've successfully connected to the device, and are now about to jump + // on to the EncryptionRunner thread to start running our encryption + // protocol. We'll mark ourselves as pending in case we get another call + // to RequestConnection or OnIncomingConnection, so that we can cancel + // the connection if needed. + // Not using designated initializers here since the VS C++ compiler + // errors out indicating that MediumSelector is not an aggregate + // TODO(b/300149127): Add test coverage to `PendingConnectionInfo` + // fields. + PendingConnectionInfo pendingConnectionInfo{}; + pendingConnectionInfo.client = client; + pendingConnectionInfo.remote_endpoint_info = endpoint->endpoint_info; + pendingConnectionInfo.nonce = connection_info.nonce; + pendingConnectionInfo.is_incoming = false; + pendingConnectionInfo.start_time = start_time; + pendingConnectionInfo.listener = info.listener; + pendingConnectionInfo.connection_options = connection_options; + pendingConnectionInfo.result = result; + pendingConnectionInfo.channel = std::move(channel); + + EndpointChannel* endpoint_channel = + pending_connections_ + .emplace(endpoint_id, std::move(pendingConnectionInfo)) + .first->second.channel.get(); + + NEARBY_LOGS(INFO) << "Initiating secure connection: endpoint_id=" + << endpoint_id; + // Next, we'll set up encryption. When it's done, our future will return + // and RequestConnection() will finish. + encryption_runner_.StartClient(client, endpoint_id, endpoint_channel, + GetResultListener()); + }); + NEARBY_LOGS(INFO) << "Waiting for connection to complete: endpoint_id=" + << endpoint_id; + auto status = + WaitForResult(absl::StrCat("RequestConnection(", endpoint_id, ")"), + client->GetClientId(), result.get()); + NEARBY_LOGS(INFO) << "Wait is complete: endpoint_id=" << endpoint_id + << "; status=" << status.value; + return status; +} + +Status BasePcpHandler::RequestConnectionV3( + ClientProxy* client, const NearbyDevice& remote_device, + const ConnectionRequestInfo& info, + const ConnectionOptions& connection_options) { + auto result = std::make_shared>(); + std::string endpoint_id = remote_device.GetEndpointId(); + RunOnPcpHandlerThread( + "request-connection-v3", + [this, client, &info, connection_options, &remote_device, + result]() RUN_ON_PCP_HANDLER_THREAD() { + absl::Time start_time = SystemClock::ElapsedRealtime(); + std::string endpoint_id = remote_device.GetEndpointId(); + + auto connection_request_verification_status = + VerifyConnectionRequest(endpoint_id, client); + if (!connection_request_verification_status.Ok()) { + result->Set(connection_request_verification_status); return; } @@ -692,7 +805,7 @@ Status BasePcpHandler::RequestConnection( } NEARBY_LOGS(INFO) - << "In requestConnection(), wrote ConnectionRequestFrame " + << "In requestConnectionV3(), wrote ConnectionRequestFrame " "to endpoint_id=" << endpoint_id; @@ -1670,6 +1783,33 @@ bool BasePcpHandler::BreakTie(ClientProxy* client, return false; } +Status BasePcpHandler::VerifyConnectionRequest(const std::string& endpoint_id, + ClientProxy* client) { + // If we already have a pending connection, then we shouldn't allow any + // more outgoing connections to this endpoint. + if (pending_connections_.count(endpoint_id)) { + NEARBY_LOGS(INFO) + << "In requestConnection(), connection requested with " + "endpoint(id=" + << endpoint_id + << "), but we already have a pending connection with them."; + return {Status::kAlreadyConnectedToEndpoint}; + } + + // If our child class says we can't send any more outgoing connections, + // listen to them. + if (client->ShouldEnforceTopologyConstraints() && + !CanSendOutgoingConnection(client)) { + NEARBY_LOGS(INFO) << "In requestConnection(), client=" + << client->GetClientId() + << " attempted a connection with endpoint(id=" + << endpoint_id + << "), but outgoing connections are disallowed"; + return {Status::kOutOfOrderApiCall}; + } + return {Status::kSuccess}; +} + void BasePcpHandler::ProcessTieBreakLoss( ClientProxy* client, const std::string& endpoint_id, BasePcpHandler::PendingConnectionInfo* info) { diff --git a/connections/implementation/base_pcp_handler.h b/connections/implementation/base_pcp_handler.h index 07496504..b40d6c0d 100644 --- a/connections/implementation/base_pcp_handler.h +++ b/connections/implementation/base_pcp_handler.h @@ -126,6 +126,11 @@ class BasePcpHandler : public PcpHandler, const ConnectionRequestInfo& info, const ConnectionOptions& connection_options) override; + Status RequestConnectionV3( + ClientProxy* client, const NearbyDevice& remote_device, + const ConnectionRequestInfo& info, + const ConnectionOptions& connection_options) override; + // Called by either party to accept connection on their part. // Until both parties call it, connection will not reach a data phase. // Updates state in ClientProxy. @@ -410,6 +415,9 @@ class BasePcpHandler : public PcpHandler, // Pass Reject notification to client. void LocalEndpointRejectedConnection(const std::string& endpoint_id); + // Check for a pending connection to |endpoint_id|. + bool HasPendingConnectionToEndpoint(const std::string& endpoint_id); + // Client state tracker to report events to. Never changes. Always valid. ClientProxy* client = nullptr; // Peer endpoint info, or empty, if not discovered yet. May change. @@ -497,6 +505,9 @@ class BasePcpHandler : public PcpHandler, const DiscoveryOptions& local_discovery_options) ABSL_LOCKS_EXCLUDED(discovered_endpoint_mutex_); + Status VerifyConnectionRequest(const std::string& endpoint_id, + ClientProxy* client); + // Returns true if the webrtc endpoint is created and appended into // discovered_endpoints_ with key endpoint_id. bool AppendWebRTCEndpoint(const std::string& endpoint_id, diff --git a/connections/implementation/base_pcp_handler_test.cc b/connections/implementation/base_pcp_handler_test.cc index 59cdded1..2e2831dc 100644 --- a/connections/implementation/base_pcp_handler_test.cc +++ b/connections/implementation/base_pcp_handler_test.cc @@ -39,6 +39,7 @@ #include "connections/implementation/endpoint_manager.h" #include "connections/implementation/flags/nearby_connections_feature_flags.h" #include "connections/implementation/mediums/mediums.h" +#include "connections/implementation/mock_device.h" #include "connections/implementation/offline_frames.h" #include "connections/implementation/pcp.h" #include "connections/implementation/proto/offline_wire_formats.pb.h" @@ -71,9 +72,12 @@ using ::testing::_; using ::testing::AtLeast; using ::testing::Invoke; using ::testing::MockFunction; +using ::testing::NiceMock; using ::testing::Return; using ::testing::StrictMock; +constexpr absl::string_view kTestEndpointId = "REMOTETEST"; + constexpr std::array kFakeMacAddress = {'a', 'b', 'c', 'd', 'e', 'f'}; constexpr BooleanMediumSelector kTestCases[] = { @@ -108,7 +112,7 @@ constexpr BooleanMediumSelector kTestCases[] = { class FakePresenceDevice : public NearbyDevice { public: - std::string GetEndpointId() const override { return "TEST"; } + std::string GetEndpointId() const override { return "LOCALTEST"; } MOCK_METHOD(std::vector, GetConnectionInfos, (), (const override)); MOCK_METHOD(NearbyDevice::Type, GetType, (), (const override)); @@ -498,6 +502,10 @@ class BasePcpHandlerTest std::move(output_b)); auto channel_b = std::make_unique(std::move(input_b), std::move(output_a)); + ON_CALL(mock_device_, GetType) + .WillByDefault(Return(NearbyDevice::Type::kUnknownDevice)); + ON_CALL(mock_device_, GetEndpointId) + .WillByDefault(Return(std::string(kTestEndpointId))); // On initiator (A) side, we drop the first write, since this is a // connection establishment packet, and we don't have the peer entity, just // the peer channel. The rest of the exchange must happen for the benefit of @@ -530,6 +538,46 @@ class BasePcpHandlerTest return std::make_pair(std::move(channel_a), std::move(channel_b)); } + std::pair, + std::unique_ptr> + SetupConnectionForConnectFailure( + location::nearby::proto::connections::Medium medium) { // NOLINT + auto [input_a, output_a] = CreatePipe(); + auto [input_b, output_b] = CreatePipe(); + auto channel_a = std::make_unique(std::move(input_a), + std::move(output_b)); + auto channel_b = std::make_unique(std::move(input_b), + std::move(output_a)); + ON_CALL(mock_device_, GetType) + .WillByDefault(Return(NearbyDevice::Type::kUnknownDevice)); + ON_CALL(mock_device_, GetEndpointId) + .WillByDefault(Return(std::string(kTestEndpointId))); + // On initiator (A) side, we drop the first write, since this is a + // connection establishment packet, and we don't have the peer entity, just + // the peer channel. The rest of the exchange must happen for the benefit of + // DH key exchange. + EXPECT_CALL(*channel_a, Read()) + .WillRepeatedly(Invoke( + [channel = channel_a.get()]() { return channel->DoRead(); })); + EXPECT_CALL(*channel_a, GetMedium).WillRepeatedly(Return(medium)); + EXPECT_CALL(*channel_a, GetLastReadTimestamp) + .WillRepeatedly(Return(absl::Now())); + EXPECT_CALL(*channel_a, IsPaused).WillRepeatedly(Return(false)); + EXPECT_CALL(*channel_b, Read()) + .WillRepeatedly(Invoke( + [channel = channel_b.get()]() { return channel->DoRead(); })); + EXPECT_CALL(*channel_b, Write(_)) + .WillRepeatedly( + Invoke([channel = channel_b.get()](const ByteArray& data) { + return channel->DoWrite(data); + })); + EXPECT_CALL(*channel_b, GetMedium).WillRepeatedly(Return(medium)); + EXPECT_CALL(*channel_b, GetLastReadTimestamp) + .WillRepeatedly(Return(absl::Now())); + EXPECT_CALL(*channel_b, IsPaused).WillRepeatedly(Return(false)); + return std::make_pair(std::move(channel_a), std::move(channel_b)); + } + void RequestConnection( const std::string& endpoint_id, std::unique_ptr channel_a, @@ -601,6 +649,76 @@ class BasePcpHandlerTest NEARBY_LOG(INFO, "Stopping Encryption Runner"); } + void RequestConnectionV3( + const NearbyDevice& remote_device, + std::unique_ptr channel_a, + MockEndpointChannel* channel_b, ClientProxy* client, + MockPcpHandler* pcp_handler, + location::nearby::proto::connections::Medium connect_medium, + std::atomic_int* flag = nullptr, + Status expected_result = {Status::kSuccess}) { + ConnectionRequestInfo info{ + .endpoint_info = ByteArray{"ABCD"}, + .listener = connection_listener_, + }; + ConnectionOptions connection_options{ + .remote_bluetooth_mac_address = ByteArray{"\x12\x34\x56\x78\x9a\xbc"}, + .keep_alive_interval_millis = + FeatureFlags::GetInstance().GetFlags().keep_alive_interval_millis, + .keep_alive_timeout_millis = + FeatureFlags::GetInstance().GetFlags().keep_alive_timeout_millis, + }; + EXPECT_CALL(mock_discovery_listener_.endpoint_found_cb, Call); + EXPECT_CALL(*pcp_handler, CanSendOutgoingConnection) + .WillRepeatedly(Return(true)); + EXPECT_CALL(*pcp_handler, GetStrategy) + .WillRepeatedly(Return(Strategy::kP2pCluster)); + if (expected_result == Status{Status::kSuccess}) { + EXPECT_CALL(mock_connection_listener_.initiated_cb, Call).Times(1); + } + // Simulate successful discovery. + auto encryption_runner = std::make_unique(); + auto allowed_mediums = pcp_handler->GetDiscoveryMediums(client); + + EXPECT_CALL(*pcp_handler, ConnectImpl) + .WillRepeatedly( + Invoke([&channel_a, connect_medium]( + ClientProxy* client, + MockPcpHandler::DiscoveredEndpoint* endpoint) { + return MockPcpHandler::ConnectImplResult{ + .medium = connect_medium, + .status = {Status::kSuccess}, + .endpoint_channel = std::move(channel_a), + }; + })); + + for (const auto& discovered_medium : allowed_mediums) { + pcp_handler->OnEndpointFound( + client, + std::make_shared(MockDiscoveredEndpoint{ + { + remote_device.GetEndpointId(), + info.endpoint_info, + "service", + discovered_medium, + WebRtcState::kUndefined, + }, + MockContext{flag}, + })); + } + auto other_client = std::make_unique(); + + // Run peer crypto in advance, if channel_b is provided. + // Otherwise stay in not-encrypted state. + if (channel_b != nullptr) { + encryption_runner->StartServer( + other_client.get(), remote_device.GetEndpointId(), channel_b, {}); + } + EXPECT_EQ(pcp_handler->RequestConnectionV3(client, remote_device, info, + connection_options), + expected_result); + } + void RequestConnectionWifiLanFail( const std::string& endpoint_id, std::unique_ptr channel_a, @@ -704,6 +822,7 @@ class BasePcpHandlerTest }; SetSafeToDisconnect set_safe_to_disconnect_{true}; MediumEnvironment& env_ = MediumEnvironment::Instance(); + NiceMock mock_device_; }; TEST_P(BasePcpHandlerTest, ConstructorDestructorWorks) { @@ -955,7 +1074,6 @@ TEST_P(BasePcpHandlerTest, CanRequestConnectionPresence) { channel_b->Close(); bwu.Shutdown(); pcp_handler.DisconnectFromEndpointManager(); - env_.Stop(); } TEST_P(BasePcpHandlerTest, CanRequestConnectionLegacy) { @@ -989,6 +1107,216 @@ TEST_P(BasePcpHandlerTest, CanRequestConnectionLegacy) { env_.Stop(); } +TEST_P(BasePcpHandlerTest, RequestConnectionV3) { + env_.Start(); + ClientProxy client; + FakePresenceDeviceProvider provider; + EXPECT_CALL(provider.local_device_, GetType) + .WillRepeatedly(Return(NearbyDevice::Type::kUnknownDevice)); + EXPECT_CALL(provider.local_device_, ToProtoBytes); + client.RegisterDeviceProvider(&provider); + Mediums m; + EndpointChannelManager ecm; + EndpointManager em(&ecm); + BwuManager bwu(m, em, ecm, {}, {}); + MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); + StartDiscovery(&client, &pcp_handler); + auto mediums = pcp_handler.GetDiscoveryMediums(&client); + auto connect_medium = mediums[mediums.size() - 1]; + auto channel_pair = SetupConnection(connect_medium); + auto& channel_a = channel_pair.first; + const auto& channel_b = channel_pair.second; + EXPECT_CALL(*channel_a, CloseImpl).Times(1); + EXPECT_CALL(*channel_b, CloseImpl).Times(1); + EXPECT_CALL(mock_connection_listener_.rejected_cb, Call).Times(AtLeast(0)); + RequestConnectionV3(mock_device_, std::move(channel_a), channel_b.get(), + &client, &pcp_handler, connect_medium); + NEARBY_LOG(INFO, "RequestConnectionV3 complete"); + channel_b->Close(); + bwu.Shutdown(); + pcp_handler.DisconnectFromEndpointManager(); + env_.Stop(); +} + +TEST_P(BasePcpHandlerTest, RequestConnectionV3_ConnectImplFailure) { + env_.Start(); + ClientProxy client; + FakePresenceDeviceProvider provider; + EXPECT_CALL(provider.local_device_, GetType) + .WillRepeatedly(Return(NearbyDevice::Type::kUnknownDevice)); + client.RegisterDeviceProvider(&provider); + Mediums m; + EndpointChannelManager ecm; + EndpointManager em(&ecm); + BwuManager bwu(m, em, ecm, {}, {}); + MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); + StartDiscovery(&client, &pcp_handler); + auto mediums = pcp_handler.GetDiscoveryMediums(&client); + auto connect_medium = mediums[mediums.size() - 1]; + auto channel_pair = SetupConnectionForConnectFailure(connect_medium); + const auto& channel_b = channel_pair.second; + EXPECT_CALL(*channel_b, CloseImpl).Times(1); + EXPECT_CALL(mock_connection_listener_.rejected_cb, Call).Times(AtLeast(0)); + ConnectionRequestInfo info{ + .endpoint_info = ByteArray{"ABCD"}, + .listener = connection_listener_, + }; + ConnectionOptions connection_options{ + .remote_bluetooth_mac_address = ByteArray{"\x12\x34\x56\x78\x9a\xbc"}, + .keep_alive_interval_millis = + FeatureFlags::GetInstance().GetFlags().keep_alive_interval_millis, + .keep_alive_timeout_millis = + FeatureFlags::GetInstance().GetFlags().keep_alive_timeout_millis, + }; + EXPECT_CALL(mock_discovery_listener_.endpoint_found_cb, Call); + EXPECT_CALL(pcp_handler, CanSendOutgoingConnection) + .WillRepeatedly(Return(true)); + EXPECT_CALL(pcp_handler, GetStrategy) + .WillRepeatedly(Return(Strategy::kP2pCluster)); + // Simulate successful discovery. + auto encryption_runner = std::make_unique(); + auto allowed_mediums = pcp_handler.GetDiscoveryMediums(&client); + + EXPECT_CALL(pcp_handler, ConnectImpl) + .WillRepeatedly(Invoke( + [connect_medium](ClientProxy* client, + MockPcpHandler::DiscoveredEndpoint* endpoint) { + return MockPcpHandler::ConnectImplResult{ + .medium = connect_medium, + .status = {Status::kError}, + .endpoint_channel = nullptr, + }; + })); + + for (const auto& discovered_medium : allowed_mediums) { + pcp_handler.OnEndpointFound( + &client, + std::make_shared(MockDiscoveredEndpoint{ + { + mock_device_.GetEndpointId(), + info.endpoint_info, + "service", + discovered_medium, + WebRtcState::kUndefined, + }, + MockContext{nullptr}, + })); + } + + Status expected_result = {Status::kError}; + EXPECT_EQ(pcp_handler.RequestConnectionV3(&client, mock_device_, info, + connection_options), + expected_result); + NEARBY_LOG(INFO, "RequestConnectionV3 complete"); + channel_b->Close(); + bwu.Shutdown(); + pcp_handler.DisconnectFromEndpointManager(); + env_.Stop(); +} + +TEST_P(BasePcpHandlerTest, RequestConnection_ConnectImplFailure) { + env_.Start(); + ClientProxy client; + FakePresenceDeviceProvider provider; + EXPECT_CALL(provider.local_device_, GetType) + .WillRepeatedly(Return(NearbyDevice::Type::kUnknownDevice)); + client.RegisterDeviceProvider(&provider); + Mediums m; + EndpointChannelManager ecm; + EndpointManager em(&ecm); + BwuManager bwu(m, em, ecm, {}, {}); + MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); + StartDiscovery(&client, &pcp_handler); + auto mediums = pcp_handler.GetDiscoveryMediums(&client); + auto connect_medium = mediums[mediums.size() - 1]; + auto channel_pair = SetupConnectionForConnectFailure(connect_medium); + const auto& channel_b = channel_pair.second; + EXPECT_CALL(*channel_b, CloseImpl).Times(1); + EXPECT_CALL(mock_connection_listener_.rejected_cb, Call).Times(AtLeast(0)); + ConnectionRequestInfo info{ + .endpoint_info = ByteArray{"ABCD"}, + .listener = connection_listener_, + }; + ConnectionOptions connection_options{ + .remote_bluetooth_mac_address = ByteArray{"\x12\x34\x56\x78\x9a\xbc"}, + .keep_alive_interval_millis = + FeatureFlags::GetInstance().GetFlags().keep_alive_interval_millis, + .keep_alive_timeout_millis = + FeatureFlags::GetInstance().GetFlags().keep_alive_timeout_millis, + }; + EXPECT_CALL(mock_discovery_listener_.endpoint_found_cb, Call); + EXPECT_CALL(pcp_handler, CanSendOutgoingConnection) + .WillRepeatedly(Return(true)); + EXPECT_CALL(pcp_handler, GetStrategy) + .WillRepeatedly(Return(Strategy::kP2pCluster)); + // Simulate successful discovery. + auto encryption_runner = std::make_unique(); + auto allowed_mediums = pcp_handler.GetDiscoveryMediums(&client); + + EXPECT_CALL(pcp_handler, ConnectImpl) + .WillRepeatedly(Invoke( + [connect_medium](ClientProxy* client, + MockPcpHandler::DiscoveredEndpoint* endpoint) { + return MockPcpHandler::ConnectImplResult{ + .medium = connect_medium, + .status = {Status::kError}, + .endpoint_channel = nullptr, + }; + })); + + for (const auto& discovered_medium : allowed_mediums) { + pcp_handler.OnEndpointFound( + &client, + std::make_shared(MockDiscoveredEndpoint{ + { + std::string(kTestEndpointId), + info.endpoint_info, + "service", + discovered_medium, + WebRtcState::kUndefined, + }, + MockContext{nullptr}, + })); + } + Status expected_result = {Status::kError}; + EXPECT_EQ(pcp_handler.RequestConnection(&client, std::string(kTestEndpointId), + info, connection_options), + expected_result); + NEARBY_LOG(INFO, "RequestConnection complete"); + channel_b->Close(); + bwu.Shutdown(); + pcp_handler.DisconnectFromEndpointManager(); + env_.Stop(); +} + +TEST_P(BasePcpHandlerTest, IoError_RequestConnectionV3Fails) { + env_.Start(); + ClientProxy client; + Mediums m; + EndpointChannelManager ecm; + EndpointManager em(&ecm); + BwuManager bwu(m, em, ecm, {}, {}); + MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); + StartDiscovery(&client, &pcp_handler); + auto mediums = pcp_handler.GetDiscoveryMediums(&client); + auto connect_medium = mediums[mediums.size() - 1]; + auto channel_pair = SetupConnection(connect_medium); + auto& channel_a = channel_pair.first; + auto& channel_b = channel_pair.second; + EXPECT_CALL(*channel_a, CloseImpl).Times(AtLeast(1)); + EXPECT_CALL(*channel_b, CloseImpl).Times(AtLeast(1)); + channel_b->broken_write_ = true; + EXPECT_CALL(mock_connection_listener_.rejected_cb, Call).Times(AtLeast(0)); + RequestConnectionV3(mock_device_, std::move(channel_a), channel_b.get(), + &client, &pcp_handler, connect_medium, nullptr, + {Status::kEndpointIoError}); + NEARBY_LOG(INFO, "RequestConnectionV3 complete"); + channel_b->Close(); + bwu.Shutdown(); + pcp_handler.DisconnectFromEndpointManager(); + env_.Stop(); +} + TEST_P(BasePcpHandlerTest, IoError_RequestConnectionFails) { env_.Start(); std::string endpoint_id{"1234"}; diff --git a/connections/implementation/mock_device.h b/connections/implementation/mock_device.h new file mode 100644 index 00000000..a764df9a --- /dev/null +++ b/connections/implementation/mock_device.h @@ -0,0 +1,37 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef CORE_INTERNAL_MOCK_DEVICE +#define CORE_INTERNAL_MOCK_DEVICE + +#include +#include + +#include "gmock/gmock.h" +#include "internal/interop/device.h" + +namespace nearby { + +class MockNearbyDevice : public NearbyDevice { + public: + MOCK_METHOD(NearbyDevice::Type, GetType, (), (const override)); + MOCK_METHOD(std::string, GetEndpointId, (), (const override)); + MOCK_METHOD(std::vector, GetConnectionInfos, (), + (const override)); + MOCK_METHOD(std::string, ToProtoBytes, (), (const override)); +}; + +} // namespace nearby + +#endif // CORE_INTERNAL_MOCK_DEVICE diff --git a/connections/implementation/mock_service_controller.h b/connections/implementation/mock_service_controller.h index adff80b3..564b4257 100644 --- a/connections/implementation/mock_service_controller.h +++ b/connections/implementation/mock_service_controller.h @@ -21,6 +21,7 @@ #include "gmock/gmock.h" #include "connections/implementation/service_controller.h" #include "connections/v3/connection_listening_options.h" +#include "internal/interop/device.h" namespace nearby { namespace connections { @@ -72,6 +73,12 @@ class MockServiceController : public ServiceController { const ConnectionOptions& connection_options), (override)); + MOCK_METHOD(Status, RequestConnectionV3, + (ClientProxy * client, const NearbyDevice& remote_device, + const ConnectionRequestInfo& info, + const ConnectionOptions& connection_options), + (override)); + MOCK_METHOD(Status, AcceptConnection, (ClientProxy * client, const std::string& endpoint_id, PayloadListener listener), diff --git a/connections/implementation/offline_service_controller.cc b/connections/implementation/offline_service_controller.cc index edd2cce5..3ae1e27d 100644 --- a/connections/implementation/offline_service_controller.cc +++ b/connections/implementation/offline_service_controller.cc @@ -19,6 +19,7 @@ #include #include "absl/strings/str_join.h" +#include "internal/interop/device.h" namespace nearby { namespace connections { @@ -101,6 +102,18 @@ Status OfflineServiceController::RequestConnection( connection_options); } +Status OfflineServiceController::RequestConnectionV3( + ClientProxy* client, const NearbyDevice& remote_device, + const ConnectionRequestInfo& info, + const ConnectionOptions& connection_options) { + if (stop_) return {Status::kOutOfOrderApiCall}; + NEARBY_LOGS(INFO) << "Client " << client->GetClientId() + << " requested a connection to endpoint_id=" + << remote_device.GetEndpointId(); + return pcp_manager_.RequestConnectionV3(client, remote_device, info, + connection_options); +} + Status OfflineServiceController::AcceptConnection( ClientProxy* client, const std::string& endpoint_id, PayloadListener listener) { diff --git a/connections/implementation/offline_service_controller.h b/connections/implementation/offline_service_controller.h index dd7e4ae7..13661961 100644 --- a/connections/implementation/offline_service_controller.h +++ b/connections/implementation/offline_service_controller.h @@ -67,6 +67,11 @@ class OfflineServiceController : public ServiceController { ClientProxy* client, const std::string& endpoint_id, const ConnectionRequestInfo& info, const ConnectionOptions& connection_options) override; + + Status RequestConnectionV3( + ClientProxy* client, const NearbyDevice& remote_device, + const ConnectionRequestInfo& info, + const ConnectionOptions& connection_options) override; Status AcceptConnection(ClientProxy* client, const std::string& endpoint_id, PayloadListener listener) override; Status RejectConnection(ClientProxy* client, diff --git a/connections/implementation/offline_service_controller_test.cc b/connections/implementation/offline_service_controller_test.cc index 5173dc1f..eede7888 100644 --- a/connections/implementation/offline_service_controller_test.cc +++ b/connections/implementation/offline_service_controller_test.cc @@ -25,6 +25,7 @@ #include "connections/advertising_options.h" #include "connections/discovery_options.h" #include "connections/implementation/flags/nearby_connections_feature_flags.h" +#include "connections/implementation/mock_device.h" #include "connections/implementation/offline_simulation_user.h" #include "connections/listeners.h" #include "connections/medium_selector.h" @@ -249,6 +250,26 @@ TEST_P(OfflineServiceControllerTest, CanConnect) { env_.Stop(); } +TEST_P(OfflineServiceControllerTest, CanConnectV3) { + env_.Start(); + OfflineSimulationUser user_a(kDeviceA, GetParam()); + OfflineSimulationUser user_b(kDeviceB, GetParam()); + EXPECT_THAT(user_a.StartAdvertising(std::string(kServiceId), &connect_latch_), + Eq(Status{Status::kSuccess})); + EXPECT_THAT(user_b.StartDiscovery(std::string(kServiceId), &discover_latch_), + Eq(Status{Status::kSuccess})); + EXPECT_TRUE(discover_latch_.Await(kLongTimeout)); + auto remote_device = MockNearbyDevice(); + ON_CALL(remote_device, GetEndpointId) + .WillByDefault(testing::Return(user_b.GetDiscovered().endpoint_id)); + EXPECT_THAT(user_b.RequestConnectionV3(&connect_latch_, remote_device), + Eq(Status{Status::kSuccess})); + EXPECT_TRUE(connect_latch_.Await(kLongTimeout)); + user_a.Stop(); + user_b.Stop(); + env_.Stop(); +} + TEST_P(OfflineServiceControllerTest, CanAcceptConnection) { env_.Start(); OfflineSimulationUser user_a(kDeviceA, GetParam()); diff --git a/connections/implementation/offline_simulation_user.cc b/connections/implementation/offline_simulation_user.cc index ae31da9f..42a6e175 100644 --- a/connections/implementation/offline_simulation_user.cc +++ b/connections/implementation/offline_simulation_user.cc @@ -17,6 +17,7 @@ #include "absl/functional/any_invocable.h" #include "absl/functional/bind_front.h" #include "connections/listeners.h" +#include "internal/interop/device.h" #include "internal/platform/byte_array.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/system_clock.h" @@ -186,6 +187,30 @@ Status OfflineSimulationUser::RequestConnection(CountDownLatch* latch) { connection_options_); } +Status OfflineSimulationUser::RequestConnectionV3( + CountDownLatch* latch, const NearbyDevice& remote_device) { + initiated_latch_ = latch; + ConnectionListener listener = { + .initiated_cb = + std::bind(&OfflineSimulationUser::OnConnectionInitiated, this, + std::placeholders::_1, std::placeholders::_2, true), + .accepted_cb = + absl::bind_front(&OfflineSimulationUser::OnConnectionAccepted, this), + .rejected_cb = + absl::bind_front(&OfflineSimulationUser::OnConnectionRejected, this), + .disconnected_cb = + absl::bind_front(&OfflineSimulationUser::OnEndpointDisconnect, this), + }; + client_.AddCancellationFlag(remote_device.GetEndpointId()); + return ctrl_.RequestConnectionV3( + &client_, remote_device, + { + .endpoint_info = discovered_.endpoint_info, + .listener = std::move(listener), + }, + connection_options_); +} + Status OfflineSimulationUser::AcceptConnection(CountDownLatch* latch) { accept_latch_ = latch; PayloadListener listener = { diff --git a/connections/implementation/offline_simulation_user.h b/connections/implementation/offline_simulation_user.h index 12e46d60..e5ba3673 100644 --- a/connections/implementation/offline_simulation_user.h +++ b/connections/implementation/offline_simulation_user.h @@ -22,6 +22,7 @@ #include "absl/strings/string_view.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/offline_service_controller.h" +#include "internal/interop/device.h" #include "internal/platform/atomic_boolean.h" #include "internal/platform/condition_variable.h" #include "internal/platform/count_down_latch.h" @@ -108,6 +109,12 @@ class OfflineSimulationUser { // callback. Status RequestConnection(CountDownLatch* latch); + // Calls PcpManager::RequestConnectionV3. + // If latch is provided, latch->CountDown() will be called in the initiated_cb + // callback. + Status RequestConnectionV3(CountDownLatch* latch, + const NearbyDevice& remote_device); + // Calls PcpManager::AcceptConnection. // If latch is provided, latch->CountDown() will be called in the accepted_cb // callback. diff --git a/connections/implementation/pcp_handler.h b/connections/implementation/pcp_handler.h index 8a738e8f..d156a916 100644 --- a/connections/implementation/pcp_handler.h +++ b/connections/implementation/pcp_handler.h @@ -25,6 +25,7 @@ #include "connections/params.h" #include "connections/status.h" #include "connections/strategy.h" +#include "internal/interop/device.h" namespace nearby { namespace connections { @@ -109,6 +110,11 @@ class PcpHandler { const ConnectionRequestInfo& info, const ConnectionOptions& connection_options) = 0; + virtual Status RequestConnectionV3( + ClientProxy* client, const NearbyDevice& remote_device, + const ConnectionRequestInfo& info, + const ConnectionOptions& connection_options) = 0; + // Either party may call this to accept connection on their part. // Until both parties call it, connection will not reach a data phase. // Update state in ClientProxy. diff --git a/connections/implementation/pcp_manager.cc b/connections/implementation/pcp_manager.cc index 2c78f57c..91b7fa14 100644 --- a/connections/implementation/pcp_manager.cc +++ b/connections/implementation/pcp_manager.cc @@ -20,6 +20,7 @@ #include "connections/implementation/p2p_point_to_point_pcp_handler.h" #include "connections/implementation/p2p_star_pcp_handler.h" #include "connections/implementation/pcp_handler.h" +#include "internal/interop/device.h" namespace nearby { namespace connections { @@ -127,6 +128,19 @@ Status PcpManager::RequestConnection( connection_options); } +Status PcpManager::RequestConnectionV3( + ClientProxy* client, const NearbyDevice& remote_device, + const ConnectionRequestInfo& info, + const ConnectionOptions& connection_options) { + // TODO(b/300174495): Add test coverage for when |current_| is nullptr. + if (!current_) { + return {Status::kOutOfOrderApiCall}; + } + + return current_->RequestConnectionV3(client, remote_device, info, + connection_options); +} + Status PcpManager::AcceptConnection(ClientProxy* client, const string& endpoint_id, PayloadListener payload_listener) { diff --git a/connections/implementation/pcp_manager.h b/connections/implementation/pcp_manager.h index 5e59a6c5..2596e56f 100644 --- a/connections/implementation/pcp_manager.h +++ b/connections/implementation/pcp_manager.h @@ -71,6 +71,11 @@ class PcpManager { Status RequestConnection(ClientProxy* client, const string& endpoint_id, const ConnectionRequestInfo& info, const ConnectionOptions& connection_options); + + Status RequestConnectionV3(ClientProxy* client, + const NearbyDevice& remote_device, + const ConnectionRequestInfo& info, + const ConnectionOptions& connection_options); Status AcceptConnection(ClientProxy* client, const string& endpoint_id, PayloadListener payload_listener); Status RejectConnection(ClientProxy* client, const string& endpoint_id); diff --git a/connections/implementation/pcp_manager_test.cc b/connections/implementation/pcp_manager_test.cc index abaac561..ce2c1698 100644 --- a/connections/implementation/pcp_manager_test.cc +++ b/connections/implementation/pcp_manager_test.cc @@ -16,12 +16,14 @@ #include #include +#include #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" #include "absl/time/time.h" #include "connections/implementation/endpoint_channel_manager.h" +#include "connections/implementation/mock_device.h" #include "connections/implementation/simulation_user.h" #include "connections/medium_selector.h" #include "connections/v3/connection_listening_options.h" @@ -32,6 +34,8 @@ namespace nearby { namespace connections { namespace { +using ::testing::Return; + constexpr std::array kFakeMacAddress = {'a', 'b', 'c', 'd', 'e', 'f'}; constexpr char kServiceId[] = "service-id"; constexpr char kDeviceA[] = "device-A"; @@ -203,6 +207,27 @@ TEST_P(PcpManagerTest, StartListeningForIncomingConnectionsFailsNoStrategy) { env_.Stop(); } +TEST_P(PcpManagerTest, CanConnectV3) { + env_.Start(); + SimulationUser user_a("device-a", GetParam()); + SimulationUser user_b("device-b", GetParam()); + CountDownLatch discovery_latch(1); + CountDownLatch connection_latch(2); + user_a.StartAdvertising(kServiceId, &connection_latch); + user_b.StartDiscovery(kServiceId, &discovery_latch); + EXPECT_TRUE(discovery_latch.Await(absl::Milliseconds(1000)).result()); + EXPECT_EQ(user_b.GetDiscovered().service_id, kServiceId); + EXPECT_EQ(user_b.GetDiscovered().endpoint_info, user_a.GetInfo()); + auto remote_device = MockNearbyDevice(); + EXPECT_CALL(remote_device, GetEndpointId) + .WillRepeatedly(Return(std::string(user_b.GetDiscovered().endpoint_id))); + user_b.RequestConnectionV3(&connection_latch, remote_device); + EXPECT_TRUE(connection_latch.Await(absl::Milliseconds(1000)).result()); + user_a.Stop(); + user_b.Stop(); + env_.Stop(); +} + INSTANTIATE_TEST_SUITE_P(ParametrisedPcpManagerTest, PcpManagerTest, ::testing::ValuesIn(kTestCases)); diff --git a/connections/implementation/service_controller.h b/connections/implementation/service_controller.h index c8ca7742..8a5acf39 100644 --- a/connections/implementation/service_controller.h +++ b/connections/implementation/service_controller.h @@ -29,6 +29,7 @@ #include "connections/status.h" #include "connections/v3/connection_listening_options.h" #include "connections/v3/listeners.h" +#include "internal/interop/device.h" namespace nearby { namespace connections { @@ -92,6 +93,11 @@ class ServiceController { ClientProxy* client, const std::string& endpoint_id, const ConnectionRequestInfo& info, const ConnectionOptions& connection_options) = 0; + + virtual Status RequestConnectionV3( + ClientProxy* client, const NearbyDevice& remote_device, + const ConnectionRequestInfo& info, + const ConnectionOptions& connection_options) = 0; virtual Status AcceptConnection(ClientProxy* client, const std::string& endpoint_id, PayloadListener listener) = 0; diff --git a/connections/implementation/service_controller_router.cc b/connections/implementation/service_controller_router.cc index e50a3999..b6053718 100644 --- a/connections/implementation/service_controller_router.cc +++ b/connections/implementation/service_controller_router.cc @@ -400,10 +400,10 @@ void ServiceControllerRouter::RequestConnectionV3( client->AddCancellationFlag(remote_device.GetEndpointId()); RouteToServiceController( - "scr-request-connection", - [this, client, endpoint_id = remote_device.GetEndpointId(), - v3_info = std::move(info), connection_options, - callback = std::move(callback)]() mutable { + "scr-request-connection-v3", + [this, client, &remote_device, v3_info = std::move(info), + connection_options, callback = std::move(callback)]() mutable { + std::string endpoint_id = remote_device.GetEndpointId(); if (client->HasPendingConnectionToEndpoint(endpoint_id) || client->IsConnectedToEndpoint(endpoint_id)) { callback({Status::kAlreadyConnectedToEndpoint}); @@ -420,7 +420,7 @@ void ServiceControllerRouter::RequestConnectionV3( ConnectionListener listener = { .initiated_cb = - [&v3_info]( + [&v3_info, &remote_device]( const std::string& endpoint_id, const ConnectionResponseInfo& response_info) mutable { v3::InitialConnectionInfo new_info = { @@ -431,10 +431,7 @@ void ServiceControllerRouter::RequestConnectionV3( .is_incoming_connection = response_info.is_incoming_connection, }; - v3::ConnectionsDevice device( - endpoint_id, - response_info.remote_endpoint_info.AsStringView(), {}); - v3_info.listener.initiated_cb(device, new_info); + v3_info.listener.initiated_cb(remote_device, new_info); }, .accepted_cb = [result_cb = v3_info.listener.result_cb]( @@ -473,8 +470,8 @@ void ServiceControllerRouter::RequestConnectionV3( .endpoint_info = ByteArray(endpoint_info), .listener = std::move(listener), }; - Status status = GetServiceController()->RequestConnection( - client, endpoint_id, std::move(old_info), connection_options); + Status status = GetServiceController()->RequestConnectionV3( + client, remote_device, std::move(old_info), connection_options); if (!status.Ok()) { NEARBY_LOGS(WARNING) << "Unable to request connection to endpoint " << endpoint_id << ": " << status.ToString(); diff --git a/connections/implementation/service_controller_router_test.cc b/connections/implementation/service_controller_router_test.cc index be3c7e0a..e636e30f 100644 --- a/connections/implementation/service_controller_router_test.cc +++ b/connections/implementation/service_controller_router_test.cc @@ -282,9 +282,9 @@ class ServiceControllerRouterTest : public testing::Test { // If we set check_result to false, we expect that RequestConnection will // not be called. if (check_result) { - EXPECT_CALL(*mock_, RequestConnection) + EXPECT_CALL(*mock_, RequestConnectionV3) .WillOnce([call_all_cb, endpoint_info_present, this]( - ClientProxy*, const std::string&, + ClientProxy*, const NearbyDevice&, const ConnectionRequestInfo& info, const ConnectionOptions&) { EXPECT_EQ(info.endpoint_info.Empty(), !endpoint_info_present); diff --git a/connections/implementation/simulation_user.cc b/connections/implementation/simulation_user.cc index 0c6dd570..99a0918f 100644 --- a/connections/implementation/simulation_user.cc +++ b/connections/implementation/simulation_user.cc @@ -16,6 +16,7 @@ #include "absl/functional/bind_front.h" #include "connections/listeners.h" +#include "internal/interop/device.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/system_clock.h" @@ -163,6 +164,29 @@ void SimulationUser::RequestConnection(CountDownLatch* latch) { .Ok()); } +void SimulationUser::RequestConnectionV3(CountDownLatch* latch, + const NearbyDevice& remote_device) { + initiated_latch_ = latch; + ConnectionListener listener = { + .initiated_cb = + std::bind(&SimulationUser::OnConnectionInitiated, this, + std::placeholders::_1, std::placeholders::_2, true), + .accepted_cb = + absl::bind_front(&SimulationUser::OnConnectionAccepted, this), + .rejected_cb = + absl::bind_front(&SimulationUser::OnConnectionRejected, this), + }; + client_.AddCancellationFlag(remote_device.GetEndpointId()); + EXPECT_TRUE( + mgr_.RequestConnectionV3(&client_, remote_device, + { + .endpoint_info = discovered_.endpoint_info, + .listener = std::move(listener), + }, + connection_options_) + .Ok()); +} + void SimulationUser::AcceptConnection(CountDownLatch* latch) { accept_latch_ = latch; PayloadListener listener = { diff --git a/connections/implementation/simulation_user.h b/connections/implementation/simulation_user.h index 7a66e4b7..78625612 100644 --- a/connections/implementation/simulation_user.h +++ b/connections/implementation/simulation_user.h @@ -27,6 +27,7 @@ #include "connections/implementation/injected_bluetooth_device_store.h" #include "connections/implementation/payload_manager.h" #include "connections/implementation/pcp_manager.h" +#include "connections/v3/connections_device.h" #include "internal/flags/nearby_flags.h" #include "internal/platform/condition_variable.h" #include "internal/platform/count_down_latch.h" @@ -128,6 +129,12 @@ class SimulationUser { // callback. void RequestConnection(CountDownLatch* latch); + // Calls PcpManager::RequestConnectionV3. + // If latch is provided, latch->CountDown() will be called in the initiated_cb + // callback. + void RequestConnectionV3(CountDownLatch* latch, + const NearbyDevice& remote_device); + // Calls PcpManager::AcceptConnection. // If latch is provided, latch->CountDown() will be called in the accepted_cb // callback. From 091b4ebfa567cf69ad580bffac50ffa025901e3a Mon Sep 17 00:00:00 2001 From: hai007 Date: Thu, 14 Sep 2023 09:36:27 -0700 Subject: [PATCH 014/683] Hotspot Test Code PiperOrigin-RevId: 565393814 --- .../platform/implementation/windows/BUILD | 2 + .../platform/implementation/windows/wifi.h | 2 +- .../windows/wifi_hotspot_test.cc | 136 ++++++++++++++++++ .../windows/wifi_medium_test.cc | 54 +++++++ 4 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 internal/platform/implementation/windows/wifi_hotspot_test.cc create mode 100644 internal/platform/implementation/windows/wifi_medium_test.cc diff --git a/internal/platform/implementation/windows/BUILD b/internal/platform/implementation/windows/BUILD index 218b43de..e58ad6a9 100644 --- a/internal/platform/implementation/windows/BUILD +++ b/internal/platform/implementation/windows/BUILD @@ -277,6 +277,8 @@ cc_test( "timer_test.cc", "utils_test.cc", "webrtc_test.cc", + "wifi_hotspot_test.cc", + "wifi_medium_test.cc", ], copts = ["-Ithird_party/nearby/internal/platform/implementation/windows/generated -DCORE_ADAPTER_DLL"], tags = ["notap"], diff --git a/internal/platform/implementation/windows/wifi.h b/internal/platform/implementation/windows/wifi.h index 01b4733b..885ded4f 100644 --- a/internal/platform/implementation/windows/wifi.h +++ b/internal/platform/implementation/windows/wifi.h @@ -15,8 +15,8 @@ #ifndef PLATFORM_IMPL_WINDOWS_WIFI_H_ #define PLATFORM_IMPL_WINDOWS_WIFI_H_ -#include #include +#include #include #include diff --git a/internal/platform/implementation/windows/wifi_hotspot_test.cc b/internal/platform/implementation/windows/wifi_hotspot_test.cc new file mode 100644 index 00000000..b99a511a --- /dev/null +++ b/internal/platform/implementation/windows/wifi_hotspot_test.cc @@ -0,0 +1,136 @@ +// Copyright 2023 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 "internal/platform/implementation/windows/wifi_hotspot.h" +#include "internal/platform/implementation/wifi_hotspot.h" +#include "internal/platform/implementation/windows/wifi_intel.h" + +#include +#include +#include + +#include "absl/time/clock.h" +#include "absl/time/time.h" +#include "gtest/gtest.h" +#include "internal/platform/logging.h" +#include "internal/platform/wifi_credential.h" + +namespace nearby { +namespace windows { +namespace { + +TEST(WifiHotspotMedium, DISABLED_StartWifiHotspot) { + int run_test; + NEARBY_LOGS(INFO) << "Run StartWifiHotspot test case? input 0 or 1:"; + std::cin >> run_test; + + if (run_test) { + HotspotCredentials hotspot_credentials; + WifiHotspotMedium hotspot_medium; + WifiIntel& intel_wifi_{WifiIntel::GetInstance()}; + + EXPECT_TRUE(hotspot_medium.IsInterfaceValid()); + EXPECT_TRUE(hotspot_medium.StartWifiHotspot(&hotspot_credentials)); + absl::SleepFor(absl::Seconds(1)); + // hotspot_medium.ListenForService(0); + intel_wifi_.Start(); + NEARBY_LOGS(INFO) << "GO channel: " << (int)intel_wifi_.GetGOChannel(); + intel_wifi_.Stop(); + + while (true) { + NEARBY_LOGS(INFO) << "Enter \"s\" to stop test:"; + std::string stop; + std::cin >> stop; + if (stop == "s") { + NEARBY_LOGS(INFO) << "Exit WiFi Hotspot"; + EXPECT_TRUE(hotspot_medium.StopWifiHotspot()); + break; + } + } + } else { + NEARBY_LOGS(INFO) << "Skip the test"; + } +} + +TEST(WifiHotspotMedium, DISABLED_WifiHotspotServerStartListen) { + int run_test; + NEARBY_LOGS(INFO) << "Run WifiHotspotServerStartListen test? input 0 or 1:"; + std::cin >> run_test; + + if (run_test) { + HotspotCredentials hotspot_credentials; + WifiHotspotMedium hotspot_medium; + + EXPECT_TRUE(hotspot_medium.IsInterfaceValid()); + EXPECT_TRUE(hotspot_medium.StartWifiHotspot(&hotspot_credentials)); + absl::SleepFor(absl::Seconds(1)); + std::unique_ptr server_socket = + hotspot_medium.ListenForService(0); + absl::SleepFor(absl::Seconds(10)); + std::unique_ptr client_socket = + server_socket->Accept(); + + while (true) { + NEARBY_LOGS(INFO) << "Enter \"s\" to stop test:"; + std::string stop; + std::cin >> stop; + if (stop == "s") { + NEARBY_LOGS(INFO) << "Close server socket and stop WiFi Hotspot"; + server_socket->Close(); + EXPECT_TRUE(hotspot_medium.StopWifiHotspot()); + break; + } + } + } else { + NEARBY_LOGS(INFO) << "Skip the test"; + } +} + + +TEST(WifiHotspotMedium, DISABLED_ConnectWifiHotspot) { + int run_test; + NEARBY_LOGS(INFO) << "Run ConnectWifiHotspot test case? input 0 or 1:"; + std::cin >> run_test; + + if (run_test) { + HotspotCredentials hotspot_credentials; + WifiHotspotMedium hotspot_medium; + NEARBY_LOGS(INFO) << "Enter Network SSID to be connected: "; + std::string ssid; + std::cin >> ssid; + NEARBY_LOGS(INFO) << "Enter password: "; + std::string password; + std::cin >> password; + hotspot_credentials.SetSSID(ssid); + hotspot_credentials.SetPassword(password); + EXPECT_TRUE(hotspot_medium.ConnectWifiHotspot(&hotspot_credentials)); + absl::SleepFor(absl::Seconds(1)); + while (true) { + NEARBY_LOGS(INFO) << "Enter \"s\" to stop test:"; + std::string stop; + std::cin >> stop; + if (stop == "s") { + NEARBY_LOGS(INFO) << "Disconnect WiFi"; + EXPECT_TRUE(hotspot_medium.DisconnectWifiHotspot()); + break; + } + } + } else { + NEARBY_LOGS(INFO) << "Skip the test"; + } +} + +} // namespace +} // namespace windows +} // namespace nearby diff --git a/internal/platform/implementation/windows/wifi_medium_test.cc b/internal/platform/implementation/windows/wifi_medium_test.cc new file mode 100644 index 00000000..9564161b --- /dev/null +++ b/internal/platform/implementation/windows/wifi_medium_test.cc @@ -0,0 +1,54 @@ +// Copyright 2023 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 "internal/platform/implementation/windows/wifi.h" + +#include + +#include "gtest/gtest.h" +#include "internal/platform/logging.h" + +namespace nearby { +namespace windows { +namespace { + +TEST(WifiMedium, DISABLED_GetCapabilityAndInformation) { + int run_test; + NEARBY_LOGS(INFO) + << "Run GetCapabilityAndInformation test case? input 0 or 1:"; + std::cin >> run_test; + + if (run_test) { + WifiMedium wifi_medium; + + auto& capability = wifi_medium.GetCapability(); + NEARBY_LOGS(INFO) << "Support 5G? " << capability.supports_5_ghz; + + auto& information = wifi_medium.GetInformation(); + NEARBY_LOGS(INFO) << "Is Connected? " << information.is_connected + << "; ssid = " << information.ssid + << "; bssid = " << information.bssid + << "; ap_frequency: " << information.ap_frequency + << "; ip_address_dot_decimal: " + << information.ip_address_dot_decimal + << "; ip_address_4_bytes: " + << information.ip_address_4_bytes; + } else { + NEARBY_LOGS(INFO) << "Skip the test"; + } +} + +} // namespace +} // namespace windows +} // namespace nearby From c7b740f0c43d77fcc3ddeb7caf4f6694f4a53ab4 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Fri, 15 Sep 2023 10:18:40 -0700 Subject: [PATCH 015/683] Begin copying sharing to github - Start with proto dir PiperOrigin-RevId: 565712295 --- .github/workflows/validate.yaml | 2 + sharing/proto/BUILD | 35 +++ sharing/proto/certificate_rpc.proto | 53 ++++ sharing/proto/contact_rpc.proto | 42 +++ sharing/proto/device_rpc.proto | 52 ++++ sharing/proto/encrypted_metadata.proto | 47 +++ sharing/proto/enums.proto | 61 ++++ sharing/proto/field_mask.proto | 24 ++ sharing/proto/rpc_resources.proto | 160 ++++++++++ sharing/proto/settings_observer_data.proto | 42 +++ sharing/proto/timestamp.proto | 32 ++ sharing/proto/wire_format.proto | 339 +++++++++++++++++++++ 12 files changed, 889 insertions(+) create mode 100644 sharing/proto/BUILD create mode 100644 sharing/proto/certificate_rpc.proto create mode 100644 sharing/proto/contact_rpc.proto create mode 100644 sharing/proto/device_rpc.proto create mode 100644 sharing/proto/encrypted_metadata.proto create mode 100644 sharing/proto/enums.proto create mode 100644 sharing/proto/field_mask.proto create mode 100644 sharing/proto/rpc_resources.proto create mode 100644 sharing/proto/settings_observer_data.proto create mode 100644 sharing/proto/timestamp.proto create mode 100644 sharing/proto/wire_format.proto diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index 25d7556e..2d03dcd2 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -37,6 +37,8 @@ jobs: run: CC=clang CXX=clang++ bazel build --check_visibility=false //connections:core --spawn_strategy=standalone - name: Build Presence run: CC=clang CXX=clang++ bazel build --check_visibility=false //presence --spawn_strategy=standalone + - name: Build Sharing + run: CC=clang CXX=clang++ bazel build --check_visibility=false //sharing/proto:all --spawn_strategy=standalone build-rust-linux: name: Build Rust on Linux diff --git a/sharing/proto/BUILD b/sharing/proto/BUILD new file mode 100644 index 00000000..c3a73631 --- /dev/null +++ b/sharing/proto/BUILD @@ -0,0 +1,35 @@ +load("@rules_cc//cc:defs.bzl", "cc_proto_library") + +licenses(["notice"]) + +proto_library( + name = "share_proto", + srcs = [ + "certificate_rpc.proto", + "contact_rpc.proto", + "device_rpc.proto", + "encrypted_metadata.proto", + "enums.proto", + "field_mask.proto", + "rpc_resources.proto", + "settings_observer_data.proto", + "timestamp.proto", + "wire_format.proto", + ], + visibility = ["//visibility:public"], + deps = [ + "//proto:sharing_enums_proto", + ], +) + +proto_library( + name = "enums_proto", + srcs = ["enums.proto"], + visibility = ["//visibility:public"], +) + +cc_proto_library( + name = "share_cc_proto", + visibility = ["//visibility:public"], + deps = [":share_proto"], +) diff --git a/sharing/proto/certificate_rpc.proto b/sharing/proto/certificate_rpc.proto new file mode 100644 index 00000000..a57c8f15 --- /dev/null +++ b/sharing/proto/certificate_rpc.proto @@ -0,0 +1,53 @@ +// 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. + +syntax = "proto3"; + +package nearby.sharing.proto; + +import "sharing/proto/rpc_resources.proto"; + +option optimize_for = LITE_RUNTIME; + +// Request to list public certificate objects. +message ListPublicCertificatesRequest { + // Required. The resource name determines which public certificates to list. + // The special prefix "users/me" lists the requesters own share targets. This + // is of the format "users/*/devices/*". + string parent = 1; + + // Optional limit on the number of ShareTarget objects to check for + // PublicCertificates for the response. Further PublicCertificates items may + // be obtained by including the page_token in a subsequent request. If this is + // not set or zero, a reasonable default value is used. + int32 page_size = 2; + + // Optional pagination token, returned earlier via + // [ListPublicCertificatesResponse.next_page_token] + string page_token = 3; + + // Optional. Represents certificates already available on local device. + repeated bytes secret_ids = 4; +} + +// Response that contains the public certificates available to calling device. +message ListPublicCertificatesResponse { + // Optional. A token to retrieve the next page of results when used in + // [ListPublicCertificatesRequest]. + string next_page_token = 1; + + // Optional. Public certificates allowed to be accessed by the calling local + // device. + repeated PublicCertificate public_certificates = 2; +} diff --git a/sharing/proto/contact_rpc.proto b/sharing/proto/contact_rpc.proto new file mode 100644 index 00000000..7f967534 --- /dev/null +++ b/sharing/proto/contact_rpc.proto @@ -0,0 +1,42 @@ +// 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. + +syntax = "proto3"; + +package nearby.sharing.proto; + +import "sharing/proto/rpc_resources.proto"; + +option optimize_for = LITE_RUNTIME; + +// Request to list ContactRecord of a user. +message ListContactPeopleRequest { + // Optional limit on the number of ContactRecord in + // [ListContactPeopleResponse.contact_records]. Defaults to 500 if not set. + int32 page_size = 1; + + // Optional pagination token, returned earlier via + // [ListContactPeopleResponse.next_page_token] + string page_token = 2; +} + +// Response from a ListContactPeopleRequest. +message ListContactPeopleResponse { + // The ContactRecord in this collection. + repeated ContactRecord contact_records = 1; + + // Optional. A token to retrieve the next page of results when used in + // [ListContactPeopleRequest]. Empty if no page is available. + string next_page_token = 2; +} diff --git a/sharing/proto/device_rpc.proto b/sharing/proto/device_rpc.proto new file mode 100644 index 00000000..c92198a4 --- /dev/null +++ b/sharing/proto/device_rpc.proto @@ -0,0 +1,52 @@ +// 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. + +syntax = "proto3"; + +package nearby.sharing.proto; + +import "sharing/proto/field_mask.proto"; +import "sharing/proto/rpc_resources.proto"; + +option optimize_for = LITE_RUNTIME; + +// The request used to register a [location.nearby.sharing.proto.Device] +// with the server. +message UpdateDeviceRequest { + // The [Device] to be updated. + Device device = 1; + + // The FieldMask for updating specific columns in device table. For the + // 'FieldMask' definition, see + // https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#fieldmask + FieldMask update_mask = 2; +} + +// The response for UpdateDeviceRequest. +message UpdateDeviceResponse { + // The [Device] to be returned. + Device device = 1; + + // Optional. The user's name as displayed to the user when selecting a share + // target. Ex: "Will Harmon" + string person_name = 2; + + // Optional. The URL of an image displayed to the user when selecting a + // share target. + string image_url = 3; + + // Optional. A hash like value to determine if the profile image has changed + // or not. Note, the image_url can change for the same image. + string image_token = 4; +} diff --git a/sharing/proto/encrypted_metadata.proto b/sharing/proto/encrypted_metadata.proto new file mode 100644 index 00000000..af1342df --- /dev/null +++ b/sharing/proto/encrypted_metadata.proto @@ -0,0 +1,47 @@ +// 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. + +syntax = "proto2"; + +package nearby.sharing.proto; + +option optimize_for = LITE_RUNTIME; + +// LINT.IfChange +message EncryptedMetadata { + // The name of the local device when certificate is created. + optional string device_name = 1; + + // The name of the user whose device created the certificate. + optional string full_name = 2; + + // The icon url of the user whose device created the certificate. + optional string icon_url = 3; + + // The Bluetooth MAC address of the device which created the certificate. + optional bytes bluetooth_mac_address = 4; + + // The obfuscated Gaia ID of the account which created the certificate. + optional string obfuscated_gaia_id = 5; + + // The name of the account which created the certificate. + optional string account_name = 6; + + // The device's model name + optional string model_name = 7; + + // The vendor ID of the local device. + optional int32 vendor_id = 8; +} +// LINT.ThenChange(//depot/google3/location/nearby/sharing/proto/contact_certificates.proto) diff --git a/sharing/proto/enums.proto b/sharing/proto/enums.proto new file mode 100644 index 00000000..d350febd --- /dev/null +++ b/sharing/proto/enums.proto @@ -0,0 +1,61 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package nearby.sharing.proto; + +option optimize_for = LITE_RUNTIME; + +// Represents the Fast Initiation Notification feature state. This feature +// shows a notification when a nearby device is trying to share. It can be +// enabled/disabled independently from the Nearby Share feature. +enum FastInitiationNotificationState { + UNKNOWN_FAST_INIT = 0; + ENABLED_FAST_INIT = 1; + // User manually disabled the Fast Initiation Notification feature. If + // Nearby Share feature is toggled the notification feature will remain + // disabled. + DISABLED_BY_USER_FAST_INIT = 2; + // User turned off Nearby Share which disables the Fast Initiation + // Notification feature. If Nearby Share is enabled while Fast Initiation + // Notification is in this state then notifications will be re-enabled. + DISABLED_BY_FEATURE_FAST_INIT = 3; +} + +enum DataUsage { + UNKNOWN_DATA_USAGE = 0; + // User is never willing to use the Internet + OFFLINE_DATA_USAGE = 1; + // User is always willing to use the Internet + ONLINE_DATA_USAGE = 2; + // User is willing to use the Internet on an un-metered connection. + // NOTE: This matches Android Nearby Share's naming for now. + WIFI_ONLY_DATA_USAGE = 3; +} + +enum DeviceVisibility { + DEVICE_VISIBILITY_UNSPECIFIED = 0; + // The user is visible to no one. + DEVICE_VISIBILITY_HIDDEN = 1; + // The user is visible to devices signed in with the same account. + DEVICE_VISIBILITY_SELF_SHARE = 2; + // The user is visible to all contacts. + DEVICE_VISIBILITY_ALL_CONTACTS = 3; + // The user is visible to everyone. + DEVICE_VISIBILITY_EVERYONE = 4; + // TODO(b/251499089): Combine kAllContacts and kSelectedContacts to kContacts + // The user is only visible to selected contacts. + DEVICE_VISIBILITY_SELECTED_CONTACTS = 5; +} diff --git a/sharing/proto/field_mask.proto b/sharing/proto/field_mask.proto new file mode 100644 index 00000000..375ebd77 --- /dev/null +++ b/sharing/proto/field_mask.proto @@ -0,0 +1,24 @@ +// 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. + +syntax = "proto3"; + +package nearby.sharing.proto; + +option optimize_for = LITE_RUNTIME; + +message FieldMask { + // The set of field mask paths. + repeated string paths = 1; +} diff --git a/sharing/proto/rpc_resources.proto b/sharing/proto/rpc_resources.proto new file mode 100644 index 00000000..9efc96ae --- /dev/null +++ b/sharing/proto/rpc_resources.proto @@ -0,0 +1,160 @@ +// 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. + +syntax = "proto3"; + +package nearby.sharing.proto; + +import "sharing/proto/timestamp.proto"; + +option optimize_for = LITE_RUNTIME; + +// A SharedCertificate contains a secret key used when recognizing another +// user's BLE advertisement and a public key used when establishing an encrypted +// connection. +// +// How a Certificate is distributed is determined by who is on a user's contact +// list. For example, if Will adds Ryan to his contact list, Ryan will have a +// ShareTarget with Will's Certificate attached to it. +// NextId=11 +message PublicCertificate { + // The secret (symmetric) identifier used when identifying the ShareTarget's + // BLE advertisement. + bytes secret_id = 1; + + // The secret (symmetric) key is used to decrypt the name field of the + // ShareTarget's BLE advertisement. + bytes secret_key = 2; + + // The public key is used to create a secure connection with the ShareTarget. + bytes public_key = 3; + + // The time that certificate validity begins. + Timestamp start_time = 4; + + // The time that certificate validity ends. + Timestamp end_time = 5; + + // Indicates if this public certificate is only for selected contacts. + bool for_selected_contacts = 6; + + // This aes key is uploaded from device to server, but not returned to device. + // It is only public to the server, for encrypting personal info metadata. + bytes metadata_encryption_key = 7; + + // The encrypted metadata in bytes, contains personal information of the + // device/user who created this certificate. Needs to be decrypted into bytes, + // and converted back to EncryptedMetadata object to access fields. + // Definition of this object see: + // location/nearby/sharing/proto/contact_certificates.proto + bytes encrypted_metadata_bytes = 8; + + // The tag for verifying metadata_encryption_key. + bytes metadata_encryption_key_tag = 9; + + // Indicates if this public certificate corresponds to a device owned by the + // current user. + bool for_self_share = 10; +} + +// A member of a contact list. This is not inlined on the recommendation of +// http://go/apidosdonts##19-make-repeated-fields-messages-not-scalar-types +// NextId=4 +message Contact { + // NextId=4 + message Identifier { + oneof identifier { + string obfuscated_gaia = 1; + string phone_number = 2; + string account_name = 3; + } + } + + // Required. The identifier of a contact can be an obfuscated gaia id, a phone + // number, or an email account name. + Identifier identifier = 1; + + // Indicates if this contact is a selected contact. + bool is_selected = 2; + + // Indicates if this contact is ourselves. + bool is_self = 3; +} + +// A contact record from People backend. +// NextId=7 +message ContactRecord { + // The type of the ContactRecord. + enum Type { + // The source of the contact is unknown. + UNKNOWN = 0; + + // The source of the contact is from google (i.e. google.com/contacts). + GOOGLE_CONTACT = 1; + + // The source of the contact is from a device. + DEVICE_CONTACT = 2; + } + + // The stable id of this contact record. + string id = 1; + + // The contact record's name. + string person_name = 2; + + // The URL of an image displayed to the user when selecting a share + // target. + string image_url = 3; + + // A list of phone numbers and emails under this contact record. + repeated Contact.Identifier identifiers = 4; + + // The type of the ContactRecord. + Type type = 5; + + // True if the contact record is WPS reachable. + bool is_reachable = 6; +} + +// A ShareTarget is a potential destination of a share. +// NextId=2 +message ShareTarget { + // Optional. Contains the keys required to identify and connect to this + // target. + repeated PublicCertificate public_certificates = 1; +} + +// Consists of editable data inside of a device. +// NextId=5 +message Device { + // Required. The resource name of this contact Device. This is of the format + // 'users/*/devices/*'. The special prefix 'users/me' uses the + // identity of the requester. + string name = 1; + + // The device name to show members of this contact. Ex: "Joe's Pixel". + // + // NOTE: Do not use on Chrome. This appears to be an artifact of the old + // Nearby Share model, and could be a privacy risk that we want to avoid. + // The display name is instead included in the certificate encrypted metadata. + string display_name = 2; + + // Users that this user has added to indicate that they may see this + // user as a ShareTarget when this user is nearby. + repeated Contact contacts = 3; + + // The public certificates generated and uploaded from local device, to be + // shared with contacts. + repeated PublicCertificate public_certificates = 4; +} diff --git a/sharing/proto/settings_observer_data.proto b/sharing/proto/settings_observer_data.proto new file mode 100644 index 00000000..1faddad8 --- /dev/null +++ b/sharing/proto/settings_observer_data.proto @@ -0,0 +1,42 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package nearby.sharing.proto; + +option optimize_for = LITE_RUNTIME; + +// LINT.IfChange(TaggedUnion) +// Tag and Data define a "variant" type, aka tagged union. +// https://en.wikipedia.org/wiki/Tagged_union +enum Tag { + TAG_NULL = 0; + TAG_BOOL = 1; + TAG_INT64 = 2; + TAG_STRING = 3; + TAG_STRING_ARRAY = 4; +} + +message Data { + Tag tag = 1; + // Not using `oneof` because `repeated` is not allowed in `oneof` + optional bool as_bool = 2; + optional int64 as_int64 = 3; + optional string as_string = 4; + repeated string as_string_array = 5; +} +// LINT.ThenChange( +// //depot/google3/third_party/nearby/sharing/nearby_sharing_settings.h:TaggedUnion +// ) diff --git a/sharing/proto/timestamp.proto b/sharing/proto/timestamp.proto new file mode 100644 index 00000000..084dd570 --- /dev/null +++ b/sharing/proto/timestamp.proto @@ -0,0 +1,32 @@ +// 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. + +syntax = "proto3"; + +package nearby.sharing.proto; + +option optimize_for = LITE_RUNTIME; + +message Timestamp { + // Represents seconds of UTC time since Unix epoch + // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to + // 9999-12-31T23:59:59Z inclusive. + int64 seconds = 1; + + // Non-negative fractions of a second at nanosecond resolution. Negative + // second values with fractions must still have non-negative nanos values + // that count forward in time. Must be from 0 to 999,999,999 + // inclusive. + int32 nanos = 2; +} diff --git a/sharing/proto/wire_format.proto b/sharing/proto/wire_format.proto new file mode 100644 index 00000000..111508ce --- /dev/null +++ b/sharing/proto/wire_format.proto @@ -0,0 +1,339 @@ +syntax = "proto2"; + +package nearby.sharing.service.proto; + +import "proto/sharing_enums.proto"; + +option java_package = "com.google.android.gms.nearby.sharing"; +option java_outer_classname = "Protocol"; +option objc_class_prefix = "GNSHP"; +option optimize_for = LITE_RUNTIME; + +// File metadata. Does not include the actual bytes of the file. +// NEXT_ID=6 +message FileMetadata { + enum Type { + UNKNOWN = 0; + IMAGE = 1; + VIDEO = 2; + ANDROID_APP = 3; + AUDIO = 4; + DOCUMENT = 5; + } + + // The human readable name of this file (eg. 'Cookbook.pdf'). + optional string name = 1; + + // The type of file (eg. 'IMAGE' from 'dog.jpg'). Specifying a type helps + // provide a richer experience on the receiving side. + optional Type type = 2 [default = UNKNOWN]; + + // The FILE payload id that will be sent as a follow up containing the actual + // bytes of the file. + optional int64 payload_id = 3; + + // The total size of the file. + optional int64 size = 4; + + // The mimeType of file (eg. 'image/jpeg' from 'dog.jpg'). Specifying a + // mimeType helps provide a richer experience on receiving side. + optional string mime_type = 5 [default = "application/octet-stream"]; + + // A uuid for the attachment. Should be unique across all attachments. + optional int64 id = 6; + + // The parent folder. + optional string parent_folder = 7; + + // A stable identifier for the attachment. Used for receiver to identify same + // attachment from different transfers. + optional int64 attachment_hash = 8; +} + +// NEXT_ID=5 +message TextMetadata { + enum Type { + UNKNOWN = 0; + TEXT = 1; + // Open with browsers. + URL = 2; + // Open with map apps. + ADDRESS = 3; + // Dial. + PHONE_NUMBER = 4; + } + + // The title of the text content. + optional string text_title = 2; + + // The type of text (phone number, url, address, or plain text). + optional Type type = 3 [default = UNKNOWN]; + + // The BYTE payload id that will be sent as a follow up containing the actual + // bytes of the text. + optional int64 payload_id = 4; + + // The size of the text content. + optional int64 size = 5; + + // A uuid for the attachment. Should be unique across all attachments. + optional int64 id = 6; +} + +// NEXT_ID=5 +message WifiCredentialsMetadata { + enum SecurityType { + UNKNOWN_SECURITY_TYPE = 0; + OPEN = 1; + WPA_PSK = 2; + WEP = 3; + SAE = 4; + } + + // The Wifi network name. This will be sent in introduction. + optional string ssid = 2; + + // The security type of network (OPEN, WPA_PSK, WEP). + optional SecurityType security_type = 3 [default = UNKNOWN_SECURITY_TYPE]; + + // The BYTE payload id that will be sent as a follow up containing the + // password. + optional int64 payload_id = 4; + + // A uuid for the attachment. Should be unique across all attachments. + optional int64 id = 5; +} + +// NEXT_ID=8 +message AppMetadata { + // The app name. This will be sent in introduction. + optional string app_name = 1; + + // The size of the all split of apks. + optional int64 size = 2; + + // The File payload id that will be sent as a follow up containing the + // apk paths. + repeated int64 payload_id = 3 [packed = true]; + + // A uuid for the attachment. Should be unique across all attachments. + optional int64 id = 4; + + // The name of apk file. This will be sent in introduction. + repeated string file_name = 5; + + // The size of apk file. This will be sent in introduction. + repeated int64 file_size = 6 [packed = true]; + + // The package name. This will be sent in introduction. + optional string package_name = 7; +} + +// A frame used when sending messages over the wire. +// NEXT_ID=3 +message Frame { + enum Version { + UNKNOWN_VERSION = 0; + V1 = 1; + } + optional Version version = 1; + + // Right now there's only 1 version, but if there are more, exactly one of + // the following fields will be set. + optional V1Frame v1 = 2; +} + +// NEXT_ID=8 +message V1Frame { + enum FrameType { + UNKNOWN_FRAME_TYPE = 0; + INTRODUCTION = 1; + RESPONSE = 2; + PAIRED_KEY_ENCRYPTION = 3; + PAIRED_KEY_RESULT = 4; + CERTIFICATE_INFO = 5; + CANCEL = 6; + PROGRESS_UPDATE = 7; + } + + optional FrameType type = 1; + + // At most one of the following fields will be set. + optional IntroductionFrame introduction = 2; + optional ConnectionResponseFrame connection_response = 3; + optional PairedKeyEncryptionFrame paired_key_encryption = 4; + optional PairedKeyResultFrame paired_key_result = 5; + optional CertificateInfoFrame certificate_info = 6; + optional ProgressUpdateFrame progress_update = 7; +} + +// An introduction packet sent by the sending side. Contains a list of files +// they'd like to share. +// NEXT_ID=7 +message IntroductionFrame { + repeated FileMetadata file_metadata = 1; + repeated TextMetadata text_metadata = 2; + // The required app package to open the content. May be null. + optional string required_package = 3; + repeated WifiCredentialsMetadata wifi_credentials_metadata = 4; + repeated AppMetadata app_metadata = 5; + optional bool start_transfer = 6; +} + +// A progress update packet sent by the sending side. Contains transfer progress +// value. NEXT_ID=3 +message ProgressUpdateFrame { + optional float progress = 1; + + // True, if the receiver should start bandwidth upgrade and receiving the + // payloads. + optional bool start_transfer = 2; +} + +// A response packet sent by the receiving side. Accepts or rejects the list of +// files. +// NEXT_ID=3 +message ConnectionResponseFrame { + enum Status { + UNKNOWN = 0; + ACCEPT = 1; + REJECT = 2; + NOT_ENOUGH_SPACE = 3; + UNSUPPORTED_ATTACHMENT_TYPE = 4; + TIMED_OUT = 5; + } + + // The receiving side's response. + optional Status status = 1; + + // Key is attachment hash, value is the details of attachment. + map attachment_details = 2; +} + +// Attachment details that sent in ConnectionResponseFrame. +message AttachmentDetails { + // LINT.IfChange + enum Type { + UNKNOWN = 0; + // Represents FileAttachment. + FILE = 1; + // Represents TextAttachment. + TEXT = 2; + // Represents WifiCredentialsAttachment. + WIFI_CREDENTIALS = 3; + // Represents AppAttachment. + APP = 4; + } + // LINT.ThenChange(//depot/google3/java/com/google/android/gmscore/integ/client/nearby/src/com/google/android/gms/nearby/sharing/Attachment.java) + + // The attachment family type. + optional Type type = 1; + + // This field is only for FILE type. + optional FileAttachmentDetails file_attachment_details = 2; +} + +// File attachment details included in ConnectionResponseFrame. +message FileAttachmentDetails { + // Existing local file size on receiver side. + optional int64 receiver_existing_file_size = 1; + + // The key is attachment hash, a stable identifier for the attachment. + // Value is list of payload details transferred for the attachment. + map attachment_hash_payloads = 2; +} + +message PayloadsDetails { + // The list should be sorted by creation timestamp. + repeated PayloadDetails payload_details = 1; +} + +// Metadata of a payload file created by Nearby Connections. +message PayloadDetails { + optional int64 id = 1; + optional int64 creation_timestamp_millis = 2; + optional int64 size = 3; +} + +// A paired key encryption packet sent between devices, contains signed data. +// NEXT_ID=5 +message PairedKeyEncryptionFrame { + // The encrypted data in byte array format. + optional bytes signed_data = 1; + + // The hash of a certificate id. + optional bytes secret_id_hash = 2; + + // An optional encrypted data in byte array format. + optional bytes optional_signed_data = 3; + + // An optional QR code handshake data in a byte array format. + // For incoming connection contains a signature of the UKEY2 + // token, created with the sender's private key. + // For outgoing connection contains an HKDF of the connection token and of the + // UKEY2 token + optional bytes qr_code_handshake_data = 4; +} + +// A paired key verification result packet sent between devices. +// NEXT_ID=3 +message PairedKeyResultFrame { + enum Status { + UNKNOWN = 0; + SUCCESS = 1; + FAIL = 2; + UNABLE = 3; + } + + // The verification result. + optional Status status = 1; + + // OS type. + optional location.nearby.proto.sharing.OSType os_type = 2; +} + +// A package containing certificate info to be shared to remote device offline. +// NEXT_ID=2 +message CertificateInfoFrame { + // The public certificates to be shared with remote devices. + repeated PublicCertificate public_certificate = 1; +} + +// A public certificate from the local device. +// NEXT_ID=8 +message PublicCertificate { + // The unique id of the public certificate. + optional bytes secret_id = 1; + + // A bytes representation of a Secret Key owned by contact, to decrypt the + // metadata_key stored within the advertisement. + optional bytes authenticity_key = 2; + + // A bytes representation a public key of X509Certificate, owned by contact, + // to decrypt encrypted UKEY2 (from Nearby Connections API) as a hand shake in + // contact verification phase. + optional bytes public_key = 3; + + // The time in millis from epoch when this certificate becomes effective. + optional int64 start_time = 4; + + // The time in millis from epoch when this certificate expires. + optional int64 end_time = 5; + + // The encrypted metadata in bytes, contains personal information of the + // device/user who created this certificate. Needs to be decrypted into bytes, + // and converted back to EncryptedMetadata object to access fields. + optional bytes encrypted_metadata_bytes = 6; + + // The tag for verifying metadata_encryption_key. + optional bytes metadata_encryption_key_tag = 7; +} + +// NEXT_ID=3 +message WifiCredentials { + // Wi-Fi password. + optional string password = 1; + // True if the network is a hidden network that is not broadcasting its SSID. + // Default is false. + optional bool hidden_ssid = 2 [default = false]; +} From 8b20e2241486b35aa829d17551328b1db0f1939d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Sep 2023 17:22:19 +0000 Subject: [PATCH 016/683] Bump archive from 3.3.7 to 3.3.8 in /fastpair/rust/demo Bumps [archive](https://github.com/brendan-duncan/archive) from 3.3.7 to 3.3.8. - [Changelog](https://github.com/brendan-duncan/archive/blob/main/CHANGELOG.md) - [Commits](https://github.com/brendan-duncan/archive/compare/3.3.7...3.3.8) --- updated-dependencies: - dependency-name: archive dependency-type: indirect ... Signed-off-by: dependabot[bot] --- fastpair/rust/demo/pubspec.lock | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/fastpair/rust/demo/pubspec.lock b/fastpair/rust/demo/pubspec.lock index a6087902..b475ef49 100644 --- a/fastpair/rust/demo/pubspec.lock +++ b/fastpair/rust/demo/pubspec.lock @@ -21,10 +21,10 @@ packages: dependency: transitive description: name: archive - sha256: "0c8368c9b3f0abbc193b9d6133649a614204b528982bebc7026372d61677ce3a" + sha256: "49b1fad315e57ab0bbc15bcbb874e83116a1d78f77ebd500a4af6c9407d6b28e" url: "https://pub.dev" source: hosted - version: "3.3.7" + version: "3.3.8" args: dependency: transitive description: @@ -165,10 +165,10 @@ packages: dependency: transitive description: name: collection - sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 url: "https://pub.dev" source: hosted - version: "1.17.1" + version: "1.17.2" convert: dependency: transitive description: @@ -375,18 +375,18 @@ packages: dependency: transitive description: name: matcher - sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" + sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" url: "https://pub.dev" source: hosted - version: "0.12.15" + version: "0.12.16" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.5.0" meta: dependency: transitive description: @@ -516,10 +516,10 @@ packages: dependency: transitive description: name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" stack_trace: dependency: transitive description: @@ -564,10 +564,10 @@ packages: dependency: transitive description: name: test_api - sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb + sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "0.6.0" timing: dependency: transitive description: @@ -616,6 +616,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + web: + dependency: transitive + description: + name: web + sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + url: "https://pub.dev" + source: hosted + version: "0.1.4-beta" web_socket_channel: dependency: transitive description: From b33c0e0332d7737e2805d9ae84acdfc6f683fa50 Mon Sep 17 00:00:00 2001 From: Janusz Sobczak Date: Fri, 15 Sep 2023 12:10:07 -0700 Subject: [PATCH 017/683] Migrate to AnyInvocable in auth module Merged success/failure callbacks into a single callback in SignInCallback and AccessTokenCallback to simplify resource management and to avoid making copies. PiperOrigin-RevId: 565744310 --- .../test/fast_pair_fake_http_client.h | 24 ++++++++------ fastpair/server_access/BUILD | 11 +++++++ .../server_access/fast_pair_client_impl.cc | 32 +++++++++++-------- .../fast_pair_client_impl_test.cc | 27 +++++++++++++--- internal/network/BUILD | 9 +++--- internal/network/http_client.h | 11 +++++-- internal/network/http_client_impl.cc | 16 +++++++--- internal/network/http_client_impl.h | 9 +++--- internal/test/fake_http_client.h | 21 ++++++------ 9 files changed, 106 insertions(+), 54 deletions(-) diff --git a/fastpair/internal/test/fast_pair_fake_http_client.h b/fastpair/internal/test/fast_pair_fake_http_client.h index 1bd12bb5..4723edf5 100644 --- a/fastpair/internal/test/fast_pair_fake_http_client.h +++ b/fastpair/internal/test/fast_pair_fake_http_client.h @@ -15,15 +15,20 @@ #ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_TEST_FAST_PAIR_FAKE_HTTP_CLIENT_H_ #define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_TEST_FAST_PAIR_FAKE_HTTP_CLIENT_H_ -#include +#include #include #include #include #include #include +#include "absl/functional/any_invocable.h" +#include "absl/status/status.h" #include "absl/status/statusor.h" #include "internal/network/http_client.h" +#include "internal/network/http_request.h" +#include "internal/network/http_response.h" +#include "internal/network/http_status_code.h" namespace nearby { namespace network { @@ -32,7 +37,7 @@ class FastPairFakeHttpClient : public HttpClient { public: struct RequestInfo { HttpRequest request; - std::function&)> callback; + absl::AnyInvocable&)> callback; }; FastPairFakeHttpClient() = default; @@ -44,18 +49,19 @@ class FastPairFakeHttpClient : public HttpClient { FastPairFakeHttpClient(FastPairFakeHttpClient&&) = default; FastPairFakeHttpClient& operator=(FastPairFakeHttpClient&&) = default; - void StartRequest(const HttpRequest& request, - std::function&)> - callback) override { + void StartRequest( + const HttpRequest& request, + absl::AnyInvocable&)> callback) + override { RequestInfo request_info; request_info.request = request; - request_info.callback = callback; + request_info.callback = std::move(callback); request_infos_.push_back(std::move(request_info)); } void StartCancellableRequest( std::unique_ptr request, - std::function&)> callback) + absl::AnyInvocable&)> callback) override {} absl::StatusOr GetResponse( @@ -70,8 +76,8 @@ class FastPairFakeHttpClient : public HttpClient { return; } - auto request_info = request_infos_.at(pos); - if (request_info.callback != nullptr) { + auto& request_info = request_infos_.at(pos); + if (request_info.callback) { request_info.callback(response); } diff --git a/fastpair/server_access/BUILD b/fastpair/server_access/BUILD index 89bfffa7..6ca7f1dc 100644 --- a/fastpair/server_access/BUILD +++ b/fastpair/server_access/BUILD @@ -33,10 +33,13 @@ cc_library( "//fastpair/proto:fastpair_cc_proto", "//fastpair/proto:proto_to_json", "//internal/account", + "//internal/auth:credential", "//internal/auth:types", "//internal/base", "//internal/network:types", "//internal/platform:types", + "//internal/platform/implementation:types", + "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", @@ -92,12 +95,20 @@ cc_test( "//internal/account", "//internal/account:test_support", "//internal/auth:credential", + "//internal/auth:types", "//internal/network:types", "//internal/platform:types", "//internal/platform/implementation/g3", # build_cleaner: keep + "//internal/preferences", "//internal/test", "//internal/test/google3_only:test", "@com_github_protobuf_matchers//protobuf-matchers", + "@com_google_absl//absl/functional:any_invocable", + "@com_google_absl//absl/log:check", + "@com_google_absl//absl/status", + "@com_google_absl//absl/status:statusor", + "@com_google_absl//absl/strings", + "@com_google_absl//absl/strings:string_view", "@com_google_googletest//:gtest_main", ], ) diff --git a/fastpair/server_access/fast_pair_client_impl.cc b/fastpair/server_access/fast_pair_client_impl.cc index 8a5960e8..21590686 100644 --- a/fastpair/server_access/fast_pair_client_impl.cc +++ b/fastpair/server_access/fast_pair_client_impl.cc @@ -14,20 +14,28 @@ #include "fastpair/server_access/fast_pair_client_impl.h" -#include #include #include #include #include +#include "absl/status/status.h" +#include "absl/status/statusor.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "absl/strings/string_view.h" #include "absl/synchronization/notification.h" #include "fastpair/common/fast_pair_switches.h" +#include "fastpair/server_access/fast_pair_http_notifier.h" #include "internal/account/account_manager.h" +#include "internal/auth/auth_status_util.h" +#include "internal/auth/authentication_manager.h" #include "internal/network/http_client.h" +#include "internal/network/http_request.h" +#include "internal/network/http_response.h" #include "internal/network/url.h" +#include "internal/platform/device_info.h" +#include "internal/platform/implementation/device_info.h" #include "internal/platform/logging.h" namespace nearby { @@ -274,19 +282,15 @@ absl::StatusOr FastPairClientImpl::GetAccessToken() { absl::StatusOr result; absl::Notification notification; authentication_manager_->FetchAccessToken( - account->id, { - .success_cb = - [&](absl::string_view access_token) { - result = std::string(access_token); - notification.Notify(); - }, - .failure_cb = - [&](auth::AuthStatus status) { - result = absl::UnknownError( - absl::StrCat(static_cast(status))); - notification.Notify(); - }, - }); + account->id, + [&](auth::AuthStatus status, absl::string_view access_token) { + if (status == auth::AuthStatus::SUCCESS) { + result = std::string(access_token); + } else { + result = absl::UnknownError(absl::StrCat(static_cast(status))); + } + notification.Notify(); + }); notification.WaitForNotification(); return result; } diff --git a/fastpair/server_access/fast_pair_client_impl_test.cc b/fastpair/server_access/fast_pair_client_impl_test.cc index f2c2c0b3..255cfa18 100644 --- a/fastpair/server_access/fast_pair_client_impl_test.cc +++ b/fastpair/server_access/fast_pair_client_impl_test.cc @@ -25,23 +25,39 @@ #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" +#include "absl/functional/any_invocable.h" +#include "absl/log/check.h" +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/strings/ascii.h" +#include "absl/strings/escaping.h" +#include "absl/strings/numbers.h" +#include "absl/strings/string_view.h" +#include "fastpair/common/account_key.h" +#include "fastpair/common/device_metadata.h" #include "fastpair/common/fast_pair_device.h" #include "fastpair/common/fast_pair_prefs.h" #include "fastpair/common/fast_pair_switches.h" +#include "fastpair/common/protocol.h" #include "fastpair/proto/data.proto.h" #include "fastpair/proto/enum.proto.h" #include "fastpair/proto/fast_pair_string.proto.h" #include "fastpair/proto/proto_builder.h" +#include "fastpair/server_access/fast_pair_client.h" #include "fastpair/server_access/fast_pair_http_notifier.h" #include "internal/account/account_manager.h" #include "internal/account/fake_account_manager.h" #include "internal/auth/auth_status_util.h" +#include "internal/auth/authentication_manager.h" #include "internal/network/http_client.h" #include "internal/network/http_request.h" #include "internal/network/http_response.h" #include "internal/network/http_status_code.h" #include "internal/network/url.h" +#include "internal/platform/device_info.h" +#include "internal/platform/task_runner.h" #include "internal/platform/task_runner_impl.h" +#include "internal/preferences/preferences_manager.h" #include "internal/test/fake_device_info.h" #include "internal/test/google3_only/fake_authentication_manager.h" @@ -89,11 +105,11 @@ class MockHttpClient : public HttpClient { public: MOCK_METHOD(void, StartRequest, (const HttpRequest& request, - std::function&)>), + absl::AnyInvocable&)>), (override)); MOCK_METHOD(void, StartCancellableRequest, (std::unique_ptr request, - std::function&)>), + absl::AnyInvocable&)>), (override)); MOCK_METHOD(absl::StatusOr, GetResponse, (const HttpRequest&), (override)); @@ -119,9 +135,10 @@ std::vector ExpectQueryStringValues( // A gMock matcher to match proto values. Use this matcher like: // request/response proto, expected_proto; // EXPECT_THAT(proto, MatchesProto(expected_proto)); -MATCHER_P(MatchesProto, expected_proto, - absl::StrCat(negation ? "does not match" : "matches", - testing::PrintToString(expected_proto.SerializeAsString()))) { +MATCHER_P( + MatchesProto, expected_proto, + absl::StrCat(negation ? "does not match" : "matches", + testing::PrintToString(expected_proto.SerializeAsString()))) { return arg.has_value() && arg->SerializeAsString() == expected_proto.SerializeAsString(); } diff --git a/internal/network/BUILD b/internal/network/BUILD index 9a1b24f5..52f6f3de 100644 --- a/internal/network/BUILD +++ b/internal/network/BUILD @@ -28,7 +28,9 @@ cc_library( ], deps = [ "//internal/platform:types", + "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/container:flat_hash_map", + "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", "@com_google_absl//absl/strings", @@ -56,13 +58,12 @@ cc_library( deps = [ ":types", "//internal/platform:types", - "//internal/platform/implementation:platform", + "//internal/platform/implementation:comm", "@com_google_absl//absl/base:core_headers", - "@com_google_absl//absl/container:flat_hash_map", + "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings:str_format", - "@com_google_absl//absl/synchronization", + "@com_google_absl//absl/strings", ], ) diff --git a/internal/network/http_client.h b/internal/network/http_client.h index 156ca091..4e2bbedc 100644 --- a/internal/network/http_client.h +++ b/internal/network/http_client.h @@ -15,12 +15,15 @@ #ifndef THIRD_PARTY_NEARBY_INTERNAL_NETWORK_HTTP_CLIENT_H_ #define THIRD_PARTY_NEARBY_INTERNAL_NETWORK_HTTP_CLIENT_H_ -#include #include +#include "absl/base/thread_annotations.h" +#include "absl/functional/any_invocable.h" +#include "absl/status/status.h" #include "absl/status/statusor.h" #include "internal/network/http_request.h" #include "internal/network/http_response.h" +#include "internal/platform/mutex.h" #include "internal/platform/mutex_lock.h" namespace nearby { @@ -60,12 +63,14 @@ class HttpClient { // Starts HTTP request in asynchronization mode. virtual void StartRequest( const HttpRequest& request, - std::function&)> callback) = 0; + absl::AnyInvocable&)> + callback) = 0; // Starts cancellable request in asynchronization mode. virtual void StartCancellableRequest( std::unique_ptr request, - std::function&)> callback) = 0; + absl::AnyInvocable&)> + callback) = 0; // Gets HTTP response in synchronization mode. virtual absl::StatusOr GetResponse( diff --git a/internal/network/http_client_impl.cc b/internal/network/http_client_impl.cc index 9a59c769..53174e5e 100644 --- a/internal/network/http_client_impl.cc +++ b/internal/network/http_client_impl.cc @@ -14,14 +14,20 @@ #include "internal/network/http_client_impl.h" -#include #include #include #include #include +#include "absl/functional/any_invocable.h" #include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/strings/str_cat.h" #include "internal/network/debug.h" +#include "internal/network/http_request.h" +#include "internal/network/http_response.h" +#include "internal/network/http_status_code.h" +#include "internal/platform/implementation/http_loader.h" #include "internal/platform/logging.h" #include "internal/platform/mutex_lock.h" #include "internal/platform/single_thread_executor.h" @@ -31,10 +37,10 @@ namespace network { void NearbyHttpClient::StartRequest( const HttpRequest& request, - std::function&)> callback) { + absl::AnyInvocable&)> callback) { MutexLock lock(&mutex_); executor_.Execute( - [request = std::move(request), callback = std::move(callback)]() { + [request = std::move(request), callback = std::move(callback)]() mutable { NEARBY_LOGS(INFO) << __func__ << ": Start async request to url=" << request.GetUrl().GetUrlPath(); absl::StatusOr response = InternalGetResponse(request); @@ -58,7 +64,7 @@ void NearbyHttpClient::StartRequest( void NearbyHttpClient::StartCancellableRequest( std::unique_ptr cancellable_request, - std::function&)> callback) { + absl::AnyInvocable&)> callback) { MutexLock lock(&mutex_); if (cancellable_request == nullptr) { NEARBY_LOGS(ERROR) << __func__ << ": invalid cancellable request."; @@ -68,7 +74,7 @@ void NearbyHttpClient::StartCancellableRequest( executor_ .Execute( [cancellable_request = std::move(cancellable_request), - callback = std::move(callback)]() { + callback = std::move(callback)]() mutable { NEARBY_LOGS(INFO) << __func__ << ": Start async request to url=" << cancellable_request->http_request().GetUrl().GetUrlPath(); diff --git a/internal/network/http_client_impl.h b/internal/network/http_client_impl.h index 904c6ced..f10f245b 100644 --- a/internal/network/http_client_impl.h +++ b/internal/network/http_client_impl.h @@ -37,13 +37,14 @@ class NearbyHttpClient : public HttpClient { NearbyHttpClient(NearbyHttpClient&&) = default; NearbyHttpClient& operator=(NearbyHttpClient&&) = default; - void StartRequest(const HttpRequest& request, - std::function&)> - callback) override ABSL_LOCKS_EXCLUDED(mutex_); + void StartRequest( + const HttpRequest& request, + absl::AnyInvocable&)> callback) + override ABSL_LOCKS_EXCLUDED(mutex_); void StartCancellableRequest( std::unique_ptr request, - std::function&)> callback) + absl::AnyInvocable&)> callback) override ABSL_LOCKS_EXCLUDED(mutex_); // Gets HTTP response in synchronization mode. diff --git a/internal/test/fake_http_client.h b/internal/test/fake_http_client.h index 14e04a80..000143af 100644 --- a/internal/test/fake_http_client.h +++ b/internal/test/fake_http_client.h @@ -17,13 +17,13 @@ #include -#include #include #include #include #include #include +#include "absl/functional/any_invocable.h" #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/string_view.h" @@ -39,7 +39,7 @@ class FakeHttpClient : public HttpClient { public: struct RequestInfo { HttpRequest request; - std::function&)> callback; + absl::AnyInvocable&)> callback; }; FakeHttpClient() = default; @@ -51,22 +51,23 @@ class FakeHttpClient : public HttpClient { FakeHttpClient(FakeHttpClient&&) = default; FakeHttpClient& operator=(FakeHttpClient&&) = default; - void StartRequest(const HttpRequest& request, - std::function&)> - callback) override { + void StartRequest( + const HttpRequest& request, + absl::AnyInvocable&)> callback) + override { RequestInfo request_info; request_info.request = request; - request_info.callback = callback; + request_info.callback = std::move(callback); request_infos_.push_back(std::move(request_info)); } void StartCancellableRequest( std::unique_ptr request, - std::function&)> callback) + absl::AnyInvocable&)> callback) override { RequestInfo request_info; request_info.request = request->http_request(); - request_info.callback = callback; + request_info.callback = std::move(callback); request_infos_.push_back(std::move(request_info)); } @@ -90,8 +91,8 @@ class FakeHttpClient : public HttpClient { if (pos >= request_infos_.size()) { return; } - auto request_info = request_infos_.at(pos); - if (request_info.callback != nullptr) { + auto& request_info = request_infos_.at(pos); + if (request_info.callback) { request_info.callback(response); } From 48eeee8d2b884af1cd5daac571b181d10979ed8b Mon Sep 17 00:00:00 2001 From: Janusz Sobczak Date: Fri, 15 Sep 2023 16:24:44 -0700 Subject: [PATCH 018/683] Migrate to AnyInvocable in webrtc medium PiperOrigin-RevId: 565805742 --- connections/implementation/mediums/webrtc/BUILD | 1 + .../implementation/mediums/webrtc/data_channel_listener.h | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/connections/implementation/mediums/webrtc/BUILD b/connections/implementation/mediums/webrtc/BUILD index 2d15ee8d..1928212b 100644 --- a/connections/implementation/mediums/webrtc/BUILD +++ b/connections/implementation/mediums/webrtc/BUILD @@ -42,6 +42,7 @@ cc_library( "//internal/platform:types", "//proto/mediums:web_rtc_signaling_frames_cc_proto", # TODO: Support WebRTC + "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/memory", "@com_google_absl//absl/time", ], diff --git a/connections/implementation/mediums/webrtc/data_channel_listener.h b/connections/implementation/mediums/webrtc/data_channel_listener.h index 8a98cda2..8e6edea8 100644 --- a/connections/implementation/mediums/webrtc/data_channel_listener.h +++ b/connections/implementation/mediums/webrtc/data_channel_listener.h @@ -17,9 +17,8 @@ #ifndef NO_WEBRTC +#include "absl/functional/any_invocable.h" #include "connections/implementation/mediums/webrtc_socket.h" -#include "connections/listeners.h" -#include "internal/platform/byte_array.h" namespace nearby { namespace connections { @@ -29,11 +28,11 @@ namespace mediums { struct DataChannelListener { // Called when the data channel is open and the socket wraper is ready to // read and write. - std::function data_channel_open_cb = + absl::AnyInvocable data_channel_open_cb = [](WebRtcSocketWrapper) {}; // Called when the data channel is closed. - std::function data_channel_closed_cb = []() {}; + absl::AnyInvocable data_channel_closed_cb = []() {}; }; } // namespace mediums From 746a8b62314f5ac82d782eb86f5965c3d514108e Mon Sep 17 00:00:00 2001 From: Janusz Sobczak Date: Mon, 18 Sep 2023 15:55:33 -0700 Subject: [PATCH 019/683] Use AnyInvocable in mediums/ble_v2 PiperOrigin-RevId: 566437160 --- connections/implementation/mediums/ble_v2.cc | 36 +++++++++---------- .../ble_v2/discovered_peripheral_tracker.cc | 14 ++++---- .../ble_v2/discovered_peripheral_tracker.h | 26 ++++++-------- .../discovered_peripheral_tracker_test.cc | 31 ++++++++-------- 4 files changed, 48 insertions(+), 59 deletions(-) diff --git a/connections/implementation/mediums/ble_v2.cc b/connections/implementation/mediums/ble_v2.cc index 88131d85..03174d6e 100644 --- a/connections/implementation/mediums/ble_v2.cc +++ b/connections/implementation/mediums/ble_v2.cc @@ -24,6 +24,7 @@ #include "absl/time/time.h" #include "absl/types/optional.h" #include "connections/implementation/flags/nearby_connections_feature_flags.h" +#include "connections/implementation/mediums/ble_v2/advertisement_read_result.h" #include "connections/implementation/mediums/ble_v2/ble_advertisement.h" #include "connections/implementation/mediums/ble_v2/ble_advertisement_header.h" #include "connections/implementation/mediums/ble_v2/ble_utils.h" @@ -273,25 +274,22 @@ bool BleV2::StartScanning(const std::string& service_id, PowerLevel power_level, discovered_peripheral_tracker_ .ProcessFoundBleAdvertisement( std::move(peripheral), advertisement_data, - { - .fetch_advertisements = - [&](BleV2Peripheral peripheral, - int num_slots, int psm, - const std::vector& - interesting_service_ids, - mediums::AdvertisementReadResult& - advertisement_read_result) { - // Th`mutex_` is already held here. Use - // `AssumeHeld` tell the thread - // annotation static analysis that - // `mutex_` is already exclusively - // locked. - AssumeHeld(mutex_); - ProcessFetchGattAdvertisementsRequest( - std::move(peripheral), num_slots, - psm, interesting_service_ids, - advertisement_read_result); - }, + [this](BleV2Peripheral peripheral, int num_slots, + int psm, + const std::vector& + interesting_service_ids, + mediums::AdvertisementReadResult& + advertisement_read_result) { + // Th`mutex_` is already held here. Use + // `AssumeHeld` tell the thread + // annotation static analysis that + // `mutex_` is already exclusively + // locked. + AssumeHeld(mutex_); + ProcessFetchGattAdvertisementsRequest( + std::move(peripheral), num_slots, psm, + interesting_service_ids, + advertisement_read_result); }); }); }, diff --git a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.cc b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.cc index 024d6c62..949855ed 100644 --- a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.cc +++ b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.cc @@ -538,7 +538,7 @@ void DiscoveredPeripheralTracker::HandleAdvertisementHeader( advertisement_fetcher = std::move(advertisement_fetcher), advertisement_data = - std::move(advertisement_data)]() { + std::move(advertisement_data)]() mutable { { MutexLock lock(&mutex_); if (!IsInterestingAdvertisementHeader(advertisement_header)) { @@ -680,9 +680,9 @@ DiscoveredPeripheralTracker::FetchRawAdvertisements( std::transform(service_id_infos_.begin(), service_id_infos_.end(), std::back_inserter(service_ids), [](auto& kv) { return kv.first; }); - advertisement_fetcher.fetch_advertisements( - std::move(peripheral), advertisement_header.GetNumSlots(), - advertisement_header.GetPsm(), service_ids, *result); + advertisement_fetcher(std::move(peripheral), + advertisement_header.GetNumSlots(), + advertisement_header.GetPsm(), service_ids, *result); // Take those results and return all the advertisements we were able to // read. @@ -709,9 +709,9 @@ DiscoveredPeripheralTracker::FetchRawAdvertisementsInThread( std::back_inserter(service_ids), [](auto& kv) { return kv.first; }); } - advertisement_fetcher.fetch_advertisements( - std::move(peripheral), advertisement_header.GetNumSlots(), - advertisement_header.GetPsm(), service_ids, *result); + advertisement_fetcher(std::move(peripheral), + advertisement_header.GetNumSlots(), + advertisement_header.GetPsm(), service_ids, *result); // Take those results and return all the advertisements we were able to // read. diff --git a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h index 380d6bd5..7e463ed5 100644 --- a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h +++ b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h @@ -15,7 +15,6 @@ #ifndef CORE_INTERNAL_MEDIUMS_BLE_V2_DISCOVERED_PERIPHERAL_TRACKER_H_ #define CORE_INTERNAL_MEDIUMS_BLE_V2_DISCOVERED_PERIPHERAL_TRACKER_H_ -#include #include #include #include @@ -23,13 +22,13 @@ #include "absl/base/thread_annotations.h" #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" +#include "absl/functional/any_invocable.h" #include "connections/implementation/mediums//lost_entity_tracker.h" #include "connections/implementation/mediums/ble_v2/advertisement_read_result.h" #include "connections/implementation/mediums/ble_v2/ble_advertisement.h" #include "connections/implementation/mediums/ble_v2/ble_advertisement_header.h" #include "connections/implementation/mediums/ble_v2/discovered_peripheral_callback.h" #include "connections/implementation/mediums/lost_entity_tracker.h" -#include "internal/platform/bluetooth_adapter.h" #include "internal/platform/byte_array.h" #include "internal/platform/multi_thread_executor.h" #include "internal/platform/mutex.h" @@ -47,20 +46,15 @@ namespace mediums { class DiscoveredPeripheralTracker { public: // GATT advertisement fetcher. - struct AdvertisementFetcher { - // Fetches relevant GATT advertisements for the peripheral found in {@link - // DiscoveredPeripheralTracker#ProcessFoundBleAdvertisement(}. - // - // `advertisement_read_result` is in/out mutable reference that the caller - // should take of its life cycle and pass a valid reference. - std::function& interesting_service_ids, - mediums::AdvertisementReadResult& advertisement_read_result)> - fetch_advertisements = [](BleV2Peripheral, int, int, - const std::vector&, - mediums::AdvertisementReadResult&) {}; - }; + // Fetches relevant GATT advertisements for the peripheral found in {@link + // DiscoveredPeripheralTracker#ProcessFoundBleAdvertisement(}. + // + // `advertisement_read_result` is in/out mutable reference that the caller + // should take of its life cycle and pass a valid reference. + using AdvertisementFetcher = absl::AnyInvocable& interesting_service_ids, + mediums::AdvertisementReadResult& advertisement_read_result)>; explicit DiscoveredPeripheralTracker( bool is_extended_advertisement_available = false); diff --git a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker_test.cc b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker_test.cc index 8379b4b0..45993a01 100644 --- a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker_test.cc +++ b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker_test.cc @@ -18,6 +18,7 @@ #include #include "gtest/gtest.h" +#include "connections/implementation/mediums/ble_v2/advertisement_read_result.h" #include "connections/implementation/mediums/ble_v2/ble_utils.h" #include "connections/implementation/mediums/ble_v2/bloom_filter.h" #include "internal/platform/ble_v2.h" @@ -152,23 +153,19 @@ class DiscoveredPeripheralTrackerTest : public testing::Test { DiscoveredPeripheralTracker::AdvertisementFetcher GetAdvertisementFetcher( CountDownLatch& fetch_latch, const std::vector& advertisement_bytes_list) { - return { - .fetch_advertisements = - [this, &fetch_latch, &advertisement_bytes_list]( - BleV2Peripheral peripheral, int num_slots, int psm, - const std::vector& interesting_service_ids, - mediums::AdvertisementReadResult& advertisement_read_result) { - MutexLock lock(&mutex_); - fetch_count_++; - int slot = 0; - for (const auto& advertisement_bytes : advertisement_bytes_list) { - advertisement_read_result.AddAdvertisement(slot++, - advertisement_bytes); - } - advertisement_read_result.RecordLastReadStatus( - /*is_success=*/true); - fetch_latch.CountDown(); - }, + return [this, &fetch_latch, &advertisement_bytes_list]( + BleV2Peripheral peripheral, int num_slots, int psm, + const std::vector& interesting_service_ids, + mediums::AdvertisementReadResult& advertisement_read_result) { + MutexLock lock(&mutex_); + fetch_count_++; + int slot = 0; + for (const auto& advertisement_bytes : advertisement_bytes_list) { + advertisement_read_result.AddAdvertisement(slot++, advertisement_bytes); + } + advertisement_read_result.RecordLastReadStatus( + /*is_success=*/true); + fetch_latch.CountDown(); }; } From 9774b5f53cbf68fb4d698c587cf2ec1033608e52 Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Mon, 18 Sep 2023 16:55:59 -0700 Subject: [PATCH 020/683] Fixed crash in Bluetooth Adapter PiperOrigin-RevId: 566452194 --- .../windows/bluetooth_adapter.cc | 30 ++++++++++++------- .../windows/bluetooth_adapter.h | 2 +- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/internal/platform/implementation/windows/bluetooth_adapter.cc b/internal/platform/implementation/windows/bluetooth_adapter.cc index 0c2675e3..7f9d143c 100644 --- a/internal/platform/implementation/windows/bluetooth_adapter.cc +++ b/internal/platform/implementation/windows/bluetooth_adapter.cc @@ -1,4 +1,4 @@ -// Copyright 2020 Google LLC +// Copyright 2020-2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -32,7 +32,9 @@ #include #include +#include #include +#include #include #include "absl/strings/str_format.h" @@ -342,14 +344,15 @@ std::string BluetoothAdapter::GetName() const { return *device_name_; } - char *_instance_id = GetGenericBluetoothAdapterInstanceID(); - if (_instance_id == nullptr) { + std::optional adapter_instance_id = + GetGenericBluetoothAdapterInstanceID(); + if (!adapter_instance_id.has_value()) { NEARBY_LOGS(ERROR) << __func__ << ": Failed to get Generic Bluetooth Adapter InstanceID"; return std::string(); } - std::string instance_id(_instance_id); + std::string instance_id = *adapter_instance_id; // Change radio module local name in registry HKEY hKey; @@ -435,13 +438,16 @@ bool BluetoothAdapter::SetName(absl::string_view name, bool persist) { return true; } - std::string instance_id(GetGenericBluetoothAdapterInstanceID()); + std::optional adapter_instance_id = + GetGenericBluetoothAdapterInstanceID(); - if (instance_id.empty()) { + if (!adapter_instance_id.has_value()) { NEARBY_LOGS(ERROR) << __func__ << ": Failed to get Generic Bluetooth Adapter InstanceID"; return false; } + + std::string instance_id = *adapter_instance_id; // defined in usbiodef.h const GUID guid = GUID_DEVINTERFACE_USB_DEVICE; @@ -697,7 +703,8 @@ void BluetoothAdapter::find_and_replace(char *source, const char *strFind, memcpy(source, s.c_str(), s.size()); } -char *BluetoothAdapter::GetGenericBluetoothAdapterInstanceID(void) const { +std::optional +BluetoothAdapter::GetGenericBluetoothAdapterInstanceID() const { unsigned i; CONFIGRET r; HDEVINFO hDevInfo; @@ -715,7 +722,7 @@ char *BluetoothAdapter::GetGenericBluetoothAdapterInstanceID(void) const { if (hDevInfo == INVALID_HANDLE_VALUE) { NEARBY_LOGS(ERROR) << __func__ << ": Could not find BluetoothDevice on this machine"; - return NULL; + return std::nullopt; } // Get first Generic Bluetooth Adapter InstanceID @@ -741,14 +748,15 @@ char *BluetoothAdapter::GetGenericBluetoothAdapterInstanceID(void) const { // computer's USB ports. // https://docs.microsoft.com/en-us/windows-hardware/drivers/bluetooth/bluetooth-host-radio-support if (strncmp("USB", deviceInstanceID, 3) == 0) { - return deviceInstanceID; + SetupDiDestroyDeviceInfoList(hDevInfo); + return std::string(deviceInstanceID); } } NEARBY_LOGS(ERROR) << __func__ << ": Failed to get the generic bluetooth adapter id"; - - return NULL; + SetupDiDestroyDeviceInfoList(hDevInfo); + return std::nullopt; } // Returns BT MAC address assigned to this adapter. diff --git a/internal/platform/implementation/windows/bluetooth_adapter.h b/internal/platform/implementation/windows/bluetooth_adapter.h index 9d5fbc0f..d1e6a001 100644 --- a/internal/platform/implementation/windows/bluetooth_adapter.h +++ b/internal/platform/implementation/windows/bluetooth_adapter.h @@ -109,7 +109,7 @@ class BluetoothAdapter : public api::BluetoothAdapter { std::string registry_bluetooth_adapter_name_; IRadio windows_bluetooth_radio_; - char *GetGenericBluetoothAdapterInstanceID() const; + std::optional GetGenericBluetoothAdapterInstanceID() const; void find_and_replace(char *source, const char *strFind, const char *strReplace) const; ScanMode scan_mode_ = ScanMode::kNone; From 94df1ffc4c00ff142d2f1f7c6c603f80d922bca4 Mon Sep 17 00:00:00 2001 From: hai007 Date: Mon, 18 Sep 2023 18:03:02 -0700 Subject: [PATCH 021/683] Records the dual band support status PiperOrigin-RevId: 566465959 --- internal/proto/analytics/connections_log.proto | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/proto/analytics/connections_log.proto b/internal/proto/analytics/connections_log.proto index 09fdb890..e2e194c7 100644 --- a/internal/proto/analytics/connections_log.proto +++ b/internal/proto/analytics/connections_log.proto @@ -420,6 +420,9 @@ message ConnectionsLog { // The power level of this advertising optional location.nearby.proto.connections.PowerLevel power_level = 5; + + // The dual band support status + optional bool supports_dual_band = 6; } // Some additional information to keep with the discovery phase. From 8846f8b57e53276687955562f58d2bfdbf63b3a9 Mon Sep 17 00:00:00 2001 From: Janusz Sobczak Date: Tue, 19 Sep 2023 13:11:50 -0700 Subject: [PATCH 022/683] Migrate to AnyInvocable in data/ PiperOrigin-RevId: 566721712 --- internal/data/BUILD | 1 + internal/data/data_set.h | 12 ++++++---- internal/data/leveldb_data_set.h | 32 ++++++++++++++------------ internal/data/memory_data_set.h | 23 +++++++++++-------- internal/test/fake_data_set.h | 39 ++++++++++++++++---------------- 5 files changed, 58 insertions(+), 49 deletions(-) diff --git a/internal/data/BUILD b/internal/data/BUILD index 8628ea53..dce7d36c 100644 --- a/internal/data/BUILD +++ b/internal/data/BUILD @@ -21,6 +21,7 @@ cc_library( "//third_party/leveldb:util", "//third_party/protobuf:protobuf_lite", "@com_google_absl//absl/container:flat_hash_map", + "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/strings", "@com_google_absl//absl/synchronization", ], diff --git a/internal/data/data_set.h b/internal/data/data_set.h index c87492a4..65ce127d 100644 --- a/internal/data/data_set.h +++ b/internal/data/data_set.h @@ -15,12 +15,13 @@ #ifndef THIRD_PARTY_NEARBY_INTERNAL_DATA_DATA_SET_H_ #define THIRD_PARTY_NEARBY_INTERNAL_DATA_DATA_SET_H_ -#include #include #include #include #include +#include "absl/functional/any_invocable.h" + namespace nearby { namespace data { @@ -43,12 +44,13 @@ class DataSet { // Asynchronously initializes the object, which must have been created by the // DataManager::GetDataSet function. |callback| will be invoked on the // calling thread when complete. - virtual void Initialize(std::function callback) = 0; + virtual void Initialize(absl::AnyInvocable callback) = 0; // Asynchronously loads all entries from the database and invokes |callback| // when complete. virtual void LoadEntries( - std::function>)> callback) = 0; + absl::AnyInvocable>) &&> + callback) = 0; // Asynchronously saves |entries_to_save| and deletes entries from // |keys_to_remove| from the database. |callback| will be invoked on the @@ -57,11 +59,11 @@ class DataSet { virtual void UpdateEntries( std::unique_ptr entries_to_save, std::unique_ptr> keys_to_remove, - std::function callback) = 0; + absl::AnyInvocable callback) = 0; // Asynchronously destroys the database. Use this call only if the database // needs to be destroyed for this particular profile. - virtual void Destroy(std::function callback) = 0; + virtual void Destroy(absl::AnyInvocable callback) = 0; }; } // namespace data diff --git a/internal/data/leveldb_data_set.h b/internal/data/leveldb_data_set.h index c55a57bc..5ad4648c 100644 --- a/internal/data/leveldb_data_set.h +++ b/internal/data/leveldb_data_set.h @@ -15,14 +15,13 @@ #ifndef THIRD_PARTY_NEARBY_INTERNAL_DATA_LEVELDB_DATA_SET_H_ #define THIRD_PARTY_NEARBY_INTERNAL_DATA_LEVELDB_DATA_SET_H_ -#include #include -#include #include #include #include #include +#include "absl/functional/any_invocable.h" #include "absl/strings/string_view.h" #include "third_party/leveldb/include/db.h" #include "third_party/leveldb/include/iterator.h" @@ -47,17 +46,19 @@ class LeveldbDataSet : public DataSet { explicit LeveldbDataSet(absl::string_view path) : path_(path) {} ~LeveldbDataSet() override = default; - void Initialize(std::function callback) override; - void LoadEntries(std::function>)> - callback) override; + void Initialize(absl::AnyInvocable callback) override; + void LoadEntries( + absl::AnyInvocable>) &&> + callback) override; void LoadEntriesWithKeys( - std::function< - void(bool, std::unique_ptr>>)> + absl::AnyInvocable< + void(bool, + std::unique_ptr>>) &&> callback); void UpdateEntries(std::unique_ptr entries_to_save, std::unique_ptr> keys_to_remove, - std::function callback) override; - void Destroy(std::function callback) override; + absl::AnyInvocable callback) override; + void Destroy(absl::AnyInvocable callback) override; private: void Serialize(T const& value, std::string& str); @@ -73,7 +74,7 @@ template ::value, bool> isMessageLite> void LeveldbDataSet::Initialize( - std::function callback) { + absl::AnyInvocable callback) { leveldb::Options options; options.create_if_missing = true; @@ -99,7 +100,8 @@ template ::value, bool> isMessageLite> void LeveldbDataSet::LoadEntries( - std::function>)> callback) { + absl::AnyInvocable>) &&> + callback) { auto result = std::make_unique>(); if (status_ != InitStatus::kOK) { std::move(callback)(false, std::move(result)); @@ -130,8 +132,8 @@ template ::value, bool> isMessageLite> void LeveldbDataSet::LoadEntriesWithKeys( - std::function>>)> + absl::AnyInvocable< + void(bool, std::unique_ptr>>) &&> callback) { auto result = std::make_unique>>(); if (status_ != InitStatus::kOK) { @@ -165,7 +167,7 @@ template ::UpdateEntries( std::unique_ptr entries_to_save, std::unique_ptr> keys_to_remove, - std::function callback) { + absl::AnyInvocable callback) { NEARBY_LOGS(INFO) << "UpdateEntries is called."; if (status_ != InitStatus::kOK) { std::move(callback)(false); @@ -193,7 +195,7 @@ template ::value, bool> isMessageLite> void LeveldbDataSet::Destroy( - std::function callback) { + absl::AnyInvocable callback) { NEARBY_LOGS(INFO) << "Destroy is called."; db_.reset(); leveldb::DestroyDB(path_, leveldb::Options()); diff --git a/internal/data/memory_data_set.h b/internal/data/memory_data_set.h index 48074573..9cf5fca2 100644 --- a/internal/data/memory_data_set.h +++ b/internal/data/memory_data_set.h @@ -15,13 +15,13 @@ #ifndef THIRD_PARTY_NEARBY_INTERNAL_DATA_MEMORY_DATA_SET_H_ #define THIRD_PARTY_NEARBY_INTERNAL_DATA_MEMORY_DATA_SET_H_ -#include #include #include #include #include #include "absl/container/flat_hash_map.h" +#include "absl/functional/any_invocable.h" #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" #include "internal/data/data_set.h" @@ -37,13 +37,14 @@ class MemoryDataSet : public DataSet { explicit MemoryDataSet(absl::string_view path) : path_(path) {} ~MemoryDataSet() override = default; - void Initialize(std::function callback) override; - void LoadEntries(std::function>)> - callback) override; + void Initialize(absl::AnyInvocable callback) override; + void LoadEntries( + absl::AnyInvocable>) &&> + callback) override; void UpdateEntries(std::unique_ptr entries_to_save, std::unique_ptr> keys_to_remove, - std::function callback) override; - void Destroy(std::function callback) override; + absl::AnyInvocable callback) override; + void Destroy(absl::AnyInvocable callback) override; private: std::string path_; @@ -53,13 +54,15 @@ class MemoryDataSet : public DataSet { }; template -void MemoryDataSet::Initialize(std::function callback) { +void MemoryDataSet::Initialize( + absl::AnyInvocable callback) { std::move(callback)(InitStatus::kOK); } template void MemoryDataSet::LoadEntries( - std::function>)> callback) { + absl::AnyInvocable>) &&> + callback) { auto result = std::make_unique>(); auto it = entries_.begin(); while (it != entries_.end()) { @@ -74,7 +77,7 @@ template void MemoryDataSet::UpdateEntries( std::unique_ptr entries_to_save, std::unique_ptr> keys_to_remove, - std::function callback) { + absl::AnyInvocable callback) { if (entries_to_save != nullptr) { auto it = entries_to_save->begin(); while (it != entries_to_save->end()) { @@ -95,7 +98,7 @@ void MemoryDataSet::UpdateEntries( } template -void MemoryDataSet::Destroy(std::function callback) { +void MemoryDataSet::Destroy(absl::AnyInvocable callback) { entries_.clear(); std::move(callback)(true); } diff --git a/internal/test/fake_data_set.h b/internal/test/fake_data_set.h index 7393abda..43494207 100644 --- a/internal/test/fake_data_set.h +++ b/internal/test/fake_data_set.h @@ -22,6 +22,7 @@ #include #include "absl/container/flat_hash_map.h" +#include "absl/functional/any_invocable.h" #include "internal/data/data_set.h" namespace nearby { @@ -35,41 +36,42 @@ class FakeDataSet : public DataSet { explicit FakeDataSet(const absl::flat_hash_map& entries_map) : entries_map_(entries_map) {} - void Initialize(std::function callback) override { + void Initialize(absl::AnyInvocable callback) override { init_callback_ = std::move(callback); } - void LoadEntries(std::function>)> - callback) override { + void LoadEntries( + absl::AnyInvocable>) &&> + callback) override { load_callback_ = std::move(callback); } void UpdateEntries(std::unique_ptr entries_to_save, std::unique_ptr> keys_to_remove, - std::function callback) override { + absl::AnyInvocable callback) override { entries_to_save_ = std::move(entries_to_save); keys_to_remove_ = std::move(keys_to_remove); update_callback_ = std::move(callback); } - void Destroy(std::function callback) override { + void Destroy(absl::AnyInvocable callback) override { destroy_callback_ = std::move(callback); } // Mocked methods void InitStatusCallback(InitStatus status) { - if (init_callback_ != nullptr) { - init_callback_(status); + if (auto callback = std::move(init_callback_)) { + std::move(callback)(status); } } void LoadCallback(bool success) { - if (load_callback_ != nullptr) { + if (auto callback = std::move(load_callback_)) { auto entries = std::make_unique>(); for (auto it = entries_map_.begin(); it != entries_map_.end(); ++it) { entries->push_back(it->second); } - load_callback_(success, std::move(entries)); + std::move(callback)(success, std::move(entries)); } } @@ -97,8 +99,8 @@ class FakeDataSet : public DataSet { entries_to_save_ = nullptr; keys_to_remove_ = nullptr; - if (update_callback_ != nullptr) { - update_callback_(success); + if (auto callback = std::move(update_callback_)) { + std::move(callback)(success); } } @@ -106,9 +108,8 @@ class FakeDataSet : public DataSet { if (success) { entries_map_.clear(); } - - if (destroy_callback_ != nullptr) { - destroy_callback_(success); + if (auto callback = std::move(destroy_callback_)) { + std::move(callback)(success); } } @@ -116,13 +117,13 @@ class FakeDataSet : public DataSet { private: absl::flat_hash_map entries_map_ = nullptr; - std::function init_callback_ = nullptr; - std::function>)> load_callback_ = - nullptr; + absl::AnyInvocable init_callback_ = nullptr; + absl::AnyInvocable>) &&> + load_callback_ = nullptr; std::unique_ptr entries_to_save_ = nullptr; std::unique_ptr> keys_to_remove_ = nullptr; - std::function update_callback_ = nullptr; - std::function destroy_callback_ = nullptr; + absl::AnyInvocable update_callback_ = nullptr; + absl::AnyInvocable destroy_callback_ = nullptr; }; } // namespace data From 6adba4c2f8ce6b8c6d49974ff4cad5dd2029d62a Mon Sep 17 00:00:00 2001 From: Hai Shang Date: Tue, 19 Sep 2023 20:22:16 -0700 Subject: [PATCH 023/683] [Analytics] log certificates stats after download PiperOrigin-RevId: 566828025 --- proto/sharing_enums.proto | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proto/sharing_enums.proto b/proto/sharing_enums.proto index 3d1d9f87..1225adca 100644 --- a/proto/sharing_enums.proto +++ b/proto/sharing_enums.proto @@ -502,6 +502,9 @@ enum ServerActionName { LIST_REACHABLE_PHONE_NUMBERS = 9; LIST_MY_DEVICES = 10; LIST_CONTACT_PEOPLE = 11; + + // used for analytics logger to record action name. + DOWNLOAD_CERTIFICATES_INFO = 12; } // The Fast Share server response state. From 1e5587e2db3f332aaaee656c27d1efac1fecb7a7 Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Wed, 20 Sep 2023 10:57:29 -0700 Subject: [PATCH 024/683] Log the failure to get RF service PiperOrigin-RevId: 567017321 --- .../implementation/windows/bluetooth_classic_device.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/internal/platform/implementation/windows/bluetooth_classic_device.cc b/internal/platform/implementation/windows/bluetooth_classic_device.cc index 707ebd62..699aa1fa 100644 --- a/internal/platform/implementation/windows/bluetooth_classic_device.cc +++ b/internal/platform/implementation/windows/bluetooth_classic_device.cc @@ -1,4 +1,4 @@ -// Copyright 2020 Google LLC +// Copyright 2020-2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -117,6 +117,9 @@ RfcommDeviceService BluetoothDevice::GetRfcommServiceForIdAsync( } } + NEARBY_LOGS(ERROR) + << __func__ + << ": Failed to get RfcommDeviceService due to no any services."; return nullptr; } catch (std::exception exception) { NEARBY_LOGS(ERROR) << __func__ << ": Failed to get RfcommDeviceService: " From 7bde3abf8b21c1dfa29f1ed523681b5904d60ccd Mon Sep 17 00:00:00 2001 From: Aaron Yu Date: Wed, 20 Sep 2023 13:47:42 -0700 Subject: [PATCH 025/683] Harden ble v2 gatt server PiperOrigin-RevId: 567069079 --- .../implementation/windows/ble_gatt_client.cc | 7 ++ .../implementation/windows/ble_gatt_server.cc | 34 ++++++++- .../windows/bluetooth_adapter.cc | 69 +++++++++++++++++++ .../windows/bluetooth_adapter.h | 10 +++ .../windows/bluetooth_adapter_test.cc | 15 ++++ 5 files changed, 133 insertions(+), 2 deletions(-) diff --git a/internal/platform/implementation/windows/ble_gatt_client.cc b/internal/platform/implementation/windows/ble_gatt_client.cc index 41d56644..7c553252 100644 --- a/internal/platform/implementation/windows/ble_gatt_client.cc +++ b/internal/platform/implementation/windows/ble_gatt_client.cc @@ -122,6 +122,13 @@ bool BleGattClient::DiscoverServiceAndCharacteristics( return false; } + if (!windows_bluetooth_adapter_.IsCentralRoleSupported()) { + NEARBY_LOGS(ERROR) << __func__ + << ": Bluetooth Hardware does not support Central " + "Role, which is required to start GATT client."; + return false; + } + if (!NearbyFlags::GetInstance().GetBoolFlag( platform::config_package_nearby::nearby_platform_feature:: kEnableBleV2GattOnNonExtendedDevice)) { diff --git a/internal/platform/implementation/windows/ble_gatt_server.cc b/internal/platform/implementation/windows/ble_gatt_server.cc index ea4ef93d..9dfe45db 100644 --- a/internal/platform/implementation/windows/ble_gatt_server.cc +++ b/internal/platform/implementation/windows/ble_gatt_server.cc @@ -226,6 +226,13 @@ bool BleGattServer::InitializeGattServer() { return false; } + if (!adapter_->IsLowEnergySupported()) { + NEARBY_LOGS(ERROR) << __func__ + << ": Bluetooth adapter does not support BLE, which " + "is needed to start GATT server."; + return false; + } + winrt::guid service_uuid = nearby_uuid_to_winrt_guid(service_uuid_); GattServiceProviderResult service_provider_result = GattServiceProvider::CreateAsync(service_uuid).get(); @@ -371,14 +378,37 @@ bool BleGattServer::StartAdvertisement(const ByteArray& service_data, return false; } - is_advertising_ = true; - if (!is_gatt_server_inited_ && !InitializeGattServer()) { NEARBY_LOGS(ERROR) << ":Failed to initalize GATT service."; is_advertising_ = false; return false; } + if (gatt_service_provider_ == nullptr) { + NEARBY_LOGS(WARNING) << __func__ << ": no GATT server is running."; + is_advertising_ = false; + return false; + } + + if (gatt_service_provider_.AdvertisementStatus() == + GattServiceProviderAdvertisementStatus::Started) { + NEARBY_LOGS(WARNING) << __func__ + << ": GATT server is already in advertising."; + is_advertising_ = true; + return false; + } + + if (!adapter_->IsPeripheralRoleSupported()) { + NEARBY_LOGS(ERROR) + << __func__ + << ": Bluetooth Hardware does not support Peripheral Role, which is " + "required to start GATT server."; + is_advertising_ = false; + return false; + } + + is_advertising_ = true; + // Start the GATT server advertising GattServiceProviderAdvertisingParameters advertisement_parameters; advertisement_parameters.IsConnectable(is_connectable); diff --git a/internal/platform/implementation/windows/bluetooth_adapter.cc b/internal/platform/implementation/windows/bluetooth_adapter.cc index 7f9d143c..42f0832c 100644 --- a/internal/platform/implementation/windows/bluetooth_adapter.cc +++ b/internal/platform/implementation/windows/bluetooth_adapter.cc @@ -218,6 +218,75 @@ bool BluetoothAdapter::IsExtendedAdvertisingSupported() const { } } +// Returns true if the Bluetooth hardware supports BLE Central Role +bool BluetoothAdapter::IsCentralRoleSupported() const { + if (windows_bluetooth_adapter_ == nullptr) { + NEARBY_LOGS(ERROR) << __func__ << ": No Bluetooth adapter on this device."; + return false; + } + try { + // Indicates whether the adapter supports the BLE Central Role + // https://learn.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.bluetoothadapter.iscentralrolesupported?view=winrt-22621 + return windows_bluetooth_adapter_.IsCentralRoleSupported(); + } catch (std::exception exception) { + NEARBY_LOGS(ERROR) << __func__ << ": exception:" << exception.what(); + return false; + } catch (const winrt::hresult_error &ex) { + NEARBY_LOGS(ERROR) << __func__ << ": exception:" << ex.code() << ": " + << winrt::to_string(ex.message()); + return false; + } catch (...) { + NEARBY_LOGS(ERROR) << __func__ << ": unknown error."; + return false; + } +} + +// Returns true if the Bluetooth hardware supports BLE Peripheral Role +bool BluetoothAdapter::IsPeripheralRoleSupported() const { + if (windows_bluetooth_adapter_ == nullptr) { + NEARBY_LOGS(ERROR) << __func__ << ": No Bluetooth adapter on this device."; + return false; + } + try { + // Indicates whether the adapter supports the BLE Peripheral Role + // https://learn.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.bluetoothadapter.isperipheralrolesupported?view=winrt-22621 + return windows_bluetooth_adapter_.IsPeripheralRoleSupported(); + } catch (std::exception exception) { + NEARBY_LOGS(ERROR) << __func__ << ": exception:" << exception.what(); + return false; + } catch (const winrt::hresult_error &ex) { + NEARBY_LOGS(ERROR) << __func__ << ": exception:" << ex.code() << ": " + << winrt::to_string(ex.message()); + return false; + } catch (...) { + NEARBY_LOGS(ERROR) << __func__ << ": unknown error."; + return false; + } +} + +// Returns true if the Bluetooth hardware supports BLE +bool BluetoothAdapter::IsLowEnergySupported() const { + if (windows_bluetooth_adapter_ == nullptr) { + NEARBY_LOGS(ERROR) << __func__ << ": No Bluetooth adapter on this device."; + return false; + } + try { + // Indicates whether the adapter supports BLE + // https://learn.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.bluetoothadapter.islowenergysupported?view=winrt-22621 + return windows_bluetooth_adapter_.IsLowEnergySupported(); + } catch (std::exception exception) { + NEARBY_LOGS(ERROR) << __func__ << ": exception:" << exception.what(); + return false; + } catch (const winrt::hresult_error &ex) { + NEARBY_LOGS(ERROR) << __func__ << ": exception:" << ex.code() << ": " + << winrt::to_string(ex.message()); + return false; + } catch (...) { + NEARBY_LOGS(ERROR) << __func__ << ": unknown error."; + return false; + } +} + // https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#getScanMode() // // Returns ScanMode::kUnknown on error. diff --git a/internal/platform/implementation/windows/bluetooth_adapter.h b/internal/platform/implementation/windows/bluetooth_adapter.h index d1e6a001..dadb2f9a 100644 --- a/internal/platform/implementation/windows/bluetooth_adapter.h +++ b/internal/platform/implementation/windows/bluetooth_adapter.h @@ -98,6 +98,16 @@ class BluetoothAdapter : public api::BluetoothAdapter { // Returns true if the Bluetooth hardware supports Bluetooth 5.0 Extended // Advertising bool IsExtendedAdvertisingSupported() const; + + // Returns true if the Bluetooth hardware supports BLE Central Role + bool IsCentralRoleSupported() const; + + // Returns true if the Bluetooth hardware supports BLE Peripheral Role + bool IsPeripheralRoleSupported() const; + + // Returns true if the Bluetooth hardware supports BLE + bool IsLowEnergySupported() const; + void RestoreRadioNameIfNecessary(); private: diff --git a/internal/platform/implementation/windows/bluetooth_adapter_test.cc b/internal/platform/implementation/windows/bluetooth_adapter_test.cc index 8c9c5ae1..32577ca2 100644 --- a/internal/platform/implementation/windows/bluetooth_adapter_test.cc +++ b/internal/platform/implementation/windows/bluetooth_adapter_test.cc @@ -183,6 +183,21 @@ TEST(BluetoothAdapter, DISABLED_IsExtendedAdvertisingSupported) { EXPECT_TRUE(bluetooth_adapter.IsExtendedAdvertisingSupported()); } +TEST(BluetoothAdapter, DISABLED_IsCentralRoleSupported) { + BluetoothAdapter bluetooth_adapter; + EXPECT_TRUE(bluetooth_adapter.IsCentralRoleSupported()); +} + +TEST(BluetoothAdapter, DISABLED_IsPeripheralRoleSupported) { + BluetoothAdapter bluetooth_adapter; + EXPECT_TRUE(bluetooth_adapter.IsPeripheralRoleSupported()); +} + +TEST(BluetoothAdapter, DISABLED_IsLowEnergySupported) { + BluetoothAdapter bluetooth_adapter; + EXPECT_TRUE(bluetooth_adapter.IsLowEnergySupported()); +} + TEST(BluetoothAdapter, DISABLED_GetNameFromComputerName) { BluetoothAdapter bluetooth_adapter; EXPECT_TRUE(!bluetooth_adapter.GetNameFromComputerName().empty()); From 77bc7311c6c33e447f219e957338d6ab660b2cec Mon Sep 17 00:00:00 2001 From: hai007 Date: Thu, 21 Sep 2023 15:35:21 -0700 Subject: [PATCH 026/683] Fix bug to work with PIE SDK version PHWFW07641_22.230.0.8PDK-20230707T202651Z-001 PiperOrigin-RevId: 567438343 --- internal/platform/implementation/windows/wifi_intel.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/platform/implementation/windows/wifi_intel.cc b/internal/platform/implementation/windows/wifi_intel.cc index 800b37bc..844852da 100644 --- a/internal/platform/implementation/windows/wifi_intel.cc +++ b/internal/platform/implementation/windows/wifi_intel.cc @@ -185,6 +185,8 @@ uint8_t WifiIntel::GetGOChannel() { NEARBY_LOGS(VERBOSE) << "Load WifiPanQueryPreferredChannelSetting API completed successfully"; + intelWifiHeader.dwSize = + sizeof(MurocDefs::INTEL_GO_OPERATION_CHANNEL_SETTING); murocApiRetVal = WifiPanQueryPreferredChannelSettingFunc( wifi_adapter_handle_, &intelWifiHeader, (void*)&intelGOChan); From c0fed171f25c3e345ae52261df68c0c676535aa5 Mon Sep 17 00:00:00 2001 From: hai007 Date: Mon, 25 Sep 2023 13:52:15 -0700 Subject: [PATCH 027/683] Add several new fields to fast_pair_log PiperOrigin-RevId: 568315642 --- internal/proto/analytics/fast_pair_log.proto | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/internal/proto/analytics/fast_pair_log.proto b/internal/proto/analytics/fast_pair_log.proto index 702b38ea..81989e0f 100644 --- a/internal/proto/analytics/fast_pair_log.proto +++ b/internal/proto/analytics/fast_pair_log.proto @@ -151,4 +151,20 @@ message FastPairLog { // For the CREATE_BOND event, add bonding transport optional uint32 bonding_transport = 18; + + // Whether the current user is first day pairing a new device by fast pair. + // This is used for evaluating the A/B test of device pairing half sheet + // layout. + optional bool is_first_day_new_user = 19; + + // Whether the current user is first seven days pairing a new device by fast + // pair. This is used for evaluating the A/B test of device pairing half sheet + // layout. + optional bool is_seven_days_new_user = 20; + + // For the CREATE_BOND event, add bonded device count + optional uint32 bonded_device_count = 21; + + // SASS connection state for the device. Not set for non-SASS devices. + optional int32 sass_connection_state = 22; } From 6f936fa78b117d4bbd4f19918445fb4420a4bee2 Mon Sep 17 00:00:00 2001 From: hai007 Date: Mon, 25 Sep 2023 18:00:15 -0700 Subject: [PATCH 028/683] [Sharing] add an enum value for SYNC_PURPOSE. PiperOrigin-RevId: 568375213 --- proto/sharing_enums.proto | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proto/sharing_enums.proto b/proto/sharing_enums.proto index 1225adca..849993b4 100644 --- a/proto/sharing_enums.proto +++ b/proto/sharing_enums.proto @@ -563,6 +563,8 @@ enum SyncPurpose { SYNC_PURPOSE_VISIBILITY_SELECTED_CONTACT_CHANGE = 14; // When switching account. SYNC_PURPOSE_ACCOUNT_CHANGE = 15; + // When regenerate certificates + SYNC_PURPOSE_REGENERATE_CERTIFICATES = 16; } // The device role to trigger the server request. From 42787803fda4db387efa446953d2cdf29b379137 Mon Sep 17 00:00:00 2001 From: hai007 Date: Tue, 26 Sep 2023 15:58:59 -0700 Subject: [PATCH 029/683] Internal change PiperOrigin-RevId: 568673212 --- proto/BUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/proto/BUILD b/proto/BUILD index 7abb0cd9..937a3efd 100644 --- a/proto/BUILD +++ b/proto/BUILD @@ -15,6 +15,7 @@ # Proto for Nearby products # Placeholder: load py_proto_library + load("@rules_cc//cc:defs.bzl", "cc_proto_library") licenses(["notice"]) From a1a442c8ebdd706436684b5d5ab21bb0fe361707 Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Wed, 27 Sep 2023 15:46:15 -0700 Subject: [PATCH 030/683] Try to fix a crash when checking Bluetooth state PiperOrigin-RevId: 568982667 --- .../platform/implementation/windows/bluetooth_adapter.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/platform/implementation/windows/bluetooth_adapter.h b/internal/platform/implementation/windows/bluetooth_adapter.h index dadb2f9a..34923e48 100644 --- a/internal/platform/implementation/windows/bluetooth_adapter.h +++ b/internal/platform/implementation/windows/bluetooth_adapter.h @@ -40,7 +40,7 @@ using WindowsBluetoothAdapter = // Represents a radio device on the system. // https://docs.microsoft.com/en-us/uwp/api/windows.devices.radios.radio?view=winrt-20348 -using winrt::Windows::Devices::Radios::IRadio; +using winrt::Windows::Devices::Radios::Radio; // Enumeration that describes possible radio states. // https://docs.microsoft.com/en-us/uwp/api/windows.devices.radios.radiostate?view=winrt-20348 @@ -115,10 +115,10 @@ class BluetoothAdapter : public api::BluetoothAdapter { void StoreRadioNames(absl::string_view original_radio_name, absl::string_view nearby_radio_name); - WindowsBluetoothAdapter windows_bluetooth_adapter_; + WindowsBluetoothAdapter windows_bluetooth_adapter_ = nullptr; std::string registry_bluetooth_adapter_name_; - IRadio windows_bluetooth_radio_; + Radio windows_bluetooth_radio_ = nullptr; std::optional GetGenericBluetoothAdapterInstanceID() const; void find_and_replace(char *source, const char *strFind, const char *strReplace) const; From d095f505d3e9dfbd0a54c5f6cc4f2be3d375eeae Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Wed, 27 Sep 2023 16:07:43 -0700 Subject: [PATCH 031/683] Send payloads one by one PiperOrigin-RevId: 568988147 --- .../implementation/windows/bluetooth_classic_medium.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/internal/platform/implementation/windows/bluetooth_classic_medium.cc b/internal/platform/implementation/windows/bluetooth_classic_medium.cc index f1f98264..f670dd53 100644 --- a/internal/platform/implementation/windows/bluetooth_classic_medium.cc +++ b/internal/platform/implementation/windows/bluetooth_classic_medium.cc @@ -702,6 +702,12 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Removed( ::winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromIdAsync( device_update_info.Id()) .get(); + + if (native_bluetooth_device == nullptr) { + NEARBY_LOGS(WARNING) << __func__ << ": cannot get native bluetooth device."; + return winrt::fire_and_forget(); + } + std::string mac_address = uint64_to_mac_address_string(native_bluetooth_device.BluetoothAddress()); auto it = mac_address_to_bluetooth_device_map_.find(mac_address); From eba928e78441e982ccad40a62e357cf68a677a79 Mon Sep 17 00:00:00 2001 From: Aaron Yu Date: Wed, 27 Sep 2023 16:33:23 -0700 Subject: [PATCH 032/683] Fix bluetooth adapter null pointer exception PiperOrigin-RevId: 568994552 --- .../platform/implementation/windows/ble_gatt_server.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/internal/platform/implementation/windows/ble_gatt_server.cc b/internal/platform/implementation/windows/ble_gatt_server.cc index 9dfe45db..6fe40e07 100644 --- a/internal/platform/implementation/windows/ble_gatt_server.cc +++ b/internal/platform/implementation/windows/ble_gatt_server.cc @@ -221,7 +221,12 @@ bool BleGattServer::InitializeGattServer() { NEARBY_LOGS(VERBOSE) << __func__ << ": Create GATT service service_uuid=" << std::string(service_uuid_); - if (adapter_ == nullptr || !adapter_->IsEnabled()) { + if (adapter_ == nullptr) { + NEARBY_LOGS(ERROR) << __func__ << ": Bluetooth adapter is absent."; + return false; + } + + if (!adapter_->IsEnabled()) { NEARBY_LOGS(ERROR) << __func__ << ": Bluetooth adapter is disabled."; return false; } From d477a2d174fc0e31f6dd06264ff3f47ff8da5378 Mon Sep 17 00:00:00 2001 From: hai007 Date: Fri, 29 Sep 2023 12:24:08 -0700 Subject: [PATCH 033/683] Apply GO frequency to NC that queries from Intel PIE SDK PiperOrigin-RevId: 569558266 --- connections/implementation/bwu_manager_test.cc | 3 ++- connections/implementation/fake_bwu_handler.h | 3 ++- connections/implementation/offline_frames.cc | 2 ++ connections/implementation/offline_frames.h | 1 + .../implementation/offline_frames_test.cc | 5 +++-- .../offline_frames_validator_test.cc | 5 +++-- .../implementation/wifi_hotspot_bwu_handler.cc | 5 +++-- .../flags/nearby_platform_feature_flags.h | 4 ++++ .../windows/wifi_hotspot_medium.cc | 17 ++++++++++++++++- .../implementation/windows/wifi_intel.cc | 10 +++++----- internal/platform/wifi_credential.h | 2 ++ 11 files changed, 43 insertions(+), 14 deletions(-) diff --git a/connections/implementation/bwu_manager_test.cc b/connections/implementation/bwu_manager_test.cc index 5a5e2659..8370c2b0 100644 --- a/connections/implementation/bwu_manager_test.cc +++ b/connections/implementation/bwu_manager_test.cc @@ -870,7 +870,8 @@ TEST_F(BwuManagerTest, InitiateBwu_Revert_OnDisconnect_Hotspot) { ExceptionOr hotspot_path_available_frame = parser::FromBytes(parser::ForBwuWifiHotspotPathAvailable( /*ssid=*/"Direct-357a2d8c", /*password=*/"b592f7d3", - /*port=*/1234, /*gateway=*/"123.234.23.1", false)); + /*port=*/1234, /*frequency=*/2412, /*gateway=*/"123.234.23.1", + false)); OfflineFrame frame = hotspot_path_available_frame.result(); frame.set_version(OfflineFrame::V1); auto* v1_frame = frame.mutable_v1(); diff --git a/connections/implementation/fake_bwu_handler.h b/connections/implementation/fake_bwu_handler.h index 78c13719..48a7e15e 100644 --- a/connections/implementation/fake_bwu_handler.h +++ b/connections/implementation/fake_bwu_handler.h @@ -143,7 +143,8 @@ class FakeBwuHandler : public BaseBwuHandler { case location::nearby::proto::connections::WIFI_HOTSPOT: return parser::ForBwuWifiHotspotPathAvailable( /*ssid=*/"Direct-357a2d8c", /*password=*/"b592f7d3", - /*port=*/1234, /*gateway=*/"123.234.23.1", false); + /*port=*/1234, /*frequency=*/2412, /*gateway=*/"123.234.23.1", + false); case location::nearby::proto::connections::WIFI_DIRECT: return parser::ForBwuWifiDirectPathAvailable( /*ssid=*/"Direct-12345678", /*password=*/"87654321", /*port=*/2143, diff --git a/connections/implementation/offline_frames.cc b/connections/implementation/offline_frames.cc index 395d2a99..5f5f86d9 100644 --- a/connections/implementation/offline_frames.cc +++ b/connections/implementation/offline_frames.cc @@ -228,6 +228,7 @@ ByteArray ForControlPayloadTransfer( ByteArray ForBwuWifiHotspotPathAvailable(const std::string& ssid, const std::string& password, std::int32_t port, + std::int32_t frequency, const std::string& gateway, bool supports_disabling_encryption) { OfflineFrame frame; @@ -248,6 +249,7 @@ ByteArray ForBwuWifiHotspotPathAvailable(const std::string& ssid, wifi_hotspot_credentials->set_ssid(ssid); wifi_hotspot_credentials->set_password(password); wifi_hotspot_credentials->set_port(port); + wifi_hotspot_credentials->set_frequency(frequency); wifi_hotspot_credentials->set_gateway(gateway); return ToBytes(std::move(frame)); diff --git a/connections/implementation/offline_frames.h b/connections/implementation/offline_frames.h index fb6214ab..9d1a7d6f 100644 --- a/connections/implementation/offline_frames.h +++ b/connections/implementation/offline_frames.h @@ -74,6 +74,7 @@ ByteArray ForBwuIntroductionAck(); ByteArray ForBwuWifiHotspotPathAvailable(const std::string& ssid, const std::string& password, std::int32_t port, + std::int32_t frequency, const std::string& gateway, bool supports_disabling_encryption); ByteArray ForBwuWifiLanPathAvailable(const std::string& ip_address, diff --git a/connections/implementation/offline_frames_test.cc b/connections/implementation/offline_frames_test.cc index ebd5c813..fea92f95 100644 --- a/connections/implementation/offline_frames_test.cc +++ b/connections/implementation/offline_frames_test.cc @@ -352,14 +352,15 @@ TEST(OfflineFramesTest, CanGenerateBwuWifiHotspotPathAvailable) { password: "password" port: 1234 gateway: "0.0.0.0" + frequency: 2412 > supports_disabling_encryption: false supports_client_introduction_ack: true > > >)pb"; - ByteArray bytes = ForBwuWifiHotspotPathAvailable("ssid", "password", 1234, - "0.0.0.0", false); + ByteArray bytes = ForBwuWifiHotspotPathAvailable( + "ssid", "password", 1234, /*frequency=*/2412, "0.0.0.0", false); auto response = FromBytes(bytes); ASSERT_TRUE(response.ok()); OfflineFrame message = response.result(); diff --git a/connections/implementation/offline_frames_validator_test.cc b/connections/implementation/offline_frames_validator_test.cc index 27fd5036..b76f30ab 100644 --- a/connections/implementation/offline_frames_validator_test.cc +++ b/connections/implementation/offline_frames_validator_test.cc @@ -48,6 +48,7 @@ constexpr absl::string_view kWifiDirectPassword = "WIFIDIRECT123456"; constexpr absl::string_view kGateway = "192.168.1.1"; constexpr int kWifiDirectFrequency = 2412; constexpr int kPort = 1000; +constexpr int kHotspotFrequency = 2412; constexpr bool kSupportsDisablingEncryption = true; constexpr std::array kMediums = { Medium::MDNS, Medium::BLUETOOTH, Medium::WIFI_HOTSPOT, @@ -570,7 +571,7 @@ TEST(OfflineFramesValidatorTest, OfflineFrame offline_frame; ByteArray bytes = ForBwuWifiHotspotPathAvailable( - std::string(kSsid), std::string(kPassword), kPort, + std::string(kSsid), std::string(kPassword), kPort, kHotspotFrequency, std::string(kWifiHotspotGateway), kSupportsDisablingEncryption); offline_frame.ParseFromString(std::string(bytes)); @@ -584,7 +585,7 @@ TEST(OfflineFramesValidatorTest, OfflineFrame offline_frame; ByteArray bytes = ForBwuWifiHotspotPathAvailable( - std::string(kSsid), std::string(kPassword), kPort, + std::string(kSsid), std::string(kPassword), kPort, kHotspotFrequency, std::string(kWifiHotspotGateway), kSupportsDisablingEncryption); offline_frame.ParseFromString(std::string(bytes)); auto* v1_frame = offline_frame.mutable_v1(); diff --git a/connections/implementation/wifi_hotspot_bwu_handler.cc b/connections/implementation/wifi_hotspot_bwu_handler.cc index 9479924d..c81b485f 100644 --- a/connections/implementation/wifi_hotspot_bwu_handler.cc +++ b/connections/implementation/wifi_hotspot_bwu_handler.cc @@ -74,15 +74,16 @@ ByteArray WifiHotspotBwuHandler::HandleInitializeUpgradedMediumForEndpoint( std::string password = hotspot_crendential->GetPassword(); std::string gateway = hotspot_crendential->GetGateway(); std::int32_t port = hotspot_crendential->GetPort(); + std::int32_t frequency = hotspot_crendential->GetFrequency(); NEARBY_LOGS(INFO) << "Start SoftAP with SSID:" << ssid << ", Password:" << password << ", Port:" << port - << ", Gateway:" << gateway; + << ", Gateway:" << gateway << ", Frequency:" << frequency; bool disabling_encryption = (client->GetAdvertisingOptions().strategy == Strategy::kP2pPointToPoint); return parser::ForBwuWifiHotspotPathAvailable( - ssid, password, port, gateway, + ssid, password, port, frequency, gateway, /* supports_disabling_encryption */ disabling_encryption); } diff --git a/internal/platform/flags/nearby_platform_feature_flags.h b/internal/platform/flags/nearby_platform_feature_flags.h index 934574e8..51ef3437 100644 --- a/internal/platform/flags/nearby_platform_feature_flags.h +++ b/internal/platform/flags/nearby_platform_feature_flags.h @@ -65,6 +65,10 @@ constexpr auto kWifiHotspotConnectionIntervalMillis = constexpr auto kWifiHotspotConnectionTimeoutMillis = flags::Flag(kConfigPackage, "45415888", 10000); +// Enable/Disable Intel PIe SDK to query/set WIFI feature. +constexpr auto kEnableIntelPieSdk = + flags::Flag(kConfigPackage, "45428547", false); + } // namespace nearby_platform_feature } // namespace config_package_nearby } // namespace platform diff --git a/internal/platform/implementation/windows/wifi_hotspot_medium.cc b/internal/platform/implementation/windows/wifi_hotspot_medium.cc index 8cdbd06b..a7108a21 100644 --- a/internal/platform/implementation/windows/wifi_hotspot_medium.cc +++ b/internal/platform/implementation/windows/wifi_hotspot_medium.cc @@ -20,16 +20,17 @@ #include #include "absl/strings/string_view.h" -#include "absl/time/time.h" #include "internal/platform/feature_flags.h" #include "internal/platform/flags/nearby_platform_feature_flags.h" #include "internal/platform/implementation/windows/wifi_hotspot.h" +#include "internal/platform/implementation/windows/wifi_intel.h" // Nearby connections headers #include "internal/flags/nearby_flags.h" #include "internal/platform/cancellation_flag_listener.h" #include "internal/platform/implementation/windows/utils.h" #include "internal/platform/logging.h" +#include "internal/platform/wifi_utils.h" namespace nearby { namespace windows { @@ -256,6 +257,20 @@ bool WifiHotspotMedium::StartWifiHotspot( WiFiDirectAdvertisementPublisherStatus::Started) { NEARBY_LOGS(INFO) << __func__ << ": WiFi Hotspot created and started."; medium_status_ |= kMediumStatusBeaconing; + if (NearbyFlags::GetInstance().GetBoolFlag( + platform::config_package_nearby::nearby_platform_feature:: + kEnableIntelPieSdk)) { + WifiIntel& intel_wifi{WifiIntel::GetInstance()}; + intel_wifi.Start(); + int GO_channel = static_cast(intel_wifi.GetGOChannel()); + NEARBY_LOGS(INFO) << "Hotspot is running on channel: " << GO_channel; + intel_wifi.Stop(); + hotspot_credentials_->SetFrequency( + WifiUtils::ConvertChannelToFrequencyMhz(GO_channel, + WifiBandType::kUnknown)); + } else { + hotspot_credentials_->SetFrequency(-1); + } return true; } diff --git a/internal/platform/implementation/windows/wifi_intel.cc b/internal/platform/implementation/windows/wifi_intel.cc index 844852da..688b09fb 100644 --- a/internal/platform/implementation/windows/wifi_intel.cc +++ b/internal/platform/implementation/windows/wifi_intel.cc @@ -428,7 +428,7 @@ HINSTANCE WifiIntel::PIEDllLoader() { // load the library and get the handle murocApiDllHandle = LoadLibraryW(pDllPathValue); // NOLINT - NEARBY_LOGS(INFO) << absl::StrFormat("Muroc Api Dll Handle is 0x%p ", + NEARBY_LOGS(VERBOSE) << absl::StrFormat("Muroc Api Dll Handle is 0x%p ", murocApiDllHandle); } else { NEARBY_LOGS(INFO) << "GetFullDllLoadPathFromPieRegistry fails eith error: " @@ -458,7 +458,7 @@ HADAPTER WifiGetAdapterList(HINSTANCE murocApiDllHandle, return INVALID_HADAPTER; } - NEARBY_LOGS(INFO) << "GetProcAddress for WifiGetAdapterListFunction API " + NEARBY_LOGS(VERBOSE) << "GetProcAddress for WifiGetAdapterListFunction API " "completed successfully"; INTEL_WIFI_HEADER intelHeader = {INTEL_STRUCT_VERSION_V156, // NOLINT sizeof(MurocDefs::INTEL_ADAPTER_LIST_V120)}; @@ -475,7 +475,7 @@ HADAPTER WifiGetAdapterList(HINSTANCE murocApiDllHandle, } firstAdapterOnTheList = (*ppAllAdapters)->adapter[0].hAdapter; - NEARBY_LOGS(INFO) << "Return WIFI Adapter: " << firstAdapterOnTheList; + NEARBY_LOGS(INFO) << "WIFI Adapter on the list: " << firstAdapterOnTheList; return firstAdapterOnTheList; } @@ -532,7 +532,7 @@ void DeregisterIntelCallback(HINSTANCE murocApiDllHandle, murocApiRetVal = deregisterIntelCBFunc(fnCallback); if (murocApiRetVal == IWLAN_E_SUCCESS) { - NEARBY_LOGS(INFO) << "Calling DeregisterIntelCallback API succeeded."; + NEARBY_LOGS(VERBOSE) << "Calling DeregisterIntelCallback API succeeded."; } else { NEARBY_LOGS(INFO) << "Calling DeregisterIntelCallback API fails with error:" @@ -566,7 +566,7 @@ void FreeMemoryList(HINSTANCE murocApiDllHandle, void* ptr) { murocApiRetVal = freeMemoryListFunction(ptr); if (murocApiRetVal == IWLAN_E_SUCCESS) { - NEARBY_LOGS(INFO) << "Calling FreeListMemory API succeeded."; + NEARBY_LOGS(VERBOSE) << "Calling FreeListMemory API succeeded."; } else { NEARBY_LOGS(INFO) << "Calling FreeListMemory API failed with error: " << murocApiRetVal; diff --git a/internal/platform/wifi_credential.h b/internal/platform/wifi_credential.h index e715235a..f1690b1d 100644 --- a/internal/platform/wifi_credential.h +++ b/internal/platform/wifi_credential.h @@ -59,6 +59,8 @@ class HotspotCredentials { // Gets the Frequency int GetFrequency() const { return frequency_; } + // Set frequency_ + void SetFrequency(int frequency) { frequency_ = frequency; } // Gets the Band location::nearby::proto::connections::ConnectionBand GetBand() const { From 3fdcbe4ddc69ce73907305b1ae18f76e438b4180 Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Mon, 2 Oct 2023 11:19:58 -0700 Subject: [PATCH 034/683] Added write timeout for Wi-Fi LAN socket PiperOrigin-RevId: 570122181 --- .../implementation/windows/wifi_lan_socket.cc | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/internal/platform/implementation/windows/wifi_lan_socket.cc b/internal/platform/implementation/windows/wifi_lan_socket.cc index 20c71471..7ab1c4b8 100644 --- a/internal/platform/implementation/windows/wifi_lan_socket.cc +++ b/internal/platform/implementation/windows/wifi_lan_socket.cc @@ -1,4 +1,4 @@ -// Copyright 2021 Google LLC +// Copyright 2021-2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,15 +12,28 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include + +#include // NOLINT(build/c++11) #include #include #include +#include "internal/platform/byte_array.h" +#include "internal/platform/exception.h" +#include "internal/platform/implementation/windows/generated/winrt/Windows.Foundation.h" #include "internal/platform/implementation/windows/wifi_lan.h" +#include "internal/platform/input_stream.h" #include "internal/platform/logging.h" +#include "internal/platform/output_stream.h" namespace nearby { namespace windows { +namespace { +using ::winrt::Windows::Foundation::TimeSpan; + +constexpr int kWriteTimeoutInSeconds = 10; +} // namespace WifiLanSocket::WifiLanSocket(StreamSocket socket) { stream_soket_ = socket; @@ -148,7 +161,26 @@ Exception WifiLanSocket::SocketOutputStream::Write(const ByteArray& data) { Buffer buffer = Buffer(data.size()); std::memcpy(buffer.data(), data.data(), data.size()); buffer.Length(data.size()); - uint32_t wrote_bytes = output_stream_.WriteAsync(buffer).get(); + uint32_t wrote_bytes = 0; + auto write_async = output_stream_.WriteAsync(buffer); + + switch (write_async.wait_for( + TimeSpan(std::chrono::seconds(kWriteTimeoutInSeconds)))) { + case winrt::Windows::Foundation::AsyncStatus::Completed: + wrote_bytes = write_async.GetResults(); + break; + case winrt::Windows::Foundation::AsyncStatus::Started: + NEARBY_LOGS(ERROR) << __func__ + << ": Failed to write socket data due to timeout."; + write_async.Cancel(); + return {Exception::kIo}; + default: + NEARBY_LOGS(ERROR) + << __func__ + << ": Failed to write socket data due to unknown reasons."; + return {Exception::kIo}; + } + if (wrote_bytes != data.size()) { NEARBY_LOGS(WARNING) << "Only wrote partial of data:[" << wrote_bytes << "/" << data.size() << "]."; From 7dea977b74ef5c14e9113b210f28f07ad40ec845 Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Tue, 3 Oct 2023 13:11:32 -0700 Subject: [PATCH 035/683] Try to fix Bluetooth issue to get service PiperOrigin-RevId: 570475245 --- .../platform/implementation/windows/ble_v2.cc | 1 + .../windows/bluetooth_classic_device.cc | 124 ++++++++++-------- .../bluetooth_classic_server_socket.cc | 10 +- .../windows/bluetooth_classic_server_socket.h | 40 ++---- .../windows/bluetooth_classic_socket.cc | 74 ++++++----- .../windows/bluetooth_classic_socket.h | 99 ++++++-------- 6 files changed, 166 insertions(+), 182 deletions(-) diff --git a/internal/platform/implementation/windows/ble_v2.cc b/internal/platform/implementation/windows/ble_v2.cc index eb607be1..c92c5365 100644 --- a/internal/platform/implementation/windows/ble_v2.cc +++ b/internal/platform/implementation/windows/ble_v2.cc @@ -89,6 +89,7 @@ using ::winrt::Windows::Devices::Bluetooth::Advertisement:: BluetoothLEScanningMode; using ::winrt::Windows::Foundation::TimeSpan; using ::winrt::Windows::Storage::Streams::Buffer; +using ::winrt::Windows::Storage::Streams::DataReader; using ::winrt::Windows::Storage::Streams::DataWriter; template diff --git a/internal/platform/implementation/windows/bluetooth_classic_device.cc b/internal/platform/implementation/windows/bluetooth_classic_device.cc index 699aa1fa..390a1d30 100644 --- a/internal/platform/implementation/windows/bluetooth_classic_device.cc +++ b/internal/platform/implementation/windows/bluetooth_classic_device.cc @@ -16,12 +16,15 @@ #include +#include // NOLINT(build/c++11) #include #include #include #include #include "absl/strings/string_view.h" +#include "absl/time/clock.h" +#include "absl/time/time.h" #include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.Bluetooth.Rfcomm.h" #include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.Bluetooth.h" #include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.Enumeration.h" @@ -34,9 +37,11 @@ namespace nearby { namespace windows { namespace { -constexpr int kBluetoothTimeoutInSeconds = 10; - using ::winrt::Windows::Foundation::TimeSpan; + +constexpr int kBluetoothTimeoutInSeconds = 10; +constexpr int kCheckBluetoothServiceMaxTimes = 3; +constexpr absl::Duration kCheckBluetoothServiceInterval = absl::Seconds(1); } // namespace BluetoothDevice::~BluetoothDevice() {} @@ -72,67 +77,74 @@ std::string BluetoothDevice::GetMacAddress() const { return mac_address_; } // Checks cache first, will check uncached if no result. RfcommDeviceService BluetoothDevice::GetRfcommServiceForIdAsync( const RfcommServiceId serviceId) { - try { - NEARBY_LOGS(INFO) << __func__ << ": Get RF services for service id:" - << winrt::to_string(serviceId.AsString()); + int check_service_count = 0; + while (check_service_count < kCheckBluetoothServiceMaxTimes) { + try { + NEARBY_LOGS(INFO) << __func__ << ": Get RF services for service id:" + << winrt::to_string(serviceId.AsString()); - RfcommDeviceServicesResult rfcomm_device_services = nullptr; - // Try to get service from un cached mode. - auto rfcomm_device_services_async = - windows_bluetooth_device_.GetRfcommServicesForIdAsync( - serviceId, BluetoothCacheMode::Uncached); + RfcommDeviceServicesResult rfcomm_device_services = nullptr; + // Try to get service from un cached mode. + auto rfcomm_device_services_async = + windows_bluetooth_device_.GetRfcommServicesForIdAsync( + serviceId, BluetoothCacheMode::Uncached); - switch (rfcomm_device_services_async.wait_for( - TimeSpan(std::chrono::seconds(kBluetoothTimeoutInSeconds)))) { - case winrt::Windows::Foundation::AsyncStatus::Completed: - rfcomm_device_services = rfcomm_device_services_async.GetResults(); - break; - case winrt::Windows::Foundation::AsyncStatus::Started: - NEARBY_LOGS(ERROR) - << __func__ - << ": Failed to get RfcommDeviceService due to timeout."; - rfcomm_device_services_async.Cancel(); - return nullptr; - default: - NEARBY_LOGS(ERROR) - << __func__ - << ": Failed to get RfcommDeviceService due to unknown reasons."; - return nullptr; - } + switch (rfcomm_device_services_async.wait_for( + TimeSpan(std::chrono::seconds(kBluetoothTimeoutInSeconds)))) { + case winrt::Windows::Foundation::AsyncStatus::Completed: + rfcomm_device_services = rfcomm_device_services_async.GetResults(); + break; + case winrt::Windows::Foundation::AsyncStatus::Started: + NEARBY_LOGS(ERROR) + << __func__ + << ": Failed to get RfcommDeviceService due to timeout."; + rfcomm_device_services_async.Cancel(); + return nullptr; + default: + NEARBY_LOGS(ERROR) + << __func__ + << ": Failed to get RfcommDeviceService due to unknown reasons."; + return nullptr; + } - if (rfcomm_device_services != nullptr && - rfcomm_device_services.Services().Size() > 0) { - NEARBY_LOGS(INFO) << __func__ << ": Get " - << rfcomm_device_services.Services().Size() - << " services without cache."; - // found the matched service. - for (auto rfcomm_device_service : rfcomm_device_services.Services()) { - if (rfcomm_device_service.Device() != nullptr && - winrt::to_string(rfcomm_device_service.Device().DeviceId()) == - id_) { - NEARBY_LOGS(INFO) - << __func__ << ": Found service from no-cache mode."; - return rfcomm_device_service; + if (rfcomm_device_services != nullptr && + rfcomm_device_services.Services().Size() > 0) { + NEARBY_LOGS(INFO) << __func__ << ": Get " + << rfcomm_device_services.Services().Size() + << " services without cache."; + // found the matched service. + for (auto rfcomm_device_service : rfcomm_device_services.Services()) { + if (rfcomm_device_service.Device() != nullptr && + winrt::to_string(rfcomm_device_service.Device().DeviceId()) == + id_) { + NEARBY_LOGS(INFO) + << __func__ << ": Found service from no-cache mode."; + return rfcomm_device_service; + } } } - } - NEARBY_LOGS(ERROR) - << __func__ - << ": Failed to get RfcommDeviceService due to no any services."; - return nullptr; - } catch (std::exception exception) { - NEARBY_LOGS(ERROR) << __func__ << ": Failed to get RfcommDeviceService: " - << exception.what(); - return nullptr; - } catch (const winrt::hresult_error& ex) { - NEARBY_LOGS(ERROR) << __func__ << ": RfcommDeviceService: " << ex.code() - << ", error message: " << winrt::to_string(ex.message()); - return nullptr; - } catch (...) { - NEARBY_LOGS(ERROR) << __func__ << ": Unknown exception."; - return nullptr; + ++check_service_count; + absl::SleepFor(kCheckBluetoothServiceInterval); + NEARBY_LOGS(ERROR) << __func__ << ": No any services at " + << check_service_count << "th check."; + } catch (std::exception exception) { + NEARBY_LOGS(ERROR) << __func__ << ": Failed to get RfcommDeviceService: " + << exception.what(); + return nullptr; + } catch (const winrt::hresult_error& ex) { + NEARBY_LOGS(ERROR) << __func__ << ": RfcommDeviceService: " << ex.code() + << ", error message: " + << winrt::to_string(ex.message()); + return nullptr; + } catch (...) { + NEARBY_LOGS(ERROR) << __func__ << ": Unknown exception."; + return nullptr; + } } + + NEARBY_LOGS(ERROR) << __func__ << ": Failed to get RfcommDeviceService."; + return nullptr; } } // namespace windows diff --git a/internal/platform/implementation/windows/bluetooth_classic_server_socket.cc b/internal/platform/implementation/windows/bluetooth_classic_server_socket.cc index 4d82cc4d..12ab598e 100644 --- a/internal/platform/implementation/windows/bluetooth_classic_server_socket.cc +++ b/internal/platform/implementation/windows/bluetooth_classic_server_socket.cc @@ -1,4 +1,4 @@ -// Copyright 2020 Google LLC +// Copyright 2020-2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -26,6 +26,14 @@ namespace nearby { namespace windows { +namespace { +using ::winrt::Windows::Networking::Sockets::StreamSocket; +using ::winrt::Windows::Networking::Sockets::SocketProtectionLevel; +using ::winrt::Windows::Networking::Sockets::SocketQualityOfService; +using ::winrt::Windows::Networking::Sockets::StreamSocketListener; +using ::winrt::Windows::Networking::Sockets:: + StreamSocketListenerConnectionReceivedEventArgs; +} // namespace BluetoothServerSocket::BluetoothServerSocket(absl::string_view service_name) : service_name_(service_name) {} diff --git a/internal/platform/implementation/windows/bluetooth_classic_server_socket.h b/internal/platform/implementation/windows/bluetooth_classic_server_socket.h index ea34de39..2e3f2baf 100644 --- a/internal/platform/implementation/windows/bluetooth_classic_server_socket.h +++ b/internal/platform/implementation/windows/bluetooth_classic_server_socket.h @@ -1,4 +1,4 @@ -// Copyright 2020 Google LLC +// Copyright 2020-2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" +#include "internal/platform/exception.h" #include "internal/platform/implementation/bluetooth_classic.h" #include "internal/platform/implementation/windows/bluetooth_classic_socket.h" #include "internal/platform/implementation/windows/generated/winrt/base.h" @@ -30,28 +31,9 @@ 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; - -// 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; - -// 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(absl::string_view service_name); + explicit BluetoothServerSocket(absl::string_view service_name); ~BluetoothServerSocket() override; @@ -77,24 +59,28 @@ class BluetoothServerSocket : public api::BluetoothServerSocket { bool listen(); - const StreamSocketListener& stream_socket_listener() const { + const ::winrt::Windows::Networking::Sockets::StreamSocketListener& + stream_socket_listener() const { return stream_socket_listener_; } private: // The listener is accepting incoming connections ::winrt::fire_and_forget Listener_ConnectionReceived( - StreamSocketListener listener, - StreamSocketListenerConnectionReceivedEventArgs const& args); + ::winrt::Windows::Networking::Sockets::StreamSocketListener listener, + ::winrt::Windows::Networking::Sockets:: + StreamSocketListenerConnectionReceivedEventArgs const& args); // Retrieves IP addresses from local machine std::vector GetIpAddresses() const; mutable absl::Mutex mutex_; absl::CondVar cond_; - std::deque pending_sockets_ ABSL_GUARDED_BY(mutex_); - StreamSocketListener stream_socket_listener_{nullptr}; - winrt::event_token listener_event_token_{}; + std::deque<::winrt::Windows::Networking::Sockets::StreamSocket> + pending_sockets_ ABSL_GUARDED_BY(mutex_); + ::winrt::Windows::Networking::Sockets::StreamSocketListener + stream_socket_listener_{nullptr}; + ::winrt::event_token listener_event_token_{}; // Close notifier absl::AnyInvocable close_notifier_ = nullptr; diff --git a/internal/platform/implementation/windows/bluetooth_classic_socket.cc b/internal/platform/implementation/windows/bluetooth_classic_socket.cc index 5eedb94b..215719a0 100644 --- a/internal/platform/implementation/windows/bluetooth_classic_socket.cc +++ b/internal/platform/implementation/windows/bluetooth_classic_socket.cc @@ -1,4 +1,4 @@ -// Copyright 2020 Google LLC +// Copyright 2020-2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,32 +14,41 @@ #include "internal/platform/implementation/windows/bluetooth_classic_socket.h" +#include #include #include #include #include -#include "absl/time/clock.h" -#include "absl/time/time.h" +#include "internal/platform/byte_array.h" +#include "internal/platform/exception.h" #include "internal/platform/feature_flags.h" +#include "internal/platform/implementation/bluetooth_classic.h" +#include "internal/platform/implementation/windows/bluetooth_classic_device.h" +#include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.Bluetooth.h" +#include "internal/platform/implementation/windows/generated/winrt/Windows.Networking.Sockets.h" +#include "internal/platform/implementation/windows/generated/winrt/base.h" +#include "internal/platform/input_stream.h" #include "internal/platform/logging.h" -#include "winrt/Windows.Devices.Bluetooth.h" -#include "winrt/Windows.Networking.Sockets.h" -#include "winrt/base.h" +#include "internal/platform/output_stream.h" namespace nearby { namespace windows { namespace { using ::winrt::Windows::Devices::Bluetooth::BluetoothConnectionStatus; -constexpr int kMaxConnectRetryCount = 3; -constexpr absl::Duration kConnectInterval = absl::Seconds(3); +using ::winrt::Windows::Networking::HostName; +using ::winrt::Windows::Networking::Sockets::StreamSocket; +using ::winrt::Windows::Storage::Streams::Buffer; +using ::winrt::Windows::Storage::Streams::IInputStream; +using ::winrt::Windows::Storage::Streams::InputStreamOptions; +using ::winrt::Windows::Storage::Streams::IOutputStream; } // namespace -BluetoothSocket::BluetoothSocket(StreamSocket streamSocket) - : windows_socket_(streamSocket) { +BluetoothSocket::BluetoothSocket(StreamSocket stream_socket) + : windows_socket_(stream_socket) { NEARBY_LOGS(INFO) << __func__ << ": Initialize bluetooth socket."; native_bluetooth_device_ = - winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromHostNameAsync( + ::winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromHostNameAsync( windows_socket_.Information().RemoteHostName()) .get(); if (FeatureFlags::GetInstance() @@ -125,26 +134,18 @@ api::BluetoothDevice* BluetoothSocket::GetRemoteDevice() { // 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. -bool BluetoothSocket::Connect(HostName connectionHostName, - winrt::hstring connectionServiceName) { +bool BluetoothSocket::Connect(HostName connection_host_name, + ::winrt::hstring connection_service_name) { NEARBY_LOGS(INFO) << __func__ << ": start to connect to bluetooth service:" - << winrt::to_string(connectionServiceName); + << winrt::to_string(connection_service_name); - connect_called_count_ = 0; - while (connect_called_count_ < kMaxConnectRetryCount) { - connect_called_count_ += 1; - bool connect_result = - InternalConnect(connectionHostName, connectionServiceName); - if (connect_result) { - return connect_result; - } - - NEARBY_LOGS(WARNING) << __func__ << ": Failed to connect bluetooth at the " - << connect_called_count_ << "th call."; - - absl::SleepFor(kConnectInterval); + bool connect_result = + InternalConnect(connection_host_name, connection_service_name); + if (connect_result) { + return connect_result; } + NEARBY_LOGS(WARNING) << __func__ << ": Failed to connect bluetooth"; return false; } @@ -164,7 +165,8 @@ ExceptionOr BluetoothSocket::BluetoothInputStream::Read( if (size > read_buffer_.Capacity()) { NEARBY_LOGS(WARNING) << __func__ - << ": resize receive buffer to packet size: " << size; + << ": resize receive buffer to packet size: " + << size; read_buffer_ = Buffer(size); } @@ -225,8 +227,8 @@ Exception BluetoothSocket::BluetoothOutputStream::Write(const ByteArray& data) { try { if (data.size() > write_buffer_.Capacity()) { NEARBY_LOGS(WARNING) << __func__ - << ": resize write buffer to packet size: " - << data.size(); + << ": resize write buffer to packet size: " + << data.size(); write_buffer_ = Buffer(data.size()); } @@ -290,10 +292,10 @@ Exception BluetoothSocket::BluetoothOutputStream::Close() { } } -bool BluetoothSocket::InternalConnect(HostName connectionHostName, - winrt::hstring connectionServiceName) { +bool BluetoothSocket::InternalConnect(HostName connection_host_name, + winrt::hstring connection_service_name) { try { - if (connectionHostName == nullptr || connectionServiceName.empty()) { + if (connection_host_name == nullptr || connection_service_name.empty()) { NEARBY_LOGS(ERROR) << __func__ << ": Bluetooth socket connection failed. Attempting to " @@ -303,14 +305,14 @@ bool BluetoothSocket::InternalConnect(HostName connectionHostName, NEARBY_LOGS(INFO) << __func__ << ": Bluetooth socket connection to host name:" - << winrt::to_string(connectionHostName.DisplayName()) + << winrt::to_string(connection_host_name.DisplayName()) << ", service name:" - << winrt::to_string(connectionServiceName); + << winrt::to_string(connection_service_name); 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) + windows_socket_.ConnectAsync(connection_host_name, connection_service_name) .get(); auto info = windows_socket_.Information(); diff --git a/internal/platform/implementation/windows/bluetooth_classic_socket.h b/internal/platform/implementation/windows/bluetooth_classic_socket.h index 19e2de3b..026d162f 100644 --- a/internal/platform/implementation/windows/bluetooth_classic_socket.h +++ b/internal/platform/implementation/windows/bluetooth_classic_socket.h @@ -1,4 +1,4 @@ -// Copyright 2020 Google LLC +// Copyright 2020-2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,60 +15,29 @@ #ifndef PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_SOCKET_H_ #define PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_SOCKET_H_ +#include + +#include #include +#include "internal/platform/byte_array.h" +#include "internal/platform/exception.h" #include "internal/platform/implementation/bluetooth_classic.h" #include "internal/platform/implementation/windows/bluetooth_classic_device.h" -#include "winrt/Windows.Foundation.h" -#include "winrt/Windows.Networking.Sockets.h" -#include "winrt/Windows.Storage.Streams.h" +#include "internal/platform/implementation/windows/generated/winrt/Windows.Foundation.h" +#include "internal/platform/implementation/windows/generated/winrt/Windows.Networking.Sockets.h" +#include "internal/platform/implementation/windows/generated/winrt/Windows.Storage.Streams.h" +#include "internal/platform/input_stream.h" +#include "internal/platform/output_stream.h" 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(); - - explicit BluetoothSocket(StreamSocket streamSocket); - + explicit BluetoothSocket( + ::winrt::Windows::Networking::Sockets::StreamSocket stream_socket); ~BluetoothSocket() override; // NOTE: @@ -95,28 +64,32 @@ class BluetoothSocket : public api::BluetoothSocket { // Connect asynchronously to the target remote device // Returns true if successful, false otherwise - bool Connect(HostName connectionHostName, - winrt::hstring connectionServiceName); + bool Connect(::winrt::Windows::Networking::HostName connection_host_name, + ::winrt::hstring connection_service_name); private: static constexpr int kInitialTransmitPacketSize = 4096; class BluetoothInputStream : public InputStream { public: - explicit BluetoothInputStream(IInputStream stream); + explicit BluetoothInputStream( + ::winrt::Windows::Storage::Streams::IInputStream stream); ~BluetoothInputStream() override = default; ExceptionOr Read(std::int64_t size) override; Exception Close() override; private: - IInputStream winrt_input_stream_{nullptr}; - Buffer read_buffer_{kInitialTransmitPacketSize}; + ::winrt::Windows::Storage::Streams::IInputStream winrt_input_stream_{ + nullptr}; + ::winrt::Windows::Storage::Streams::Buffer read_buffer_{ + kInitialTransmitPacketSize}; }; class BluetoothOutputStream : public OutputStream { public: - explicit BluetoothOutputStream(IOutputStream stream); + explicit BluetoothOutputStream( + ::winrt::Windows::Storage::Streams::IOutputStream stream); ~BluetoothOutputStream() override = default; Exception Write(const ByteArray& data) override; @@ -125,26 +98,28 @@ class BluetoothSocket : public api::BluetoothSocket { Exception Close() override; private: - IOutputStream winrt_output_stream_{nullptr}; - Buffer write_buffer_{kInitialTransmitPacketSize}; + ::winrt::Windows::Storage::Streams::IOutputStream winrt_output_stream_{ + nullptr}; + ::winrt::Windows::Storage::Streams::Buffer write_buffer_{ + kInitialTransmitPacketSize}; }; - bool InternalConnect(HostName connectionHostName, - winrt::hstring connectionServiceName); + bool InternalConnect( + ::winrt::Windows::Networking::HostName connection_host_name, + ::winrt::hstring connection_service_name); - winrt::fire_and_forget Listener_ConnectionStatusChanged( - winrt::Windows::Devices::Bluetooth::BluetoothDevice device, - winrt::Windows::Foundation::IInspectable const& args); + ::winrt::fire_and_forget Listener_ConnectionStatusChanged( + ::winrt::Windows::Devices::Bluetooth::BluetoothDevice device, + ::winrt::Windows::Foundation::IInspectable const& args); - StreamSocket windows_socket_{nullptr}; + ::winrt::Windows::Networking::Sockets::StreamSocket windows_socket_{nullptr}; bool is_bluetooth_socket_closed_ = false; BluetoothInputStream input_stream_{nullptr}; BluetoothOutputStream output_stream_{nullptr}; std::unique_ptr bluetooth_device_ = nullptr; - winrt::Windows::Devices::Bluetooth::BluetoothDevice native_bluetooth_device_{ - nullptr}; - winrt::event_token connection_status_changed_token_{}; - int connect_called_count_ = 0; + ::winrt::Windows::Devices::Bluetooth::BluetoothDevice + native_bluetooth_device_{nullptr}; + ::winrt::event_token connection_status_changed_token_{}; }; } // namespace windows From 7596c298f776380e9750c044dc0287e1ca6775b6 Mon Sep 17 00:00:00 2001 From: hai007 Date: Wed, 4 Oct 2023 03:51:07 -0700 Subject: [PATCH 036/683] [SubsequentPair] Add is_pair_triggered_by_settings in Fast Pair log to track subsequent pairing triggered from Pixel Settings. LOG_STORAGE_INCREASE(GB/week): <1 1 perday * 7 days * (2+1 [tag+length] + 2+1 [tag+bool]) bytes/record Single record size (average): 6 bytes Design doc: go/subsequent-pairing-settings-integration PiperOrigin-RevId: 570646781 --- internal/proto/analytics/fast_pair_log.proto | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/proto/analytics/fast_pair_log.proto b/internal/proto/analytics/fast_pair_log.proto index 81989e0f..cfea1892 100644 --- a/internal/proto/analytics/fast_pair_log.proto +++ b/internal/proto/analytics/fast_pair_log.proto @@ -167,4 +167,6 @@ message FastPairLog { // SASS connection state for the device. Not set for non-SASS devices. optional int32 sass_connection_state = 22; + + optional bool is_pair_triggered_by_settings = 23; } From 264aa3829fce5c48199f06095c19df898dda42b4 Mon Sep 17 00:00:00 2001 From: Qin Wang Date: Wed, 4 Oct 2023 11:16:50 -0700 Subject: [PATCH 037/683] Disable flaky test//third_party/nearby/fastpair/scanning:scanner_broker_impl_test PiperOrigin-RevId: 570749393 --- fastpair/scanning/scanner_broker_impl_test.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fastpair/scanning/scanner_broker_impl_test.cc b/fastpair/scanning/scanner_broker_impl_test.cc index 6e00d9a4..aed8f916 100644 --- a/fastpair/scanning/scanner_broker_impl_test.cc +++ b/fastpair/scanning/scanner_broker_impl_test.cc @@ -21,6 +21,7 @@ #include "gtest/gtest.h" #include "absl/strings/escaping.h" #include "absl/strings/string_view.h" +#include "fastpair/common/account_key.h" #include "fastpair/common/fast_pair_device.h" #include "fastpair/common/protocol.h" #include "fastpair/internal/mediums/mediums.h" @@ -145,7 +146,7 @@ TEST_F(ScannerBrokerImplTest, FoundDiscoverableAdvertisement) { scanning_session.reset(); } -TEST_F(ScannerBrokerImplTest, FoundNonDiscoverableAdvertisement) { +TEST_F(ScannerBrokerImplTest, DISABLED_FoundNonDiscoverableAdvertisement) { SingleThreadExecutor executor; FastPairDeviceRepository devices{&executor}; From dfd3de80cfda101db8c1f5f76e2642f74d57e1e8 Mon Sep 17 00:00:00 2001 From: hai007 Date: Wed, 4 Oct 2023 13:50:21 -0700 Subject: [PATCH 038/683] Set a separate shorter timeout (10s) for REMOTE_DISCONNECTION PiperOrigin-RevId: 570795839 --- connections/implementation/client_proxy.cc | 3 +++ .../implementation/endpoint_channel_manager.cc | 11 +++++------ .../implementation/endpoint_channel_manager.h | 7 +++++-- connections/implementation/endpoint_manager.cc | 17 +++++++++++++++-- internal/platform/feature_flags.h | 2 ++ 5 files changed, 30 insertions(+), 10 deletions(-) diff --git a/connections/implementation/client_proxy.cc b/connections/implementation/client_proxy.cc index 06768e72..441d774d 100644 --- a/connections/implementation/client_proxy.cc +++ b/connections/implementation/client_proxy.cc @@ -76,6 +76,9 @@ ClientProxy::ClientProxy(::nearby::analytics::EventLogger* event_logger) local_safe_to_disconnect_version_ = NearbyFlags::GetInstance().GetInt64Flag( config_package_nearby::nearby_connections_feature:: kSafeToDisconnectVersion); + NEARBY_LOGS(INFO) << "[safe-to-disconnect]: Local enabled: " + << supports_safe_to_disconnect_ + << "; Version_: " << local_safe_to_disconnect_version_; } ClientProxy::~ClientProxy() { Reset(); } diff --git a/connections/implementation/endpoint_channel_manager.cc b/connections/implementation/endpoint_channel_manager.cc index cc3b5282..17970452 100644 --- a/connections/implementation/endpoint_channel_manager.cc +++ b/connections/implementation/endpoint_channel_manager.cc @@ -135,8 +135,9 @@ void EndpointChannelManager::MarkEndpointStopWaitToDisconnect( } bool EndpointChannelManager::CreateNewTimeoutDisconnectedState( - const std::string& endpoint_id) { - return channel_state_.CreateNewTimeoutDisconnectedState(endpoint_id); + const std::string& endpoint_id, absl::Duration timeout_millis) { + return channel_state_.CreateNewTimeoutDisconnectedState(endpoint_id, + timeout_millis); } bool EndpointChannelManager::IsSafeToDisconnect( @@ -281,7 +282,7 @@ void EndpointChannelManager::ChannelState::MarkEndpointStopWaitToDisconnect( } bool EndpointChannelManager::ChannelState::CreateNewTimeoutDisconnectedState( - const std::string& endpoint_id) { + const std::string& endpoint_id, absl::Duration timeout_millis) { auto item = endpoints_.find(endpoint_id); if (item == endpoints_.end()) return false; NEARBY_LOGS(INFO) << "[safe-to-disconnect] " @@ -291,9 +292,7 @@ bool EndpointChannelManager::ChannelState::CreateNewTimeoutDisconnectedState( MutexLock lock(&item->second.timeout_to_disconnected_mutex); item->second.timeout_to_disconnected_enabled = true; item->second.timeout_to_disconnected_notified = false; - item->second.timeout_to_disconnected.Wait(FeatureFlags::GetInstance() - .GetFlags() - .safe_to_disconnect_ack_delay_millis); + item->second.timeout_to_disconnected.Wait(timeout_millis); NEARBY_LOGS(INFO) << "[safe-to-disconnect] Wait is done with " << (item->second.timeout_to_disconnected_notified ? "notification" diff --git a/connections/implementation/endpoint_channel_manager.h b/connections/implementation/endpoint_channel_manager.h index 16980164..2f7348aa 100644 --- a/connections/implementation/endpoint_channel_manager.h +++ b/connections/implementation/endpoint_channel_manager.h @@ -22,6 +22,7 @@ #include "securegcm/d2d_connection_context_v1.h" #include "absl/base/thread_annotations.h" #include "absl/container/flat_hash_map.h" +#include "absl/time/time.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/endpoint_channel.h" #include "internal/platform/feature_flags.h" @@ -114,7 +115,8 @@ class EndpointChannelManager final { bool is_safe_to_disconnect, bool notify_stop_waiting) ABSL_LOCKS_EXCLUDED(mutex_); - bool CreateNewTimeoutDisconnectedState(const std::string& endpoint_id) + bool CreateNewTimeoutDisconnectedState(const std::string& endpoint_id, + absl::Duration timeout_millis) ABSL_LOCKS_EXCLUDED(mutex_); bool IsSafeToDisconnect(const std::string& endpoint_id) ABSL_LOCKS_EXCLUDED(mutex_); @@ -193,7 +195,8 @@ class EndpointChannelManager final { void MarkEndpointStopWaitToDisconnect(const std::string& endpoint_id, bool is_safe_to_disconnect, bool notify_stop_waiting); - bool CreateNewTimeoutDisconnectedState(const std::string& endpoint_id); + bool CreateNewTimeoutDisconnectedState(const std::string& endpoint_id, + absl::Duration timeout_millis); bool IsSafeToDisconnect(const std::string& endpoint_id); void RemoveTimeoutDisconnectedState(const std::string& endpoint_id); diff --git a/connections/implementation/endpoint_manager.cc b/connections/implementation/endpoint_manager.cc index 1cccfc41..0e61b8c1 100644 --- a/connections/implementation/endpoint_manager.cc +++ b/connections/implementation/endpoint_manager.cc @@ -32,6 +32,7 @@ #include "connections/implementation/service_id_constants.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/exception.h" +#include "internal/platform/feature_flags.h" #include "internal/platform/logging.h" #include "internal/platform/mutex.h" #include "internal/platform/mutex_lock.h" @@ -782,6 +783,10 @@ bool EndpointManager::ApplySafeToDisconnect(const std::string& endpoint_id, << reason; bool is_safe_disconnection = false; bool send_disconnection_frame = true; + absl::Duration timeout_millis = FeatureFlags::GetInstance() + .GetFlags() + .safe_to_disconnect_ack_delay_millis; + bool is_wait_for_ack = true; switch (reason) { case DisconnectionReason::UPGRADED: case DisconnectionReason::SHUTDOWN: @@ -796,6 +801,11 @@ bool EndpointManager::ApplySafeToDisconnect(const std::string& endpoint_id, case DisconnectionReason::REMOTE_DISCONNECTION: is_safe_disconnection = true; send_disconnection_frame = false; + timeout_millis = + FeatureFlags::GetInstance() + .GetFlags() + .safe_to_disconnect_remote_disc_delay_millis; + is_wait_for_ack = false; break; default: is_safe_disconnection = false; @@ -820,8 +830,11 @@ bool EndpointManager::ApplySafeToDisconnect(const std::string& endpoint_id, } } - bool state = - channel_manager_->CreateNewTimeoutDisconnectedState(endpoint_id); + NEARBY_LOGS(WARNING) << "[safe-to-disconnect] Wait for " + << (is_wait_for_ack ? "ack" : "disconnection") + << ", timeout in " << timeout_millis; + bool state = channel_manager_->CreateNewTimeoutDisconnectedState( + endpoint_id, timeout_millis); if (!state) return is_safe_disconnection; return is_safe_disconnection || diff --git a/internal/platform/feature_flags.h b/internal/platform/feature_flags.h index d4202188..736c8015 100644 --- a/internal/platform/feature_flags.h +++ b/internal/platform/feature_flags.h @@ -71,6 +71,8 @@ class FeatureFlags { // initiator will end the connection in 30s. absl::Duration safe_to_disconnect_ack_delay_millis = absl::Milliseconds(30000); + absl::Duration safe_to_disconnect_remote_disc_delay_millis = + absl::Milliseconds(10000); // If the receiver doesn't ack with payload_received_ack frame in 1s, the // sender will timeout the waiting. absl::Duration wait_payload_received_ack_millis = absl::Milliseconds(1000); From 56acecdffa3fd4b395a197f23e503606337c895c Mon Sep 17 00:00:00 2001 From: Janusz Sobczak Date: Thu, 5 Oct 2023 11:19:20 -0700 Subject: [PATCH 039/683] Migrate to AnyInvocable in DiscoveryListener PiperOrigin-RevId: 571077933 --- connections/c/core_adapter.cc | 6 +- connections/core.cc | 27 +++++---- connections/core_test.cc | 12 ++-- .../implementation/base_pcp_handler.cc | 51 ++++++++-------- connections/implementation/base_pcp_handler.h | 2 +- .../implementation/base_pcp_handler_test.cc | 27 +++++---- connections/implementation/client_proxy.cc | 6 +- connections/implementation/client_proxy.h | 2 +- .../implementation/client_proxy_test.cc | 58 ++++++++++--------- .../implementation/mock_service_controller.h | 3 +- .../mock_service_controller_router.h | 3 +- .../offline_service_controller.cc | 7 ++- .../offline_service_controller.h | 2 +- connections/implementation/pcp_handler.h | 2 +- .../implementation/service_controller.h | 2 +- .../service_controller_router.cc | 10 ++-- .../service_controller_router.h | 2 +- .../service_controller_router_test.cc | 52 ++++++++--------- connections/listeners.h | 10 ++-- .../Sources/GNCCoreAdapter.mm | 55 +++++++++--------- 20 files changed, 174 insertions(+), 165 deletions(-) diff --git a/connections/c/core_adapter.cc b/connections/c/core_adapter.cc index f8521f6d..920c7aa4 100644 --- a/connections/c/core_adapter.cc +++ b/connections/c/core_adapter.cc @@ -95,9 +95,6 @@ void StartDiscovery(connections::Core *pCore, const char *service_id, if (pCore == nullptr) { return; } - connections::DiscoveryListener discoveryListener = - std::move(*listener.GetImpl()); - connections::DiscoveryOptions discovery_options; if (discovery_options_w.strategy == StrategyW::kNone) @@ -125,7 +122,8 @@ void StartDiscovery(connections::Core *pCore, const char *service_id, discovery_options_w.allowed.wifi_hotspot; discovery_options.allowed.web_rtc = discovery_options_w.allowed.web_rtc; - pCore->StartDiscovery(service_id, discovery_options, discoveryListener, + pCore->StartDiscovery(service_id, discovery_options, + std::move(*listener.GetImpl()), std::move(*callback.GetImpl())); } diff --git a/connections/core.cc b/connections/core.cc index 2dbb44a2..cbca2a82 100644 --- a/connections/core.cc +++ b/connections/core.cc @@ -102,8 +102,8 @@ void Core::StartDiscovery(absl::string_view service_id, CheckServiceId(service_id); CHECK(discovery_options.strategy.IsValid()); - router_->StartDiscovery(&client_, service_id, discovery_options, listener, - std::move(callback)); + router_->StartDiscovery(&client_, service_id, discovery_options, + std::move(listener), std::move(callback)); } void Core::InjectEndpoint(absl::string_view service_id, @@ -302,23 +302,26 @@ void Core::StartDiscoveryV3(absl::string_view service_id, ResultCallback callback) { DiscoveryListener old_listener = { .endpoint_found_cb = - [&listener](const std::string& endpoint_id, - const ByteArray& endpoint_info, - const std::string& service_id) { + [endpoint_found_cb = std::move(listener.endpoint_found_cb)]( + const std::string& endpoint_id, const ByteArray& endpoint_info, + const std::string& service_id) mutable { auto remote_device = v3::ConnectionsDevice( endpoint_id, endpoint_info.AsStringView(), {}); - listener.endpoint_found_cb(remote_device, service_id); + endpoint_found_cb(remote_device, service_id); }, .endpoint_lost_cb = - [&listener](const std::string& endpoint_id) { + [endpoint_lost_cb = std::move(listener.endpoint_lost_cb)]( + const std::string& endpoint_id) mutable { auto remote_device = v3::ConnectionsDevice(endpoint_id, "", {}); - listener.endpoint_lost_cb(remote_device); + endpoint_lost_cb(remote_device); }, .endpoint_distance_changed_cb = - [&listener](const std::string& endpoint_id, - DistanceInfo distance_info) { + [endpoint_distance_changed_cb = + std::move(listener.endpoint_distance_changed_cb)]( + const std::string& endpoint_id, + DistanceInfo distance_info) mutable { auto remote = v3::ConnectionsDevice(endpoint_id, "", {}); - listener.endpoint_distance_changed_cb(remote, distance_info); + endpoint_distance_changed_cb(remote, distance_info); }, }; DiscoveryOptions old_discovery_options = { @@ -333,7 +336,7 @@ void Core::StartDiscoveryV3(absl::string_view service_id, discovery_options.power_level == PowerLevel::kLowPower, }; // TODO(b/291295755): Deeper refactor to use v3 options throughout. - StartDiscovery(service_id, old_discovery_options, old_listener, + StartDiscovery(service_id, old_discovery_options, std::move(old_listener), std::move(callback)); } diff --git a/connections/core_test.cc b/connections/core_test.cc index 5456963c..7fa4dfdd 100644 --- a/connections/core_test.cc +++ b/connections/core_test.cc @@ -158,8 +158,8 @@ TEST(CoreV3Test, TestDiscoveryOptionsConversionWorks) { }); EXPECT_CALL(mock, StartDiscovery) .WillOnce([](ClientProxy*, absl::string_view, - const DiscoveryOptions& options, - const DiscoveryListener& info, ResultCallback) { + const DiscoveryOptions& options, DiscoveryListener, + ResultCallback) { EXPECT_EQ(options.strategy, Strategy::kP2pCluster); EXPECT_FALSE(options.low_power); EXPECT_TRUE(options.auto_upgrade_bandwidth); @@ -411,12 +411,12 @@ TEST(CoreV3Test, TestCallbackWrapWorksStartDiscoveryV3) { MockServiceControllerRouter mock; EXPECT_CALL(mock, StartDiscovery) .WillOnce([&](ClientProxy*, absl::string_view, const DiscoveryOptions&, - const DiscoveryListener& info, const ResultCallback&) { + DiscoveryListener listener, const ResultCallback&) { // call all callbacks to make sure it all gets called correctly. NEARBY_LOGS(INFO) << "StartDiscovery called"; - info.endpoint_distance_changed_cb("FAKE", {}); - info.endpoint_found_cb("FAKE", ByteArray(), ""); - info.endpoint_lost_cb("FAKE"); + listener.endpoint_distance_changed_cb("FAKE", {}); + listener.endpoint_found_cb("FAKE", ByteArray(), ""); + listener.endpoint_lost_cb("FAKE"); }); EXPECT_CALL(mock, StopAllEndpoints) .WillOnce([&](ClientProxy* client, ResultCallback callback) { diff --git a/connections/implementation/base_pcp_handler.cc b/connections/implementation/base_pcp_handler.cc index 41218bbe..efdd7c91 100644 --- a/connections/implementation/base_pcp_handler.cc +++ b/connections/implementation/base_pcp_handler.cc @@ -22,18 +22,20 @@ #include #include "securegcm/ukey2_handshake.h" +#include "absl/base/thread_annotations.h" #include "absl/container/flat_hash_set.h" #include "absl/strings/escaping.h" #include "absl/time/time.h" #include "absl/types/span.h" #include "connections/advertising_options.h" #include "connections/connection_options.h" -#include "connections/implementation/endpoint_channel_manager.h" #include "connections/implementation/client_proxy.h" +#include "connections/implementation/endpoint_channel_manager.h" #include "connections/implementation/flags/nearby_connections_feature_flags.h" #include "connections/implementation/mediums/utils.h" #include "connections/implementation/offline_frames.h" #include "connections/implementation/proto/offline_wire_formats.pb.h" +#include "connections/listeners.h" #include "connections/medium_selector.h" #include "connections/status.h" #include "connections/v3/connection_listening_options.h" @@ -353,7 +355,7 @@ BooleanMediumSelector BasePcpHandler::ComputeIntersectionOfSupportedMediums( Status BasePcpHandler::StartDiscovery(ClientProxy* client, const std::string& service_id, const DiscoveryOptions& discovery_options, - const DiscoveryListener& listener) { + DiscoveryListener listener) { Future response; DiscoveryOptions stripped_discovery_options = discovery_options; StripOutUnavailableMediums(stripped_discovery_options); @@ -362,9 +364,9 @@ Status BasePcpHandler::StartDiscovery(ClientProxy* client, stripped_discovery_options); RunOnPcpHandlerThread( "start-discovery", - [this, client, service_id, stripped_discovery_options, &listener, - &response]() RUN_ON_PCP_HANDLER_THREAD() - ABSL_LOCKS_EXCLUDED(discovered_endpoint_mutex_) { + [this, client, service_id, stripped_discovery_options, + listener = std::move(listener), &response]() RUN_ON_PCP_HANDLER_THREAD() + ABSL_LOCKS_EXCLUDED(discovered_endpoint_mutex_) mutable { // Ask the implementation to attempt to start discovery. auto result = StartDiscoveryImpl(client, service_id, stripped_discovery_options); @@ -379,9 +381,9 @@ Status BasePcpHandler::StartDiscovery(ClientProxy* client, MutexLock lock(&discovered_endpoint_mutex_); discovered_endpoints_.clear(); } - client->StartedDiscovery(service_id, GetStrategy(), listener, - absl::MakeSpan(result.mediums), - stripped_discovery_options); + client->StartedDiscovery( + service_id, GetStrategy(), std::move(listener), + absl::MakeSpan(result.mediums), stripped_discovery_options); response.Set({Status::kSuccess}); }); return WaitForResult(absl::StrCat("StartDiscovery(", service_id, ")"), @@ -1316,8 +1318,8 @@ void BasePcpHandler::OnIncomingFrame( client->SetRemoteSafeToDisconnectVersion( endpoint_id, connection_response.safe_to_disconnect_version()); } - channel_manager_->UpdateSafeToDisconnectForEndpoint(endpoint_id, - client->IsSafeToDisconnectEnabled(endpoint_id)); + channel_manager_->UpdateSafeToDisconnectForEndpoint( + endpoint_id, client->IsSafeToDisconnectEnabled(endpoint_id)); EvaluateConnectionResult(client, endpoint_id, /* can_close_immediately= */ true); @@ -1335,21 +1337,20 @@ void BasePcpHandler::OnEndpointDisconnect(ClientProxy* client, barrier.CountDown(); return; } - RunOnPcpHandlerThread("on-endpoint-disconnect", - [this, client, endpoint_id, barrier, reason]() - RUN_ON_PCP_HANDLER_THREAD() mutable { - auto item = pending_alarms_.find(endpoint_id); - if (item != pending_alarms_.end()) { - auto& alarm = item->second; - alarm->Cancel(); - pending_alarms_.erase(item); - } - ProcessPreConnectionResultFailure( - client, endpoint_id, - /* should_call_disconnect_endpoint= */ false, - reason); - barrier.CountDown(); - }); + RunOnPcpHandlerThread( + "on-endpoint-disconnect", [this, client, endpoint_id, barrier, + reason]() RUN_ON_PCP_HANDLER_THREAD() mutable { + auto item = pending_alarms_.find(endpoint_id); + if (item != pending_alarms_.end()) { + auto& alarm = item->second; + alarm->Cancel(); + pending_alarms_.erase(item); + } + ProcessPreConnectionResultFailure( + client, endpoint_id, + /* should_call_disconnect_endpoint= */ false, reason); + barrier.CountDown(); + }); } BluetoothDevice BasePcpHandler::GetRemoteBluetoothDevice( diff --git a/connections/implementation/base_pcp_handler.h b/connections/implementation/base_pcp_handler.h index b40d6c0d..19b87e80 100644 --- a/connections/implementation/base_pcp_handler.h +++ b/connections/implementation/base_pcp_handler.h @@ -106,7 +106,7 @@ class BasePcpHandler : public PcpHandler, // DiscoveryListener will get called in case of any event. Status StartDiscovery(ClientProxy* client, const std::string& service_id, const DiscoveryOptions& discovery_options, - const DiscoveryListener& listener) override; + DiscoveryListener listener) override; // Stops Discovery if it is active, and changes CLientProxy state, // otherwise does nothing. diff --git a/connections/implementation/base_pcp_handler_test.cc b/connections/implementation/base_pcp_handler_test.cc index 2e2831dc..535a1a74 100644 --- a/connections/implementation/base_pcp_handler_test.cc +++ b/connections/implementation/base_pcp_handler_test.cc @@ -471,7 +471,7 @@ class BasePcpHandlerTest pcp_handler->GetMediumsFromSelector(discovery_options.allowed), })); EXPECT_EQ(pcp_handler->StartDiscovery(client, service_id, discovery_options, - discovery_listener_), + GetDiscoveryListener()), Status{Status::kSuccess}); EXPECT_TRUE(client->IsDiscovering()); for (const auto& discovered_medium : @@ -812,14 +812,17 @@ class BasePcpHandlerTest .bandwidth_changed_cb = mock_connection_listener_.bandwidth_changed_cb.AsStdFunction(), }; - DiscoveryListener discovery_listener_{ - .endpoint_found_cb = - mock_discovery_listener_.endpoint_found_cb.AsStdFunction(), - .endpoint_lost_cb = - mock_discovery_listener_.endpoint_lost_cb.AsStdFunction(), - .endpoint_distance_changed_cb = - mock_discovery_listener_.endpoint_distance_changed_cb.AsStdFunction(), - }; + DiscoveryListener GetDiscoveryListener() { + return DiscoveryListener{ + .endpoint_found_cb = + mock_discovery_listener_.endpoint_found_cb.AsStdFunction(), + .endpoint_lost_cb = + mock_discovery_listener_.endpoint_lost_cb.AsStdFunction(), + .endpoint_distance_changed_cb = + mock_discovery_listener_.endpoint_distance_changed_cb + .AsStdFunction(), + }; + } SetSafeToDisconnect set_safe_to_disconnect_{true}; MediumEnvironment& env_ = MediumEnvironment::Instance(); NiceMock mock_device_; @@ -902,7 +905,7 @@ TEST_P(BasePcpHandlerTest, StartDiscoveryFails) { .mediums = {}, })); EXPECT_EQ(pcp_handler.StartDiscovery(&client, "service", discovery_options, - discovery_listener_), + GetDiscoveryListener()), Status{Status::kError}); bwu.Shutdown(); env_.Stop(); @@ -985,7 +988,7 @@ TEST_F(BasePcpHandlerTest, WifiMediumFailFallBackToBT) { })); EXPECT_EQ(pcp_handler.StartDiscovery(&client, service_id, discovery_options, - discovery_listener_), + GetDiscoveryListener()), Status{Status::kSuccess}); EXPECT_TRUE(client.IsDiscovering()); @@ -1566,7 +1569,7 @@ TEST_F(BasePcpHandlerTest, InjectEndpoint) { .mediums = allowed.GetMediums(true), })); EXPECT_EQ(pcp_handler.StartDiscovery(&client, service_id, discovery_options, - discovery_listener_), + GetDiscoveryListener()), Status{Status::kSuccess}); EXPECT_TRUE(client.IsDiscovering()); diff --git a/connections/implementation/client_proxy.cc b/connections/implementation/client_proxy.cc index 441d774d..c86ae99f 100644 --- a/connections/implementation/client_proxy.cc +++ b/connections/implementation/client_proxy.cc @@ -31,6 +31,7 @@ #include "absl/strings/escaping.h" #include "absl/strings/string_view.h" #include "connections/implementation/flags/nearby_connections_feature_flags.h" +#include "connections/listeners.h" #include "connections/v3/bandwidth_info.h" #include "connections/v3/connection_listening_options.h" #include "connections/v3/connections_device_provider.h" @@ -282,11 +283,11 @@ ConnectionListener ClientProxy::GetAdvertisingOrIncomingConnectionListener() { void ClientProxy::StartedDiscovery( const std::string& service_id, Strategy strategy, - const DiscoveryListener& listener, + DiscoveryListener listener, absl::Span mediums, const DiscoveryOptions& discovery_options) { MutexLock lock(&mutex_); - discovery_info_ = DiscoveryInfo{service_id, listener}; + discovery_info_ = DiscoveryInfo{service_id, std::move(listener)}; discovery_options_ = discovery_options; const std::vector medium_vector( @@ -856,7 +857,6 @@ bool ClientProxy::IsPayloadReceivedAckEnabled(absl::string_view endpoint_id) { .min_nc_version_supports_payload_received_ack); } - void ClientProxy::CancelAllEndpoints() { for (const auto& item : cancellation_flags_) { CancellationFlag* cancellation_flag = item.second.get(); diff --git a/connections/implementation/client_proxy.h b/connections/implementation/client_proxy.h index e39ae058..ff6a8c4d 100644 --- a/connections/implementation/client_proxy.h +++ b/connections/implementation/client_proxy.h @@ -110,7 +110,7 @@ class ClientProxy final { // Marks this client as discovering with the given callback. void StartedDiscovery( const std::string& service_id, Strategy strategy, - const DiscoveryListener& discovery_listener, + DiscoveryListener discovery_listener, absl::Span mediums, const DiscoveryOptions& discovery_options = DiscoveryOptions{}); // Marks this client as not discovering at all. diff --git a/connections/implementation/client_proxy_test.cc b/connections/implementation/client_proxy_test.cc index 3d53bc87..e128f33c 100644 --- a/connections/implementation/client_proxy_test.cc +++ b/connections/implementation/client_proxy_test.cc @@ -210,7 +210,7 @@ class ClientProxyTest : public ::testing::TestWithParam { .info = ByteArray{"discovery endpoint name"}, .id = client->GetLocalEndpointId(), }; - client->StartedDiscovery(service_id_, strategy_, listener, + client->StartedDiscovery(service_id_, strategy_, std::move(listener), absl::MakeSpan(mediums_)); return endpoint; } @@ -363,10 +363,12 @@ class ClientProxyTest : public ::testing::TestWithParam { .bandwidth_changed_cb = mock_discovery_connection_.bandwidth_changed_cb.AsStdFunction(), }; - DiscoveryListener discovery_listener_{ - .endpoint_found_cb = mock_discovery_.endpoint_found_cb.AsStdFunction(), - .endpoint_lost_cb = mock_discovery_.endpoint_lost_cb.AsStdFunction(), - }; + DiscoveryListener GetDiscoveryListener() { + return DiscoveryListener{ + .endpoint_found_cb = mock_discovery_.endpoint_found_cb.AsStdFunction(), + .endpoint_lost_cb = mock_discovery_.endpoint_lost_cb.AsStdFunction(), + }; + } ConnectionOptions connection_options_; AdvertisingOptions advertising_options_; DiscoveryOptions discovery_options_; @@ -379,7 +381,7 @@ TEST_P(ClientProxyTest, CanCancelEndpoint) { Endpoint advertising_endpoint = StartAdvertising(&client1_, advertising_connection_listener_); - StartDiscovery(&client2_, discovery_listener_); + StartDiscovery(&client2_, GetDiscoveryListener()); OnDiscoveryEndpointFound(&client2_, advertising_endpoint); OnDiscoveryConnectionInitiated(&client2_, advertising_endpoint); @@ -415,7 +417,7 @@ TEST_P(ClientProxyTest, CanCancelAllEndpoints) { Endpoint advertising_endpoint = StartAdvertising(&client1_, advertising_connection_listener_); - StartDiscovery(&client2_, discovery_listener_); + StartDiscovery(&client2_, GetDiscoveryListener()); OnDiscoveryEndpointFound(&client2_, advertising_endpoint); OnDiscoveryConnectionInitiated(&client2_, advertising_endpoint); @@ -452,7 +454,7 @@ TEST_P(ClientProxyTest, CanCancelAllEndpointsWithDifferentEndpoint) { ConnectionListener advertising_connection_listener_3; ClientProxy client3; - StartDiscovery(&client1_, discovery_listener_); + StartDiscovery(&client1_, GetDiscoveryListener()); Endpoint advertising_endpoint_2 = StartAdvertising(&client2_, advertising_connection_listener_2); Endpoint advertising_endpoint_3 = @@ -558,14 +560,14 @@ TEST_F(ClientProxyTest, StartedDiscoveryChangesStateFromIdle) { TEST_F(ClientProxyTest, OnEndpointFoundFiresNotificationInDiscovery) { Endpoint advertising_endpoint = StartAdvertising(&client1_, advertising_connection_listener_); - StartDiscovery(&client2_, discovery_listener_); + StartDiscovery(&client2_, GetDiscoveryListener()); OnDiscoveryEndpointFound(&client2_, advertising_endpoint); } TEST_F(ClientProxyTest, OnEndpointLostFiresNotificationInDiscovery) { Endpoint advertising_endpoint = StartAdvertising(&client1_, advertising_connection_listener_); - StartDiscovery(&client2_, discovery_listener_); + StartDiscovery(&client2_, GetDiscoveryListener()); OnDiscoveryEndpointFound(&client2_, advertising_endpoint); OnDiscoveryEndpointLost(&client2_, advertising_endpoint); } @@ -573,7 +575,7 @@ TEST_F(ClientProxyTest, OnEndpointLostFiresNotificationInDiscovery) { TEST_F(ClientProxyTest, OnConnectionInitiatedFiresNotificationInDiscovery) { Endpoint advertising_endpoint = StartAdvertising(&client1_, advertising_connection_listener_); - StartDiscovery(&client2_, discovery_listener_); + StartDiscovery(&client2_, GetDiscoveryListener()); OnDiscoveryEndpointFound(&client2_, advertising_endpoint); OnDiscoveryConnectionInitiated(&client2_, advertising_endpoint); } @@ -581,7 +583,7 @@ TEST_F(ClientProxyTest, OnConnectionInitiatedFiresNotificationInDiscovery) { TEST_F(ClientProxyTest, OnBandwidthChangedFiresNotificationInDiscovery) { Endpoint advertising_endpoint = StartAdvertising(&client1_, advertising_connection_listener_); - StartDiscovery(&client2_, discovery_listener_); + StartDiscovery(&client2_, GetDiscoveryListener()); OnDiscoveryEndpointFound(&client2_, advertising_endpoint); OnDiscoveryConnectionInitiated(&client2_, advertising_endpoint); OnDiscoveryConnectionLocalAccepted(&client2_, advertising_endpoint); @@ -593,7 +595,7 @@ TEST_F(ClientProxyTest, OnBandwidthChangedFiresNotificationInDiscovery) { TEST_F(ClientProxyTest, OnDisconnectedFiresNotificationInDiscovery) { Endpoint advertising_endpoint = StartAdvertising(&client1_, advertising_connection_listener_); - StartDiscovery(&client2_, discovery_listener_); + StartDiscovery(&client2_, GetDiscoveryListener()); OnDiscoveryEndpointFound(&client2_, advertising_endpoint); OnDiscoveryConnectionInitiated(&client2_, advertising_endpoint); OnDiscoveryConnectionDisconnected(&client2_, advertising_endpoint); @@ -602,7 +604,7 @@ TEST_F(ClientProxyTest, OnDisconnectedFiresNotificationInDiscovery) { TEST_F(ClientProxyTest, LocalEndpointAcceptedConnectionChangesState) { Endpoint advertising_endpoint = StartAdvertising(&client1_, advertising_connection_listener_); - StartDiscovery(&client2_, discovery_listener_); + StartDiscovery(&client2_, GetDiscoveryListener()); OnDiscoveryEndpointFound(&client2_, advertising_endpoint); OnDiscoveryConnectionInitiated(&client2_, advertising_endpoint); OnDiscoveryConnectionLocalAccepted(&client2_, advertising_endpoint); @@ -611,7 +613,7 @@ TEST_F(ClientProxyTest, LocalEndpointAcceptedConnectionChangesState) { TEST_F(ClientProxyTest, LocalEndpointRejectedConnectionChangesState) { Endpoint advertising_endpoint = StartAdvertising(&client1_, advertising_connection_listener_); - StartDiscovery(&client2_, discovery_listener_); + StartDiscovery(&client2_, GetDiscoveryListener()); OnDiscoveryEndpointFound(&client2_, advertising_endpoint); OnDiscoveryConnectionInitiated(&client2_, advertising_endpoint); OnDiscoveryConnectionLocalRejected(&client2_, advertising_endpoint); @@ -620,7 +622,7 @@ TEST_F(ClientProxyTest, LocalEndpointRejectedConnectionChangesState) { TEST_F(ClientProxyTest, RemoteEndpointAcceptedConnectionChangesState) { Endpoint advertising_endpoint = StartAdvertising(&client1_, advertising_connection_listener_); - StartDiscovery(&client2_, discovery_listener_); + StartDiscovery(&client2_, GetDiscoveryListener()); OnDiscoveryEndpointFound(&client2_, advertising_endpoint); OnDiscoveryConnectionInitiated(&client2_, advertising_endpoint); OnDiscoveryConnectionRemoteAccepted(&client2_, advertising_endpoint); @@ -629,7 +631,7 @@ TEST_F(ClientProxyTest, RemoteEndpointAcceptedConnectionChangesState) { TEST_F(ClientProxyTest, RemoteEndpointRejectedConnectionChangesState) { Endpoint advertising_endpoint = StartAdvertising(&client1_, advertising_connection_listener_); - StartDiscovery(&client2_, discovery_listener_); + StartDiscovery(&client2_, GetDiscoveryListener()); OnDiscoveryEndpointFound(&client2_, advertising_endpoint); OnDiscoveryConnectionInitiated(&client2_, advertising_endpoint); OnDiscoveryConnectionRemoteRejected(&client2_, advertising_endpoint); @@ -638,7 +640,7 @@ TEST_F(ClientProxyTest, RemoteEndpointRejectedConnectionChangesState) { TEST_F(ClientProxyTest, OnPayloadChangesState) { Endpoint advertising_endpoint = StartAdvertising(&client1_, advertising_connection_listener_); - StartDiscovery(&client2_, discovery_listener_); + StartDiscovery(&client2_, GetDiscoveryListener()); OnDiscoveryEndpointFound(&client2_, advertising_endpoint); OnDiscoveryConnectionInitiated(&client2_, advertising_endpoint); OnDiscoveryConnectionLocalAccepted(&client2_, advertising_endpoint); @@ -650,7 +652,7 @@ TEST_F(ClientProxyTest, OnPayloadChangesState) { TEST_F(ClientProxyTest, OnPayloadProgressChangesState) { Endpoint advertising_endpoint = StartAdvertising(&client1_, advertising_connection_listener_); - StartDiscovery(&client2_, discovery_listener_); + StartDiscovery(&client2_, GetDiscoveryListener()); OnDiscoveryEndpointFound(&client2_, advertising_endpoint); OnDiscoveryConnectionInitiated(&client2_, advertising_endpoint); OnDiscoveryConnectionLocalAccepted(&client2_, advertising_endpoint); @@ -770,7 +772,7 @@ TEST_F(ClientProxyTest, EndpointIdRotateWhenStartDiscovery) { &client1_, advertising_connection_listener_, advertising_options); StopAdvertising(&client1_); - StartDiscovery(&client1_, discovery_listener_); + StartDiscovery(&client1_, GetDiscoveryListener()); Endpoint advertising_endpoint_2 = StartAdvertising( &client1_, advertising_connection_listener_, advertising_options); @@ -835,7 +837,7 @@ TEST_F(ClientProxyTest, NotLogSessionForStoppedAdvertisingWithConnection) { StartAdvertising(&client1_, advertising_connection_listener_); OnAdvertisingConnectionInitiated(&client1_, advertising_endpoint); - StartDiscovery(&client2_, discovery_listener_); + StartDiscovery(&client2_, GetDiscoveryListener()); OnDiscoveryEndpointFound(&client2_, advertising_endpoint); OnDiscoveryConnectionInitiated(&client2_, advertising_endpoint); @@ -874,7 +876,7 @@ TEST_F(ClientProxyTest, NotLogSessionForStoppedDiscoveryWithConnection) { Endpoint advertising_endpoint = StartAdvertising(&client1_, advertising_connection_listener_); - StartDiscovery(&client2_, discovery_listener_); + StartDiscovery(&client2_, GetDiscoveryListener()); OnDiscoveryEndpointFound(&client2_, advertising_endpoint); // Before @@ -894,7 +896,7 @@ TEST_F(ClientProxyTest, Endpoint advertising_endpoint = StartAdvertising(&client1_, advertising_connection_listener_); - StartDiscovery(&client2_, discovery_listener_); + StartDiscovery(&client2_, GetDiscoveryListener()); // Before EXPECT_FALSE(client2_.IsAdvertising()); // No Advertising @@ -911,7 +913,7 @@ TEST_F(ClientProxyTest, TEST_F(ClientProxyTest, LogSessionOnDisconnectedWithOneConnection) { Endpoint advertising_endpoint = StartAdvertising(&client1_, advertising_connection_listener_); - StartDiscovery(&client2_, discovery_listener_); + StartDiscovery(&client2_, GetDiscoveryListener()); OnDiscoveryEndpointFound(&client2_, advertising_endpoint); OnDiscoveryConnectionInitiated(&client2_, advertising_endpoint); @@ -950,7 +952,7 @@ TEST_F(ClientProxyTest, NotLogSessionOnDisconnectedWhenMoreThanOneConnection) { StartAdvertising(&client1_, advertising_connection_listener_); Endpoint advertising_endpoint_2 = StartAdvertising(&client2_, advertising_connection_listener_); - StartDiscovery(&client3, discovery_listener_); + StartDiscovery(&client3, GetDiscoveryListener()); OnDiscoveryEndpointFound(&client3, advertising_endpoint_1); OnDiscoveryConnectionInitiated(&client3, advertising_endpoint_1); @@ -976,7 +978,7 @@ TEST_F(ClientProxyTest, NotLogSessionOnDisconnectedForDiscoveringWithOnlyOneConnection) { Endpoint advertising_endpoint = StartAdvertising(&client1_, advertising_connection_listener_); - StartDiscovery(&client2_, discovery_listener_); + StartDiscovery(&client2_, GetDiscoveryListener()); OnDiscoveryEndpointFound(&client2_, advertising_endpoint); OnDiscoveryConnectionInitiated(&client2_, advertising_endpoint); @@ -995,7 +997,7 @@ TEST_F(ClientProxyTest, TEST_F(ClientProxyTest, LogSessionForResetClientProxy) { Endpoint advertising_endpoint = StartAdvertising(&client1_, advertising_connection_listener_); - StartDiscovery(&client2_, discovery_listener_); + StartDiscovery(&client2_, GetDiscoveryListener()); OnDiscoveryEndpointFound(&client2_, advertising_endpoint); OnDiscoveryConnectionInitiated(&client2_, advertising_endpoint); @@ -1039,7 +1041,7 @@ TEST_F(ClientProxyTest, SetRemoteInfoCorrect) { std::int32_t nearby_connections_version = 2; client1_.SetRemoteOsInfo(advertising_endpoint.id, os_info); client1_.SetRemoteSafeToDisconnectVersion(advertising_endpoint.id, - nearby_connections_version); + nearby_connections_version); ASSERT_TRUE(client1_.GetRemoteOsInfo(advertising_endpoint.id).has_value()); EXPECT_EQ(client1_.GetRemoteOsInfo(advertising_endpoint.id).value().type(), diff --git a/connections/implementation/mock_service_controller.h b/connections/implementation/mock_service_controller.h index 564b4257..02e336c4 100644 --- a/connections/implementation/mock_service_controller.h +++ b/connections/implementation/mock_service_controller.h @@ -20,6 +20,7 @@ #include "gmock/gmock.h" #include "connections/implementation/service_controller.h" +#include "connections/listeners.h" #include "connections/v3/connection_listening_options.h" #include "internal/interop/device.h" @@ -47,7 +48,7 @@ class MockServiceController : public ServiceController { MOCK_METHOD(Status, StartDiscovery, (ClientProxy * client, const std::string& service_id, const DiscoveryOptions& discovery_options, - const DiscoveryListener& listener), + DiscoveryListener listener), (override)); MOCK_METHOD(void, StopDiscovery, (ClientProxy * client), (override)); diff --git a/connections/implementation/mock_service_controller_router.h b/connections/implementation/mock_service_controller_router.h index 4d8ea108..14e6e9c5 100644 --- a/connections/implementation/mock_service_controller_router.h +++ b/connections/implementation/mock_service_controller_router.h @@ -17,6 +17,7 @@ #include "gmock/gmock.h" #include "connections/implementation/service_controller_router.h" +#include "connections/listeners.h" namespace nearby { namespace connections { @@ -35,7 +36,7 @@ class MockServiceControllerRouter : public ServiceControllerRouter { MOCK_METHOD(void, StartDiscovery, (ClientProxy * client, absl::string_view service_id, const DiscoveryOptions& discovery_options, - const DiscoveryListener& listener, ResultCallback callback), + DiscoveryListener listener, ResultCallback callback), (override)); MOCK_METHOD(void, StopDiscovery, diff --git a/connections/implementation/offline_service_controller.cc b/connections/implementation/offline_service_controller.cc index 3ae1e27d..a1811cd7 100644 --- a/connections/implementation/offline_service_controller.cc +++ b/connections/implementation/offline_service_controller.cc @@ -19,6 +19,8 @@ #include #include "absl/strings/str_join.h" +#include "connections/discovery_options.h" +#include "connections/listeners.h" #include "internal/interop/device.h" namespace nearby { @@ -54,13 +56,12 @@ void OfflineServiceController::StopAdvertising(ClientProxy* client) { Status OfflineServiceController::StartDiscovery( ClientProxy* client, const std::string& service_id, - const DiscoveryOptions& discovery_options, - const DiscoveryListener& listener) { + const DiscoveryOptions& discovery_options, DiscoveryListener listener) { if (stop_) return {Status::kOutOfOrderApiCall}; NEARBY_LOGS(INFO) << "Client " << client->GetClientId() << " requested discovery to start."; return pcp_manager_.StartDiscovery(client, service_id, discovery_options, - listener); + std::move(listener)); } void OfflineServiceController::StopDiscovery(ClientProxy* client) { diff --git a/connections/implementation/offline_service_controller.h b/connections/implementation/offline_service_controller.h index 13661961..9331aa35 100644 --- a/connections/implementation/offline_service_controller.h +++ b/connections/implementation/offline_service_controller.h @@ -49,7 +49,7 @@ class OfflineServiceController : public ServiceController { Status StartDiscovery(ClientProxy* client, const std::string& service_id, const DiscoveryOptions& discovery_options, - const DiscoveryListener& listener) override; + DiscoveryListener listener) override; void StopDiscovery(ClientProxy* client) override; void InjectEndpoint(ClientProxy* client, const std::string& service_id, diff --git a/connections/implementation/pcp_handler.h b/connections/implementation/pcp_handler.h index d156a916..16d9273a 100644 --- a/connections/implementation/pcp_handler.h +++ b/connections/implementation/pcp_handler.h @@ -83,7 +83,7 @@ class PcpHandler { virtual Status StartDiscovery(ClientProxy* client, const std::string& service_id, const DiscoveryOptions& discovery_options, - const DiscoveryListener& listener) = 0; + DiscoveryListener listener) = 0; // If Discovery is active, stop it, and change CLientProxy state, // otherwise do nothing. diff --git a/connections/implementation/service_controller.h b/connections/implementation/service_controller.h index 8a5acf39..e0dbbf31 100644 --- a/connections/implementation/service_controller.h +++ b/connections/implementation/service_controller.h @@ -74,7 +74,7 @@ class ServiceController { virtual Status StartDiscovery(ClientProxy* client, const std::string& service_id, const DiscoveryOptions& discovery_options, - const DiscoveryListener& listener) = 0; + DiscoveryListener listener) = 0; virtual void StopDiscovery(ClientProxy* client) = 0; virtual void InjectEndpoint(ClientProxy* client, diff --git a/connections/implementation/service_controller_router.cc b/connections/implementation/service_controller_router.cc index b6053718..15605478 100644 --- a/connections/implementation/service_controller_router.cc +++ b/connections/implementation/service_controller_router.cc @@ -20,6 +20,7 @@ #include #include "absl/memory/memory.h" +#include "connections/discovery_options.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/offline_service_controller.h" #include "connections/listeners.h" @@ -127,19 +128,20 @@ void ServiceControllerRouter::StopAdvertising(ClientProxy* client, void ServiceControllerRouter::StartDiscovery( ClientProxy* client, absl::string_view service_id, - const DiscoveryOptions& discovery_options, - const DiscoveryListener& listener, ResultCallback callback) { + const DiscoveryOptions& discovery_options, DiscoveryListener listener, + ResultCallback callback) { RouteToServiceController( "scr-start-discovery", [this, client, service_id = std::string(service_id), discovery_options, - listener, callback = std::move(callback)]() mutable { + listener = std::move(listener), + callback = std::move(callback)]() mutable { if (client->IsDiscovering()) { callback({Status::kAlreadyDiscovering}); return; } callback(GetServiceController()->StartDiscovery( - client, service_id, discovery_options, listener)); + client, service_id, discovery_options, std::move(listener))); }); } diff --git a/connections/implementation/service_controller_router.h b/connections/implementation/service_controller_router.h index 9b3ee470..759aea75 100644 --- a/connections/implementation/service_controller_router.h +++ b/connections/implementation/service_controller_router.h @@ -76,7 +76,7 @@ class ServiceControllerRouter { virtual void StartDiscovery(ClientProxy* client, absl::string_view service_id, const DiscoveryOptions& discovery_options, - const DiscoveryListener& listener, + DiscoveryListener listener, ResultCallback callback); virtual void StopDiscovery(ClientProxy* client, ResultCallback callback); diff --git a/connections/implementation/service_controller_router_test.cc b/connections/implementation/service_controller_router_test.cc index e636e30f..9fdd2b8f 100644 --- a/connections/implementation/service_controller_router_test.cc +++ b/connections/implementation/service_controller_router_test.cc @@ -104,20 +104,19 @@ class ServiceControllerRouterTest : public testing::Test { void StartDiscovery(ClientProxy* client, std::string service_id, DiscoveryOptions discovery_options, - const DiscoveryListener& listener, - ResultCallback callback) { + DiscoveryListener listener, ResultCallback callback) { EXPECT_CALL(*mock_, StartDiscovery) .WillOnce(Return(Status{Status::kSuccess})); { MutexLock lock(&mutex_); complete_ = false; - router_.StartDiscovery(client, kServiceId, discovery_options, listener, + router_.StartDiscovery(client, kServiceId, discovery_options, {}, std::move(callback)); while (!complete_) cond_.Wait(); EXPECT_EQ(result_, Status{Status::kSuccess}); } - client->StartedDiscovery(service_id, discovery_options.strategy, listener, - absl::MakeSpan(mediums_)); + client->StartedDiscovery(service_id, discovery_options.strategy, + std::move(listener), absl::MakeSpan(mediums_)); EXPECT_TRUE(client->IsDiscovering()); } @@ -185,8 +184,7 @@ class ServiceControllerRouterTest : public testing::Test { while (!complete_) cond_.Wait(); EXPECT_EQ(result_, Status{Status::kSuccess}); } - client->LocalEndpointAcceptedConnection(endpoint_id, - {}); + client->LocalEndpointAcceptedConnection(endpoint_id, {}); client->RemoteEndpointAcceptedConnection(endpoint_id); EXPECT_TRUE(client->IsConnectionAccepted(endpoint_id)); client->OnConnectionAccepted(endpoint_id); @@ -506,8 +504,6 @@ class ServiceControllerRouterTest : public testing::Test { .listener = ConnectionListener(), }; - DiscoveryListener discovery_listener_; - Mutex mutex_; ConditionVariable cond_{&mutex_}; Status result_ ABSL_GUARDED_BY(mutex_) = {Status::kError}; @@ -561,7 +557,7 @@ TEST_F(ServiceControllerRouterTest, StopAdvertisingCalled) { } TEST_F(ServiceControllerRouterTest, StartDiscoveryCalled) { - StartDiscovery(&client_, kServiceId, kDiscoveryOptions, discovery_listener_, + StartDiscovery(&client_, kServiceId, kDiscoveryOptions, DiscoveryListener{}, [this](Status status) { MutexLock lock(&mutex_); result_ = status; @@ -571,7 +567,7 @@ TEST_F(ServiceControllerRouterTest, StartDiscoveryCalled) { } TEST_F(ServiceControllerRouterTest, StopDiscoveryCalled) { - StartDiscovery(&client_, kServiceId, kDiscoveryOptions, discovery_listener_, + StartDiscovery(&client_, kServiceId, kDiscoveryOptions, DiscoveryListener{}, [this](Status status) { MutexLock lock(&mutex_); result_ = status; @@ -587,7 +583,7 @@ TEST_F(ServiceControllerRouterTest, StopDiscoveryCalled) { } TEST_F(ServiceControllerRouterTest, InjectEndpointCalled) { - StartDiscovery(&client_, kServiceId, kDiscoveryOptions, discovery_listener_, + StartDiscovery(&client_, kServiceId, kDiscoveryOptions, DiscoveryListener{}, [this](Status status) { MutexLock lock(&mutex_); result_ = status; @@ -611,7 +607,7 @@ TEST_F(ServiceControllerRouterTest, InjectEndpointCalled) { TEST_F(ServiceControllerRouterTest, RequestConnectionCalled) { // Either Advertising, or Discovery should be ongoing. - StartDiscovery(&client_, kServiceId, kDiscoveryOptions, discovery_listener_, + StartDiscovery(&client_, kServiceId, kDiscoveryOptions, DiscoveryListener{}, [this](Status status) { MutexLock lock(&mutex_); result_ = status; @@ -629,7 +625,7 @@ TEST_F(ServiceControllerRouterTest, RequestConnectionCalled) { TEST_F(ServiceControllerRouterTest, AcceptConnectionCalled) { // Either Advertising, or Discovery should be ongoing. - StartDiscovery(&client_, kServiceId, kDiscoveryOptions, discovery_listener_, + StartDiscovery(&client_, kServiceId, kDiscoveryOptions, DiscoveryListener{}, [this](Status status) { MutexLock lock(&mutex_); result_ = status; @@ -655,7 +651,7 @@ TEST_F(ServiceControllerRouterTest, AcceptConnectionCalled) { TEST_F(ServiceControllerRouterTest, RejectConnectionCalled) { // Either Advertising, or Discovery should be ongoing. - StartDiscovery(&client_, kServiceId, kDiscoveryOptions, discovery_listener_, + StartDiscovery(&client_, kServiceId, kDiscoveryOptions, DiscoveryListener{}, [this](Status status) { MutexLock lock(&mutex_); result_ = status; @@ -681,7 +677,7 @@ TEST_F(ServiceControllerRouterTest, RejectConnectionCalled) { TEST_F(ServiceControllerRouterTest, InitiateBandwidthUpgradeCalled) { // Either Advertising, or Discovery should be ongoing. - StartDiscovery(&client_, kServiceId, kDiscoveryOptions, discovery_listener_, + StartDiscovery(&client_, kServiceId, kDiscoveryOptions, DiscoveryListener{}, [this](Status status) { MutexLock lock(&mutex_); result_ = status; @@ -714,7 +710,7 @@ TEST_F(ServiceControllerRouterTest, InitiateBandwidthUpgradeCalled) { TEST_F(ServiceControllerRouterTest, SendPayloadCalled) { // Either Advertising, or Discovery should be ongoing. - StartDiscovery(&client_, kServiceId, kDiscoveryOptions, discovery_listener_, + StartDiscovery(&client_, kServiceId, kDiscoveryOptions, DiscoveryListener{}, [this](Status status) { MutexLock lock(&mutex_); result_ = status; @@ -748,7 +744,7 @@ TEST_F(ServiceControllerRouterTest, SendPayloadCalled) { TEST_F(ServiceControllerRouterTest, CancelPayloadCalled) { // Either Advertising, or Discovery should be ongoing. - StartDiscovery(&client_, kServiceId, kDiscoveryOptions, discovery_listener_, + StartDiscovery(&client_, kServiceId, kDiscoveryOptions, DiscoveryListener{}, [this](Status status) { MutexLock lock(&mutex_); result_ = status; @@ -783,7 +779,7 @@ TEST_F(ServiceControllerRouterTest, CancelPayloadCalled) { TEST_F(ServiceControllerRouterTest, DisconnectFromEndpointCalled) { // Either Advertising, or Discovery should be ongoing. - StartDiscovery(&client_, kServiceId, kDiscoveryOptions, discovery_listener_, + StartDiscovery(&client_, kServiceId, kDiscoveryOptions, DiscoveryListener{}, [this](Status status) { MutexLock lock(&mutex_); result_ = status; @@ -816,7 +812,7 @@ TEST_F(ServiceControllerRouterTest, DisconnectFromEndpointCalled) { TEST_F(ServiceControllerRouterTest, RequestConnectionCalledV3) { // Either Advertising, or Discovery should be ongoing. - StartDiscovery(&client_, kServiceId, kDiscoveryOptions, discovery_listener_, + StartDiscovery(&client_, kServiceId, kDiscoveryOptions, DiscoveryListener{}, [this](Status status) { MutexLock lock(&mutex_); result_ = status; @@ -870,7 +866,7 @@ TEST_F(ServiceControllerRouterTest, RequestConnectionCalledV3) { TEST_F(ServiceControllerRouterTest, RequestConnectionV3FakeDevice) { // Either Advertising, or Discovery should be ongoing. - StartDiscovery(&client_, kServiceId, kDiscoveryOptions, discovery_listener_, + StartDiscovery(&client_, kServiceId, kDiscoveryOptions, DiscoveryListener{}, [this](Status status) { MutexLock lock(&mutex_); result_ = status; @@ -923,7 +919,7 @@ TEST_F(ServiceControllerRouterTest, RequestConnectionV3FakeDevice) { TEST_F(ServiceControllerRouterTest, RequestConnectionV3TwiceFails) { // Either Advertising, or Discovery should be ongoing. - StartDiscovery(&client_, kServiceId, kDiscoveryOptions, discovery_listener_, + StartDiscovery(&client_, kServiceId, kDiscoveryOptions, DiscoveryListener{}, [this](Status status) { MutexLock lock(&mutex_); result_ = status; @@ -967,7 +963,7 @@ TEST_F(ServiceControllerRouterTest, RequestConnectionV3TwiceFails) { TEST_F(ServiceControllerRouterTest, AcceptConnectionCalledV3) { // Either Advertising, or Discovery should be ongoing. - StartDiscovery(&client_, kServiceId, kDiscoveryOptions, discovery_listener_, + StartDiscovery(&client_, kServiceId, kDiscoveryOptions, DiscoveryListener{}, [this](Status status) { MutexLock lock(&mutex_); result_ = status; @@ -1001,7 +997,7 @@ TEST_F(ServiceControllerRouterTest, AcceptConnectionCalledV3) { TEST_F(ServiceControllerRouterTest, RejectConnectionCalledV3) { // Either Advertising, or Discovery should be ongoing. - StartDiscovery(&client_, kServiceId, kDiscoveryOptions, discovery_listener_, + StartDiscovery(&client_, kServiceId, kDiscoveryOptions, DiscoveryListener{}, [this](Status status) { MutexLock lock(&mutex_); result_ = status; @@ -1035,7 +1031,7 @@ TEST_F(ServiceControllerRouterTest, RejectConnectionCalledV3) { TEST_F(ServiceControllerRouterTest, InitiateBandwidthUpgradeCalledV3) { // Either Advertising, or Discovery should be ongoing. - StartDiscovery(&client_, kServiceId, kDiscoveryOptions, discovery_listener_, + StartDiscovery(&client_, kServiceId, kDiscoveryOptions, DiscoveryListener{}, [this](Status status) { MutexLock lock(&mutex_); result_ = status; @@ -1076,7 +1072,7 @@ TEST_F(ServiceControllerRouterTest, InitiateBandwidthUpgradeCalledV3) { TEST_F(ServiceControllerRouterTest, SendPayloadCalledV3) { // Either Advertising, or Discovery should be ongoing. - StartDiscovery(&client_, kServiceId, kDiscoveryOptions, discovery_listener_, + StartDiscovery(&client_, kServiceId, kDiscoveryOptions, DiscoveryListener{}, [this](Status status) { MutexLock lock(&mutex_); result_ = status; @@ -1118,7 +1114,7 @@ TEST_F(ServiceControllerRouterTest, SendPayloadCalledV3) { TEST_F(ServiceControllerRouterTest, DisconnectFromDeviceCalledV3) { // Either Advertising, or Discovery should be ongoing. - StartDiscovery(&client_, kServiceId, kDiscoveryOptions, discovery_listener_, + StartDiscovery(&client_, kServiceId, kDiscoveryOptions, DiscoveryListener{}, [this](Status status) { MutexLock lock(&mutex_); result_ = status; @@ -1159,7 +1155,7 @@ TEST_F(ServiceControllerRouterTest, DisconnectFromDeviceCalledV3) { TEST_F(ServiceControllerRouterTest, CancelPayloadV3Called) { // Either Advertising, or Discovery should be ongoing. - StartDiscovery(&client_, kServiceId, kDiscoveryOptions, discovery_listener_, + StartDiscovery(&client_, kServiceId, kDiscoveryOptions, DiscoveryListener{}, [this](Status status) { MutexLock lock(&mutex_); result_ = status; diff --git a/connections/listeners.h b/connections/listeners.h index 15ed72f7..493decaf 100644 --- a/connections/listeners.h +++ b/connections/listeners.h @@ -136,9 +136,9 @@ struct DiscoveryListener { // endpoint_id - The ID of the remote endpoint that was discovered. // endpoint_info - The info of the remote endpoint representd by ByteArray. // service_id - The ID of the service advertised by the remote endpoint. - std::function + absl::AnyInvocable endpoint_found_cb = [](const std::string&, const ByteArray&, const std::string&) {}; @@ -147,7 +147,7 @@ struct DiscoveryListener { // #onEndpointFound(String, DiscoveredEndpointInfo)}. // // endpoint_id - The ID of the remote endpoint that was lost. - std::function endpoint_lost_cb = + absl::AnyInvocable endpoint_lost_cb = [](const std::string&) {}; // Called when a remote endpoint is found with an updated distance. @@ -155,7 +155,7 @@ struct DiscoveryListener { // arguments: // endpoint_id - The ID of the remote endpoint that was lost. // info - The distance info, encoded as enum value. - std::function + absl::AnyInvocable endpoint_distance_changed_cb = [](const std::string&, DistanceInfo) {}; }; diff --git a/connections/swift/NearbyCoreAdapter/Sources/GNCCoreAdapter.mm b/connections/swift/NearbyCoreAdapter/Sources/GNCCoreAdapter.mm index ef72eded..6ed239f3 100644 --- a/connections/swift/NearbyCoreAdapter/Sources/GNCCoreAdapter.mm +++ b/connections/swift/NearbyCoreAdapter/Sources/GNCCoreAdapter.mm @@ -199,13 +199,14 @@ GNCStatus GNCStatusFromCppStatus(Status status) { DiscoveryOptions discovery_options = [discoveryOptions toCpp]; DiscoveryListener listener; - listener.endpoint_found_cb = ^(const std::string &endpoint_id, const ByteArray &endpoint_info, - const std::string &service_id) { + listener.endpoint_found_cb = [delegate](const std::string &endpoint_id, + const ByteArray &endpoint_info, + const std::string &service_id) { NSString *endpointID = @(endpoint_id.c_str()); NSData *info = [NSData dataWithBytes:endpoint_info.data() length:endpoint_info.size()]; [delegate foundEndpoint:endpointID withEndpointInfo:info]; }; - listener.endpoint_lost_cb = ^(const std::string &endpoint_id) { + listener.endpoint_lost_cb = [delegate](const std::string &endpoint_id) { NSString *endpointID = @(endpoint_id.c_str()); [delegate lostEndpoint:endpointID]; }; @@ -290,30 +291,30 @@ GNCStatus GNCStatusFromCppStatus(Status status) { GNCPayload *gncPayload = [GNCPayload fromCpp:std::move(payload)]; [delegate receivedPayload:gncPayload fromEndpoint:endpointID]; }; - listener.payload_progress_cb = - [delegate](absl::string_view endpoint_id, const PayloadProgressInfo &info) { - NSString *endpointID = @(std::string(endpoint_id).c_str()); - GNCPayloadStatus status; - switch (info.status) { - case PayloadProgressInfo::Status::kSuccess: - status = GNCPayloadStatusSuccess; - break; - case PayloadProgressInfo::Status::kFailure: - status = GNCPayloadStatusFailure; - break; - case PayloadProgressInfo::Status::kInProgress: - status = GNCPayloadStatusInProgress; - break; - case PayloadProgressInfo::Status::kCanceled: - status = GNCPayloadStatusCanceled; - break; - } - [delegate receivedProgressUpdateForPayload:info.payload_id - withStatus:status - fromEndpoint:endpointID - bytesTransfered:info.bytes_transferred - totalBytes:info.total_bytes]; - }; + listener.payload_progress_cb = [delegate](absl::string_view endpoint_id, + const PayloadProgressInfo &info) { + NSString *endpointID = @(std::string(endpoint_id).c_str()); + GNCPayloadStatus status; + switch (info.status) { + case PayloadProgressInfo::Status::kSuccess: + status = GNCPayloadStatusSuccess; + break; + case PayloadProgressInfo::Status::kFailure: + status = GNCPayloadStatusFailure; + break; + case PayloadProgressInfo::Status::kInProgress: + status = GNCPayloadStatusInProgress; + break; + case PayloadProgressInfo::Status::kCanceled: + status = GNCPayloadStatusCanceled; + break; + } + [delegate receivedProgressUpdateForPayload:info.payload_id + withStatus:status + fromEndpoint:endpointID + bytesTransfered:info.bytes_transferred + totalBytes:info.total_bytes]; + }; ResultListener result = [completionHandler](Status status) { NSError *err = NSErrorFromCppStatus(status); From 12346928ef4dc7784c409c529cbf9e7bdc036fc7 Mon Sep 17 00:00:00 2001 From: hai007 Date: Thu, 5 Oct 2023 12:10:07 -0700 Subject: [PATCH 040/683] fix auto-resume logging issue PiperOrigin-RevId: 571093232 --- proto/connections_enums.proto | 1 + 1 file changed, 1 insertion(+) diff --git a/proto/connections_enums.proto b/proto/connections_enums.proto index 072b4625..6873d7dc 100644 --- a/proto/connections_enums.proto +++ b/proto/connections_enums.proto @@ -169,6 +169,7 @@ enum DisconnectionReason { UPGRADED = 4; SHUTDOWN = 5; UNFINISHED = 6; + PREV_CHANNEL_DISCONNECTION_IN_RECONNECT = 7; } // The type of a Payload. From 0160b32c1d432f4608cd409a7026e675afb5eccf Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Fri, 6 Oct 2023 09:43:44 -0700 Subject: [PATCH 041/683] fix auto-resume logging issue PiperOrigin-RevId: 571361682 --- connections/implementation/endpoint_channel_manager.h | 1 + connections/implementation/endpoint_manager.cc | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/connections/implementation/endpoint_channel_manager.h b/connections/implementation/endpoint_channel_manager.h index 2f7348aa..df38a538 100644 --- a/connections/implementation/endpoint_channel_manager.h +++ b/connections/implementation/endpoint_channel_manager.h @@ -28,6 +28,7 @@ #include "internal/platform/feature_flags.h" #include "internal/platform/mutex.h" #include "internal/proto/analytics/connections_log.pb.h" +#include "proto/connections_enums.pb.h" namespace nearby { namespace connections { diff --git a/connections/implementation/endpoint_manager.cc b/connections/implementation/endpoint_manager.cc index 0e61b8c1..97c393dd 100644 --- a/connections/implementation/endpoint_manager.cc +++ b/connections/implementation/endpoint_manager.cc @@ -47,6 +47,8 @@ using ::location::nearby::analytics::proto::ConnectionsLog; using ::location::nearby::connections::OfflineFrame; using ::location::nearby::connections::V1Frame; using ::nearby::analytics::PacketMetaData; +using DisconnectionReason = + ::location::nearby::proto::connections::DisconnectionReason; // We set this to 11s to provide sufficient time for an in-progress WebRTC // bandwidth upgrade to resolve. This is chosen to be slightly longer than the @@ -204,7 +206,7 @@ ExceptionOr EndpointManager::TryDecryptFrame( } auto elapsed = SystemClock::ElapsedRealtime() - start_time; if (elapsed > kDecryptRetryTimeout) { - NEARBY_LOGS(WARNING) << "Can't decrypt the mesage. Timeout after " + NEARBY_LOGS(WARNING) << "Can't decrypt the message. Timeout after " << elapsed; return Exception::kTimeout; } @@ -781,6 +783,7 @@ bool EndpointManager::ApplySafeToDisconnect(const std::string& endpoint_id, DisconnectionReason reason) { NEARBY_LOGS(INFO) << "[safe-to-disconnect] ApplySafeToDisconnect reason: " << reason; + // TODO(b/303544913): clean up the safe-to-disconnect logic bool is_safe_disconnection = false; bool send_disconnection_frame = true; absl::Duration timeout_millis = FeatureFlags::GetInstance() @@ -790,6 +793,7 @@ bool EndpointManager::ApplySafeToDisconnect(const std::string& endpoint_id, switch (reason) { case DisconnectionReason::UPGRADED: case DisconnectionReason::SHUTDOWN: + case DisconnectionReason::PREV_CHANNEL_DISCONNECTION_IN_RECONNECT: case DisconnectionReason::UNFINISHED: return true; // safe disconnection case DisconnectionReason::IO_ERROR: From 6a3fc35be801dfb3d71a969b4e4bced195189628 Mon Sep 17 00:00:00 2001 From: ggli-google Date: Fri, 6 Oct 2023 15:36:12 -0700 Subject: [PATCH 042/683] Compile protos --- compiled_proto/proto/connections_enums.pb.cc | 52 +++++++++++--------- compiled_proto/proto/connections_enums.pb.h | 10 ++-- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/compiled_proto/proto/connections_enums.pb.cc b/compiled_proto/proto/connections_enums.pb.cc index 20cd2d6f..76d86f05 100644 --- a/compiled_proto/proto/connections_enums.pb.cc +++ b/compiled_proto/proto/connections_enums.pb.cc @@ -656,29 +656,33 @@ bool ConnectionAttemptType_IsValid(int value) { case 0: case 1: case 2: + case 3: return true; default: return false; } } -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed ConnectionAttemptType_strings[3] = {}; +static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed ConnectionAttemptType_strings[4] = {}; static const char ConnectionAttemptType_names[] = "INITIAL" + "RECONNECT" "UNKNOWN_CONNECTION_ATTEMPT_TYPE" "UPGRADE"; static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry ConnectionAttemptType_entries[] = { { {ConnectionAttemptType_names + 0, 7}, 1 }, - { {ConnectionAttemptType_names + 7, 31}, 0 }, - { {ConnectionAttemptType_names + 38, 7}, 2 }, + { {ConnectionAttemptType_names + 7, 9}, 3 }, + { {ConnectionAttemptType_names + 16, 31}, 0 }, + { {ConnectionAttemptType_names + 47, 7}, 2 }, }; static const int ConnectionAttemptType_entries_by_number[] = { - 1, // 0 -> UNKNOWN_CONNECTION_ATTEMPT_TYPE + 2, // 0 -> UNKNOWN_CONNECTION_ATTEMPT_TYPE 0, // 1 -> INITIAL - 2, // 2 -> UPGRADE + 3, // 2 -> UPGRADE + 1, // 3 -> RECONNECT }; const std::string& ConnectionAttemptType_Name( @@ -687,12 +691,12 @@ const std::string& ConnectionAttemptType_Name( ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( ConnectionAttemptType_entries, ConnectionAttemptType_entries_by_number, - 3, ConnectionAttemptType_strings); + 4, ConnectionAttemptType_strings); (void) dummy; int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( ConnectionAttemptType_entries, ConnectionAttemptType_entries_by_number, - 3, value); + 4, value); return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : ConnectionAttemptType_strings[idx].get(); } @@ -700,7 +704,7 @@ bool ConnectionAttemptType_Parse( ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, ConnectionAttemptType* value) { int int_value; bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - ConnectionAttemptType_entries, 3, name, &int_value); + ConnectionAttemptType_entries, 4, name, &int_value); if (success) { *value = static_cast(int_value); } @@ -715,17 +719,19 @@ bool DisconnectionReason_IsValid(int value) { case 4: case 5: case 6: + case 7: return true; default: return false; } } -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed DisconnectionReason_strings[7] = {}; +static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed DisconnectionReason_strings[8] = {}; static const char DisconnectionReason_names[] = "IO_ERROR" "LOCAL_DISCONNECTION" + "PREV_CHANNEL_DISCONNECTION_IN_RECONNECT" "REMOTE_DISCONNECTION" "SHUTDOWN" "UNFINISHED" @@ -735,21 +741,23 @@ static const char DisconnectionReason_names[] = static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry DisconnectionReason_entries[] = { { {DisconnectionReason_names + 0, 8}, 3 }, { {DisconnectionReason_names + 8, 19}, 1 }, - { {DisconnectionReason_names + 27, 20}, 2 }, - { {DisconnectionReason_names + 47, 8}, 5 }, - { {DisconnectionReason_names + 55, 10}, 6 }, - { {DisconnectionReason_names + 65, 28}, 0 }, - { {DisconnectionReason_names + 93, 8}, 4 }, + { {DisconnectionReason_names + 27, 39}, 7 }, + { {DisconnectionReason_names + 66, 20}, 2 }, + { {DisconnectionReason_names + 86, 8}, 5 }, + { {DisconnectionReason_names + 94, 10}, 6 }, + { {DisconnectionReason_names + 104, 28}, 0 }, + { {DisconnectionReason_names + 132, 8}, 4 }, }; static const int DisconnectionReason_entries_by_number[] = { - 5, // 0 -> UNKNOWN_DISCONNECTION_REASON + 6, // 0 -> UNKNOWN_DISCONNECTION_REASON 1, // 1 -> LOCAL_DISCONNECTION - 2, // 2 -> REMOTE_DISCONNECTION + 3, // 2 -> REMOTE_DISCONNECTION 0, // 3 -> IO_ERROR - 6, // 4 -> UPGRADED - 3, // 5 -> SHUTDOWN - 4, // 6 -> UNFINISHED + 7, // 4 -> UPGRADED + 4, // 5 -> SHUTDOWN + 5, // 6 -> UNFINISHED + 2, // 7 -> PREV_CHANNEL_DISCONNECTION_IN_RECONNECT }; const std::string& DisconnectionReason_Name( @@ -758,12 +766,12 @@ const std::string& DisconnectionReason_Name( ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( DisconnectionReason_entries, DisconnectionReason_entries_by_number, - 7, DisconnectionReason_strings); + 8, DisconnectionReason_strings); (void) dummy; int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( DisconnectionReason_entries, DisconnectionReason_entries_by_number, - 7, value); + 8, value); return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : DisconnectionReason_strings[idx].get(); } @@ -771,7 +779,7 @@ bool DisconnectionReason_Parse( ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, DisconnectionReason* value) { int int_value; bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - DisconnectionReason_entries, 7, name, &int_value); + DisconnectionReason_entries, 8, name, &int_value); if (success) { *value = static_cast(int_value); } diff --git a/compiled_proto/proto/connections_enums.pb.h b/compiled_proto/proto/connections_enums.pb.h index 5f00902d..c7023f89 100644 --- a/compiled_proto/proto/connections_enums.pb.h +++ b/compiled_proto/proto/connections_enums.pb.h @@ -273,11 +273,12 @@ bool ConnectionAttemptDirection_Parse( enum ConnectionAttemptType : int { UNKNOWN_CONNECTION_ATTEMPT_TYPE = 0, INITIAL = 1, - UPGRADE = 2 + UPGRADE = 2, + RECONNECT = 3 }; bool ConnectionAttemptType_IsValid(int value); constexpr ConnectionAttemptType ConnectionAttemptType_MIN = UNKNOWN_CONNECTION_ATTEMPT_TYPE; -constexpr ConnectionAttemptType ConnectionAttemptType_MAX = UPGRADE; +constexpr ConnectionAttemptType ConnectionAttemptType_MAX = RECONNECT; constexpr int ConnectionAttemptType_ARRAYSIZE = ConnectionAttemptType_MAX + 1; const std::string& ConnectionAttemptType_Name(ConnectionAttemptType value); @@ -297,11 +298,12 @@ enum DisconnectionReason : int { IO_ERROR = 3, UPGRADED = 4, SHUTDOWN = 5, - UNFINISHED = 6 + UNFINISHED = 6, + PREV_CHANNEL_DISCONNECTION_IN_RECONNECT = 7 }; bool DisconnectionReason_IsValid(int value); constexpr DisconnectionReason DisconnectionReason_MIN = UNKNOWN_DISCONNECTION_REASON; -constexpr DisconnectionReason DisconnectionReason_MAX = UNFINISHED; +constexpr DisconnectionReason DisconnectionReason_MAX = PREV_CHANNEL_DISCONNECTION_IN_RECONNECT; constexpr int DisconnectionReason_ARRAYSIZE = DisconnectionReason_MAX + 1; const std::string& DisconnectionReason_Name(DisconnectionReason value); From ad6bd802679a5a1bb27a83207ff18fec5600d2ca Mon Sep 17 00:00:00 2001 From: Deling Ren Date: Tue, 10 Oct 2023 11:53:23 -0700 Subject: [PATCH 043/683] Fix the crash when an endpoint without a UTF8 name is discovered --- .../Example/iOS Example/Model/Model.swift | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/connections/swift/NearbyConnections/Example/iOS Example/Model/Model.swift b/connections/swift/NearbyConnections/Example/iOS Example/Model/Model.swift index 6128816c..df9bd086 100644 --- a/connections/swift/NearbyConnections/Example/iOS Example/Model/Model.swift +++ b/connections/swift/NearbyConnections/Example/iOS Example/Model/Model.swift @@ -120,10 +120,13 @@ class Model: ObservableObject { extension Model: DiscovererDelegate { func discoverer(_ discoverer: Discoverer, didFind endpointID: EndpointID, with context: Data) { + guard let endpointName = String(data: context, encoding: .utf8) else { + return + } let endpoint = DiscoveredEndpoint( id: UUID(), endpointID: endpointID, - endpointName: String(data: context, encoding: .utf8)! + endpointName: endpointName ) endpoints.insert(endpoint, at: 0) } @@ -138,10 +141,13 @@ extension Model: DiscovererDelegate { extension Model: AdvertiserDelegate { func advertiser(_ advertiser: Advertiser, didReceiveConnectionRequestFrom endpointID: EndpointID, with context: Data, connectionRequestHandler: @escaping (Bool) -> Void) { + guard let endpointName = String(data: context, encoding: .utf8) else { + return + } let endpoint = DiscoveredEndpoint( id: UUID(), endpointID: endpointID, - endpointName: String(data: context, encoding: .utf8)! + endpointName: endpointName ) endpoints.insert(endpoint, at: 0) connectionRequestHandler(true) From 5695ef696d1bb9ea7c67d9a911667a5746585407 Mon Sep 17 00:00:00 2001 From: ggli-google Date: Fri, 6 Oct 2023 15:36:12 -0700 Subject: [PATCH 044/683] Compile protos --- compiled_proto/proto/connections_enums.pb.cc | 52 +++++++++++--------- compiled_proto/proto/connections_enums.pb.h | 10 ++-- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/compiled_proto/proto/connections_enums.pb.cc b/compiled_proto/proto/connections_enums.pb.cc index 20cd2d6f..76d86f05 100644 --- a/compiled_proto/proto/connections_enums.pb.cc +++ b/compiled_proto/proto/connections_enums.pb.cc @@ -656,29 +656,33 @@ bool ConnectionAttemptType_IsValid(int value) { case 0: case 1: case 2: + case 3: return true; default: return false; } } -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed ConnectionAttemptType_strings[3] = {}; +static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed ConnectionAttemptType_strings[4] = {}; static const char ConnectionAttemptType_names[] = "INITIAL" + "RECONNECT" "UNKNOWN_CONNECTION_ATTEMPT_TYPE" "UPGRADE"; static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry ConnectionAttemptType_entries[] = { { {ConnectionAttemptType_names + 0, 7}, 1 }, - { {ConnectionAttemptType_names + 7, 31}, 0 }, - { {ConnectionAttemptType_names + 38, 7}, 2 }, + { {ConnectionAttemptType_names + 7, 9}, 3 }, + { {ConnectionAttemptType_names + 16, 31}, 0 }, + { {ConnectionAttemptType_names + 47, 7}, 2 }, }; static const int ConnectionAttemptType_entries_by_number[] = { - 1, // 0 -> UNKNOWN_CONNECTION_ATTEMPT_TYPE + 2, // 0 -> UNKNOWN_CONNECTION_ATTEMPT_TYPE 0, // 1 -> INITIAL - 2, // 2 -> UPGRADE + 3, // 2 -> UPGRADE + 1, // 3 -> RECONNECT }; const std::string& ConnectionAttemptType_Name( @@ -687,12 +691,12 @@ const std::string& ConnectionAttemptType_Name( ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( ConnectionAttemptType_entries, ConnectionAttemptType_entries_by_number, - 3, ConnectionAttemptType_strings); + 4, ConnectionAttemptType_strings); (void) dummy; int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( ConnectionAttemptType_entries, ConnectionAttemptType_entries_by_number, - 3, value); + 4, value); return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : ConnectionAttemptType_strings[idx].get(); } @@ -700,7 +704,7 @@ bool ConnectionAttemptType_Parse( ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, ConnectionAttemptType* value) { int int_value; bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - ConnectionAttemptType_entries, 3, name, &int_value); + ConnectionAttemptType_entries, 4, name, &int_value); if (success) { *value = static_cast(int_value); } @@ -715,17 +719,19 @@ bool DisconnectionReason_IsValid(int value) { case 4: case 5: case 6: + case 7: return true; default: return false; } } -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed DisconnectionReason_strings[7] = {}; +static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed DisconnectionReason_strings[8] = {}; static const char DisconnectionReason_names[] = "IO_ERROR" "LOCAL_DISCONNECTION" + "PREV_CHANNEL_DISCONNECTION_IN_RECONNECT" "REMOTE_DISCONNECTION" "SHUTDOWN" "UNFINISHED" @@ -735,21 +741,23 @@ static const char DisconnectionReason_names[] = static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry DisconnectionReason_entries[] = { { {DisconnectionReason_names + 0, 8}, 3 }, { {DisconnectionReason_names + 8, 19}, 1 }, - { {DisconnectionReason_names + 27, 20}, 2 }, - { {DisconnectionReason_names + 47, 8}, 5 }, - { {DisconnectionReason_names + 55, 10}, 6 }, - { {DisconnectionReason_names + 65, 28}, 0 }, - { {DisconnectionReason_names + 93, 8}, 4 }, + { {DisconnectionReason_names + 27, 39}, 7 }, + { {DisconnectionReason_names + 66, 20}, 2 }, + { {DisconnectionReason_names + 86, 8}, 5 }, + { {DisconnectionReason_names + 94, 10}, 6 }, + { {DisconnectionReason_names + 104, 28}, 0 }, + { {DisconnectionReason_names + 132, 8}, 4 }, }; static const int DisconnectionReason_entries_by_number[] = { - 5, // 0 -> UNKNOWN_DISCONNECTION_REASON + 6, // 0 -> UNKNOWN_DISCONNECTION_REASON 1, // 1 -> LOCAL_DISCONNECTION - 2, // 2 -> REMOTE_DISCONNECTION + 3, // 2 -> REMOTE_DISCONNECTION 0, // 3 -> IO_ERROR - 6, // 4 -> UPGRADED - 3, // 5 -> SHUTDOWN - 4, // 6 -> UNFINISHED + 7, // 4 -> UPGRADED + 4, // 5 -> SHUTDOWN + 5, // 6 -> UNFINISHED + 2, // 7 -> PREV_CHANNEL_DISCONNECTION_IN_RECONNECT }; const std::string& DisconnectionReason_Name( @@ -758,12 +766,12 @@ const std::string& DisconnectionReason_Name( ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( DisconnectionReason_entries, DisconnectionReason_entries_by_number, - 7, DisconnectionReason_strings); + 8, DisconnectionReason_strings); (void) dummy; int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( DisconnectionReason_entries, DisconnectionReason_entries_by_number, - 7, value); + 8, value); return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : DisconnectionReason_strings[idx].get(); } @@ -771,7 +779,7 @@ bool DisconnectionReason_Parse( ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, DisconnectionReason* value) { int int_value; bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - DisconnectionReason_entries, 7, name, &int_value); + DisconnectionReason_entries, 8, name, &int_value); if (success) { *value = static_cast(int_value); } diff --git a/compiled_proto/proto/connections_enums.pb.h b/compiled_proto/proto/connections_enums.pb.h index 5f00902d..c7023f89 100644 --- a/compiled_proto/proto/connections_enums.pb.h +++ b/compiled_proto/proto/connections_enums.pb.h @@ -273,11 +273,12 @@ bool ConnectionAttemptDirection_Parse( enum ConnectionAttemptType : int { UNKNOWN_CONNECTION_ATTEMPT_TYPE = 0, INITIAL = 1, - UPGRADE = 2 + UPGRADE = 2, + RECONNECT = 3 }; bool ConnectionAttemptType_IsValid(int value); constexpr ConnectionAttemptType ConnectionAttemptType_MIN = UNKNOWN_CONNECTION_ATTEMPT_TYPE; -constexpr ConnectionAttemptType ConnectionAttemptType_MAX = UPGRADE; +constexpr ConnectionAttemptType ConnectionAttemptType_MAX = RECONNECT; constexpr int ConnectionAttemptType_ARRAYSIZE = ConnectionAttemptType_MAX + 1; const std::string& ConnectionAttemptType_Name(ConnectionAttemptType value); @@ -297,11 +298,12 @@ enum DisconnectionReason : int { IO_ERROR = 3, UPGRADED = 4, SHUTDOWN = 5, - UNFINISHED = 6 + UNFINISHED = 6, + PREV_CHANNEL_DISCONNECTION_IN_RECONNECT = 7 }; bool DisconnectionReason_IsValid(int value); constexpr DisconnectionReason DisconnectionReason_MIN = UNKNOWN_DISCONNECTION_REASON; -constexpr DisconnectionReason DisconnectionReason_MAX = UNFINISHED; +constexpr DisconnectionReason DisconnectionReason_MAX = PREV_CHANNEL_DISCONNECTION_IN_RECONNECT; constexpr int DisconnectionReason_ARRAYSIZE = DisconnectionReason_MAX + 1; const std::string& DisconnectionReason_Name(DisconnectionReason value); From 5d4aab0185038975e50a0c7bba62faa422410c7f Mon Sep 17 00:00:00 2001 From: Janusz Sobczak Date: Mon, 9 Oct 2023 17:46:01 +0000 Subject: [PATCH 045/683] Improve thread-safety in TaskRunnerImpl PiperOrigin-RevId: 571981130 --- internal/platform/task_runner_impl.cc | 25 ++++++++++++++++++---- internal/platform/task_runner_impl.h | 7 +++--- internal/platform/task_runner_impl_test.cc | 17 +++++++-------- 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/internal/platform/task_runner_impl.cc b/internal/platform/task_runner_impl.cc index 4892ae76..16e526f7 100644 --- a/internal/platform/task_runner_impl.cc +++ b/internal/platform/task_runner_impl.cc @@ -14,30 +14,41 @@ #include "internal/platform/task_runner_impl.h" +#include #include #include +#include "absl/container/flat_hash_map.h" #include "absl/functional/any_invocable.h" #include "absl/time/time.h" #include "internal/platform/implementation/crypto.h" +#include "internal/platform/multi_thread_executor.h" #include "internal/platform/single_thread_executor.h" +#include "internal/platform/timer.h" #include "internal/platform/timer_impl.h" namespace nearby { TaskRunnerImpl::TaskRunnerImpl(uint32_t runner_count) { if (runner_count == 1) { - executor_ = std::make_unique<::nearby::SingleThreadExecutor>(); + executor_ = std::make_unique(); } else { - executor_ = std::make_unique<::nearby::MultiThreadExecutor>(runner_count); + executor_ = std::make_unique(runner_count); } } TaskRunnerImpl::~TaskRunnerImpl() { + absl::flat_hash_map> timers; { absl::MutexLock lock(&mutex_); - timers_map_.clear(); + closed_ = true; + timers = std::move(timers_map_); } + for (auto& timer : timers) { + timer.second->Stop(); + } + // We expect that all timers are stopped, no new timers will be added, and the + // timer callbacks are not running. executor_->Shutdown(); } @@ -58,14 +69,20 @@ bool TaskRunnerImpl::PostDelayedTask(absl::Duration delay, } absl::MutexLock lock(&mutex_); + if (closed_) { + return false; + } uint64_t id = GenerateId(); std::unique_ptr timer = std::make_unique(); if (timer->Start(absl::ToInt64Milliseconds(delay), 0, [this, id, task = std::move(task)]() mutable { + absl::MutexLock lock(&mutex_); + if (closed_) { + return; + } PostTask(std::move(task)); // We can't destroy the timer directly from the timer // callback. - absl::MutexLock lock(&mutex_); auto timer = timers_map_.extract(id); PostTask([timer = std::move(timer)]() {}); })) { diff --git a/internal/platform/task_runner_impl.h b/internal/platform/task_runner_impl.h index 337a10df..0cc0c317 100644 --- a/internal/platform/task_runner_impl.h +++ b/internal/platform/task_runner_impl.h @@ -24,13 +24,13 @@ #endif #include -#include #include "absl/base/thread_annotations.h" #include "absl/container/flat_hash_map.h" #include "absl/functional/any_invocable.h" #include "absl/synchronization/mutex.h" -#include "internal/platform/multi_thread_executor.h" +#include "internal/platform/atomic_boolean.h" +#include "internal/platform/submittable_executor.h" #include "internal/platform/task_runner.h" #include "internal/platform/timer.h" @@ -50,9 +50,10 @@ class TaskRunnerImpl : public TaskRunner { uint64_t GenerateId(); mutable absl::Mutex mutex_; - std::unique_ptr<::nearby::SubmittableExecutor> executor_; + std::unique_ptr executor_; absl::flat_hash_map> timers_map_ ABSL_GUARDED_BY(mutex_); + bool closed_ ABSL_GUARDED_BY(mutex_) = false; }; } // namespace nearby diff --git a/internal/platform/task_runner_impl_test.cc b/internal/platform/task_runner_impl_test.cc index f7323ef7..ea53011a 100644 --- a/internal/platform/task_runner_impl_test.cc +++ b/internal/platform/task_runner_impl_test.cc @@ -28,9 +28,9 @@ namespace { constexpr uint32_t kNumThreads[] = {1, 10}; -class BaseTaskRunnerImplTest : public ::testing::TestWithParam {}; +class TaskRunnerImplTest : public ::testing::TestWithParam {}; -TEST_P(BaseTaskRunnerImplTest, PostTask) { +TEST_P(TaskRunnerImplTest, PostTask) { TaskRunnerImpl task_runner{GetParam()}; absl::Notification notification; bool called = false; @@ -43,7 +43,7 @@ TEST_P(BaseTaskRunnerImplTest, PostTask) { EXPECT_TRUE(called); } -TEST_F(BaseTaskRunnerImplTest, PostSequenceTasks) { +TEST_F(TaskRunnerImplTest, PostSequenceTasks) { TaskRunnerImpl task_runner{1}; std::vector completed_tasks; absl::Notification notification; @@ -71,7 +71,7 @@ TEST_F(BaseTaskRunnerImplTest, PostSequenceTasks) { EXPECT_EQ(completed_tasks[1], "task2"); } -TEST_P(BaseTaskRunnerImplTest, PostDelayedTask) { +TEST_P(TaskRunnerImplTest, PostDelayedTask) { TaskRunnerImpl task_runner{GetParam()}; std::atomic_bool first_task_started = false; CountDownLatch latch(2); @@ -91,7 +91,7 @@ TEST_P(BaseTaskRunnerImplTest, PostDelayedTask) { latch.Await(); } -TEST_P(BaseTaskRunnerImplTest, PostTwoDelayedTasks) { +TEST_P(TaskRunnerImplTest, PostTwoDelayedTasks) { TaskRunnerImpl task_runner{GetParam()}; std::atomic_bool first_task_started = false; CountDownLatch latch(2); @@ -111,7 +111,7 @@ TEST_P(BaseTaskRunnerImplTest, PostTwoDelayedTasks) { latch.Await(); } -TEST_P(BaseTaskRunnerImplTest, PostMultipleTasks) { +TEST_P(TaskRunnerImplTest, PostMultipleTasks) { TaskRunnerImpl task_runner(GetParam()); constexpr int kNumTasks = 10; CountDownLatch latch(kNumTasks); @@ -126,14 +126,13 @@ TEST_P(BaseTaskRunnerImplTest, PostMultipleTasks) { EXPECT_TRUE(latch.Await()); } -TEST_P(BaseTaskRunnerImplTest, PostEmptyTask) { +TEST_P(TaskRunnerImplTest, PostEmptyTask) { TaskRunnerImpl task_runner{GetParam()}; EXPECT_TRUE(task_runner.PostTask(nullptr)); EXPECT_TRUE(task_runner.PostDelayedTask(absl::Milliseconds(100), nullptr)); } -INSTANTIATE_TEST_SUITE_P(ParameterizedBasePcpHandlerTest, - BaseTaskRunnerImplTest, +INSTANTIATE_TEST_SUITE_P(ParameterizedTaskRunnerImplTest, TaskRunnerImplTest, ::testing::ValuesIn(kNumThreads)); } // namespace From 1d7751f581f41f73e47348c5ef5d769db1eed42c Mon Sep 17 00:00:00 2001 From: hai007 Date: Mon, 9 Oct 2023 17:46:12 +0000 Subject: [PATCH 046/683] fix auto-resume logging issue PiperOrigin-RevId: 571981185 --- connections/implementation/endpoint_channel_manager.h | 1 + connections/implementation/endpoint_manager.cc | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/connections/implementation/endpoint_channel_manager.h b/connections/implementation/endpoint_channel_manager.h index 2f7348aa..df38a538 100644 --- a/connections/implementation/endpoint_channel_manager.h +++ b/connections/implementation/endpoint_channel_manager.h @@ -28,6 +28,7 @@ #include "internal/platform/feature_flags.h" #include "internal/platform/mutex.h" #include "internal/proto/analytics/connections_log.pb.h" +#include "proto/connections_enums.pb.h" namespace nearby { namespace connections { diff --git a/connections/implementation/endpoint_manager.cc b/connections/implementation/endpoint_manager.cc index 0e61b8c1..97c393dd 100644 --- a/connections/implementation/endpoint_manager.cc +++ b/connections/implementation/endpoint_manager.cc @@ -47,6 +47,8 @@ using ::location::nearby::analytics::proto::ConnectionsLog; using ::location::nearby::connections::OfflineFrame; using ::location::nearby::connections::V1Frame; using ::nearby::analytics::PacketMetaData; +using DisconnectionReason = + ::location::nearby::proto::connections::DisconnectionReason; // We set this to 11s to provide sufficient time for an in-progress WebRTC // bandwidth upgrade to resolve. This is chosen to be slightly longer than the @@ -204,7 +206,7 @@ ExceptionOr EndpointManager::TryDecryptFrame( } auto elapsed = SystemClock::ElapsedRealtime() - start_time; if (elapsed > kDecryptRetryTimeout) { - NEARBY_LOGS(WARNING) << "Can't decrypt the mesage. Timeout after " + NEARBY_LOGS(WARNING) << "Can't decrypt the message. Timeout after " << elapsed; return Exception::kTimeout; } @@ -781,6 +783,7 @@ bool EndpointManager::ApplySafeToDisconnect(const std::string& endpoint_id, DisconnectionReason reason) { NEARBY_LOGS(INFO) << "[safe-to-disconnect] ApplySafeToDisconnect reason: " << reason; + // TODO(b/303544913): clean up the safe-to-disconnect logic bool is_safe_disconnection = false; bool send_disconnection_frame = true; absl::Duration timeout_millis = FeatureFlags::GetInstance() @@ -790,6 +793,7 @@ bool EndpointManager::ApplySafeToDisconnect(const std::string& endpoint_id, switch (reason) { case DisconnectionReason::UPGRADED: case DisconnectionReason::SHUTDOWN: + case DisconnectionReason::PREV_CHANNEL_DISCONNECTION_IN_RECONNECT: case DisconnectionReason::UNFINISHED: return true; // safe disconnection case DisconnectionReason::IO_ERROR: From eed80b2891f45912a6a738c5a295e763156ec5cd Mon Sep 17 00:00:00 2001 From: Juliet Levesque Date: Mon, 9 Oct 2023 23:13:20 +0000 Subject: [PATCH 047/683] [Nearby Presence] Cache the manager app id in PresenceDeviceProvider Cache the manager app id sent in UpdateLocalDeviceMetadata() (which is called every time the service is started up). The manager app id and the account name (which is stored in the already cached Metadata) is needed to fetch the credentials used during connection authentication. See [Anay's one pager](https://docs.google.com/document/d/1bffDNH-he4qteN3MxkbUz-P2xFoIniO088sRiTc-kkE/edit?usp=sharing) for more details. PiperOrigin-RevId: 572067964 --- presence/presence_device_provider.h | 9 +++++++++ presence/presence_device_provider_test.cc | 7 +++++++ presence/presence_service_impl.cc | 1 + 3 files changed, 17 insertions(+) diff --git a/presence/presence_device_provider.h b/presence/presence_device_provider.h index 0b63a939..6a627bdc 100644 --- a/presence/presence_device_provider.h +++ b/presence/presence_device_provider.h @@ -46,8 +46,17 @@ class PresenceDeviceProvider : public NearbyDeviceProvider { device_.SetMetadata(metadata); } + void SetManagerAppId(absl::string_view manager_app_id) { + manager_app_id_ = manager_app_id; + } + + std::string GetManagerAppId() { + return manager_app_id_; + } + private: PresenceDevice device_; + std::string manager_app_id_; }; } // namespace presence } // namespace nearby diff --git a/presence/presence_device_provider_test.cc b/presence/presence_device_provider_test.cc index 57323d8c..b7a6eb79 100644 --- a/presence/presence_device_provider_test.cc +++ b/presence/presence_device_provider_test.cc @@ -30,6 +30,7 @@ namespace { using ::nearby::internal::Metadata; constexpr absl::string_view kMacAddr = "\x4C\x8B\x1D\xCE\xBA\xD1"; +constexpr absl::string_view kManagerAppId = "test_app_id"; Metadata CreateTestMetadata() { Metadata metadata; @@ -69,6 +70,12 @@ TEST(PresenceDeviceProviderTest, DeviceProviderCanUpdateDevice) { new_metadata.SerializeAsString()); } +TEST(PresenceDeviceProviderTest, SetManagerAppId) { + PresenceDeviceProvider provider(CreateTestMetadata()); + provider.SetManagerAppId(kManagerAppId); + EXPECT_EQ(provider.GetManagerAppId(), kManagerAppId); +} + } // namespace } // namespace presence } // namespace nearby diff --git a/presence/presence_service_impl.cc b/presence/presence_service_impl.cc index eac607b3..a40eb6d1 100644 --- a/presence/presence_service_impl.cc +++ b/presence/presence_service_impl.cc @@ -62,6 +62,7 @@ void PresenceServiceImpl::UpdateLocalDeviceMetadata( int credential_life_cycle_days, int contiguous_copy_of_credentials, GenerateCredentialsResultCallback credentials_generated_cb) { provider_->UpdateMetadata(metadata); + provider_->SetManagerAppId(manager_app_id); service_controller_->UpdateLocalDeviceMetadata( metadata, regen_credentials, manager_app_id, identity_types, credential_life_cycle_days, contiguous_copy_of_credentials, From 7933f3a75e5f8444606b812a69e0dfbcc581c163 Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Wed, 11 Oct 2023 22:55:23 +0000 Subject: [PATCH 048/683] Use stable ABSL build PiperOrigin-RevId: 572711938 --- WORKSPACE | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index 76584685..5ff5e67f 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -23,8 +23,8 @@ filegroup( http_archive( name = "com_google_absl", - strip_prefix = "abseil-cpp-master", - urls = ["https://github.com/abseil/abseil-cpp/archive/master.zip"], + strip_prefix = "abseil-cpp-20230802.1", + urls = ["https://github.com/abseil/abseil-cpp/archive/refs/tags/20230802.1.zip"], ) # Using a protobuf javalite version that contains @com_google_protobuf_javalite//:javalite_toolchain From 0d8ffabe0843264c81a30640a71da3bf15a095c1 Mon Sep 17 00:00:00 2001 From: Anay Wadhera Date: Thu, 12 Oct 2023 05:03:19 +0000 Subject: [PATCH 049/683] Lock flutter_rust_bridge to 1.80.1 --- fastpair/rust/demo/rust/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fastpair/rust/demo/rust/Cargo.toml b/fastpair/rust/demo/rust/Cargo.toml index 4d736a04..e9769834 100644 --- a/fastpair/rust/demo/rust/Cargo.toml +++ b/fastpair/rust/demo/rust/Cargo.toml @@ -10,7 +10,7 @@ crate-type = ["lib", "cdylib", "staticlib"] [dependencies] bluetooth = { version = "0.1", path = "../../bluetooth" } -flutter_rust_bridge = "1" +flutter_rust_bridge = "=1.80.1" futures = { version = "0.3", features = ["executor"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" From b0ab83535f618f7240d649b4393fdc90c227b390 Mon Sep 17 00:00:00 2001 From: Anay Wadhera Date: Wed, 11 Oct 2023 22:07:21 -0700 Subject: [PATCH 050/683] silly season PiperOrigin-RevId: 572781177 --- connections/implementation/endpoint_manager.cc | 2 +- connections/implementation/endpoint_manager.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/connections/implementation/endpoint_manager.cc b/connections/implementation/endpoint_manager.cc index 97c393dd..6eeadb47 100644 --- a/connections/implementation/endpoint_manager.cc +++ b/connections/implementation/endpoint_manager.cc @@ -1,4 +1,4 @@ -// Copyright 2021 Google LLC +// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/connections/implementation/endpoint_manager.h b/connections/implementation/endpoint_manager.h index 02306ca2..2081c22c 100644 --- a/connections/implementation/endpoint_manager.h +++ b/connections/implementation/endpoint_manager.h @@ -1,4 +1,4 @@ -// Copyright 2021 Google LLC +// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. From 60735e8e2e202ab2581f33bdeba66e8c3db82062 Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Fri, 13 Oct 2023 16:50:44 -0700 Subject: [PATCH 051/683] Fixed the logic issue to handle discovered endpoint PiperOrigin-RevId: 573350212 --- .../implementation/base_pcp_handler.cc | 70 ++++++++--- .../implementation/base_pcp_handler_test.cc | 116 ++++++++++++++++++ 2 files changed, 168 insertions(+), 18 deletions(-) diff --git a/connections/implementation/base_pcp_handler.cc b/connections/implementation/base_pcp_handler.cc index efdd7c91..487b87a4 100644 --- a/connections/implementation/base_pcp_handler.cc +++ b/connections/implementation/base_pcp_handler.cc @@ -1,4 +1,4 @@ -// Copyright 2021 Google LLC +// Copyright 2021-2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ #include "connections/implementation/base_pcp_handler.h" #include +#include #include #include #include @@ -23,33 +24,55 @@ #include "securegcm/ukey2_handshake.h" #include "absl/base/thread_annotations.h" +#include "absl/container/btree_map.h" #include "absl/container/flat_hash_set.h" #include "absl/strings/escaping.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" #include "absl/time/time.h" #include "absl/types/span.h" #include "connections/advertising_options.h" #include "connections/connection_options.h" +#include "connections/discovery_options.h" +#include "connections/implementation/analytics/connection_attempt_metadata_params.h" +#include "connections/implementation/bwu_manager.h" #include "connections/implementation/client_proxy.h" +#include "connections/implementation/encryption_runner.h" +#include "connections/implementation/endpoint_channel.h" #include "connections/implementation/endpoint_channel_manager.h" +#include "connections/implementation/endpoint_manager.h" #include "connections/implementation/flags/nearby_connections_feature_flags.h" +#include "connections/implementation/mediums/mediums.h" #include "connections/implementation/mediums/utils.h" +#include "connections/implementation/mediums/webrtc_peer_id.h" #include "connections/implementation/offline_frames.h" +#include "connections/implementation/pcp.h" #include "connections/implementation/proto/offline_wire_formats.pb.h" #include "connections/listeners.h" #include "connections/medium_selector.h" +#include "connections/out_of_band_connection_metadata.h" +#include "connections/params.h" #include "connections/status.h" #include "connections/v3/connection_listening_options.h" #include "connections/v3/listeners.h" #include "internal/flags/nearby_flags.h" #include "internal/interop/device.h" #include "internal/platform/base64_utils.h" +#include "internal/platform/bluetooth_adapter.h" #include "internal/platform/bluetooth_connection_info.h" #include "internal/platform/bluetooth_utils.h" +#include "internal/platform/byte_array.h" #include "internal/platform/cancelable_alarm.h" #include "internal/platform/connection_info.h" #include "internal/platform/count_down_latch.h" +#include "internal/platform/exception.h" +#include "internal/platform/feature_flags.h" #include "internal/platform/future.h" #include "internal/platform/logging.h" +#include "internal/platform/mutex_lock.h" +#include "internal/platform/prng.h" +#include "internal/platform/runnable.h" +#include "internal/platform/wifi.h" #include "internal/platform/wifi_lan_connection_info.h" #include "proto/connections_enums.pb.h" @@ -1363,21 +1386,29 @@ void BasePcpHandler::OnEndpointFound( ClientProxy* client, std::shared_ptr endpoint) { // Check if we've seen this endpoint ID before. std::string& endpoint_id = endpoint->endpoint_id; - NEARBY_LOGS(INFO) << "OnEndpointFound: id=" << endpoint_id << " [enter]"; + NEARBY_LOGS(INFO) << "OnEndpointFound: id=" << endpoint_id << ", medium=" + << location::nearby::proto::connections::Medium_Name( + endpoint->medium) + << " [enter]"; MutexLock lock(&discovered_endpoint_mutex_); auto range = discovered_endpoints_.equal_range(endpoint->endpoint_id); bool is_range_empty = range.first == range.second; DiscoveredEndpoint* owned_endpoint = nullptr; for (auto& item = range.first; item != range.second; ++item) { auto& discovered_endpoint = item->second; - if (discovered_endpoint->medium != endpoint->medium) continue; - // Check if there was a info change. If there was, report the previous - // endpoint as lost. if (discovered_endpoint->endpoint_info != endpoint->endpoint_info) { - owned_endpoint = discovered_endpoint.get(); - client->OnEndpointLost(owned_endpoint->service_id, - owned_endpoint->endpoint_id); - discovered_endpoints_.erase(item); + // Endpoint info should be same for an endpoint ID. If it is changed, + // we should reset discovered endpoints of the endpoint ID, and use the + // new endpoint info and medium as discovered endpoint. + NEARBY_LOGS(INFO) << "Endpoint info of endpoint " << endpoint_id + << " changed on medium " + << location::nearby::proto::connections::Medium_Name( + endpoint->medium); + // Report endpoint lost + client->OnEndpointLost(endpoint->service_id, endpoint->endpoint_id); + // Reset discovered endpoints + discovered_endpoints_.erase(item->first); + // Add the endpoint as discovered endpoint. owned_endpoint = discovered_endpoints_.emplace(endpoint_id, std::move(endpoint)) ->second.get(); @@ -1387,17 +1418,19 @@ void BasePcpHandler::OnEndpointFound( owned_endpoint->service_id, owned_endpoint->endpoint_id, owned_endpoint->endpoint_info, owned_endpoint->medium); return; - } else { - owned_endpoint = endpoint.get(); - break; + } + if (discovered_endpoint->medium == endpoint->medium) { + NEARBY_LOGS(INFO) << "Ignore the dup endpoint info on medium " + << location::nearby::proto::connections::Medium_Name( + endpoint->medium); + return; } } - if (!owned_endpoint) { - owned_endpoint = - discovered_endpoints_.emplace(endpoint_id, std::move(endpoint)) - ->second.get(); - } + owned_endpoint = + discovered_endpoints_.emplace(endpoint_id, std::move(endpoint)) + ->second.get(); + NEARBY_LOGS(INFO) << "Adding new medium for endpoint: endpoint_id=" << endpoint_id << "; medium=" << location::nearby::proto::connections::Medium_Name( @@ -1443,7 +1476,8 @@ void BasePcpHandler::OnEndpointLost( << absl::BytesToHexString( discovered_endpoint->endpoint_info.data()); } - NEARBY_LOGS(INFO) << "Erase Endpoint with Meduim: " + NEARBY_LOGS(INFO) << "Erase Endpoint " << endpoint.endpoint_id + << " on Medium " << location::nearby::proto::connections::Medium_Name( discovered_endpoint->medium); if (--count == 0) { diff --git a/connections/implementation/base_pcp_handler_test.cc b/connections/implementation/base_pcp_handler_test.cc index 535a1a74..cab92ff0 100644 --- a/connections/implementation/base_pcp_handler_test.cc +++ b/connections/implementation/base_pcp_handler_test.cc @@ -1601,6 +1601,122 @@ TEST_F(BasePcpHandlerTest, InjectEndpoint) { env_.Stop(); } +TEST_F(BasePcpHandlerTest, + TestEndpointInfoChangedWhenEndpointDiscoveredOnMultipleMediums) { + env_.Start(); + std::string service_id{"service"}; + std::string endpoint_id{"ABCD"}; + ClientProxy client; + Mediums m; + EndpointChannelManager ecm; + EndpointManager em(&ecm); + BwuManager bwu(m, em, ecm, {}, {}); + MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); + BooleanMediumSelector allowed{ + .bluetooth = true, + .ble = true, + }; + DiscoveryOptions discovery_options{ + { + Strategy::kP2pPointToPoint, + allowed, + }, + false, // auto_upgrade_bandwidth; + false, // enforce_topology_constraints; + }; + + EXPECT_CALL(pcp_handler, StartDiscoveryImpl) + .WillOnce(Return(MockPcpHandler::StartOperationResult{ + .status = {Status::kSuccess}, + .mediums = allowed.GetMediums(true), + })); + + EXPECT_EQ(pcp_handler.StartDiscovery(&client, service_id, discovery_options, + GetDiscoveryListener()), + Status{Status::kSuccess}); + EXPECT_TRUE(client.IsDiscovering()); + + ::testing::InSequence seq; + EXPECT_CALL(mock_discovery_listener_.endpoint_found_cb, Call) + .WillOnce(Invoke([id = endpoint_id](const std::string& endpoint_id, + const ByteArray& endpoint_info, + const std::string& service_id) { + EXPECT_EQ(endpoint_id, id); + EXPECT_EQ(endpoint_info, ByteArray{"ABCD"}); + })); + + EXPECT_CALL(mock_discovery_listener_.endpoint_lost_cb, Call) + .WillOnce(Invoke([id = endpoint_id](const std::string& endpoint_id) { + EXPECT_EQ(endpoint_id, id); + })); + + EXPECT_CALL(mock_discovery_listener_.endpoint_found_cb, Call) + .WillOnce(Invoke([id = endpoint_id](const std::string& endpoint_id, + const ByteArray& endpoint_info, + const std::string& service_id) { + EXPECT_EQ(endpoint_id, id); + EXPECT_EQ(endpoint_info, ByteArray{"ABCDEF"}); + })); + + EXPECT_CALL(mock_discovery_listener_.endpoint_lost_cb, Call) + .WillOnce(Invoke([id = endpoint_id](const std::string& endpoint_id) { + EXPECT_EQ(endpoint_id, id); + })); + + // Found endpoint on Bluetooth + pcp_handler.OnEndpointFound( + &client, std::make_shared(MockDiscoveredEndpoint{ + { + endpoint_id, + /*endpoint_info=*/ByteArray{"ABCD"}, + service_id, + Medium::BLUETOOTH, + WebRtcState::kUndefined, + }, + MockContext{nullptr}, + })); + // Found endpoint on BLE + pcp_handler.OnEndpointFound( + &client, std::make_shared(MockDiscoveredEndpoint{ + { + endpoint_id, + /*endpoint_info=*/ByteArray{"ABCD"}, + service_id, + Medium::BLE, + WebRtcState::kUndefined, + }, + MockContext{nullptr}, + })); + + // Endpoint info changed on BLE + pcp_handler.OnEndpointFound( + &client, std::make_shared(MockDiscoveredEndpoint{ + { + endpoint_id, + /*endpoint_info=*/ByteArray{"ABCDEF"}, + service_id, + Medium::BLE, + WebRtcState::kUndefined, + }, + MockContext{nullptr}, + })); + + pcp_handler.OnEndpointLost(&client, + MockDiscoveredEndpoint{ + { + endpoint_id, + /*endpoint_info=*/ByteArray{"ABCDEF"}, + service_id, + Medium::BLE, + WebRtcState::kUndefined, + }, + MockContext{nullptr}, + }); + + env_.Sync(false); + env_.Stop(); +} + TEST_F(BasePcpHandlerTest, TestStartStopEndpointLostAlarm) { env_.Start(); std::string service_id{"service"}; From 9b0f46a2da7a29be5361e5572eca63bb5c8c1abe Mon Sep 17 00:00:00 2001 From: hai007 Date: Mon, 16 Oct 2023 16:25:38 -0700 Subject: [PATCH 052/683] Internal change. PiperOrigin-RevId: 573961794 --- proto/sharing_enums.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proto/sharing_enums.proto b/proto/sharing_enums.proto index 849993b4..57858776 100644 --- a/proto/sharing_enums.proto +++ b/proto/sharing_enums.proto @@ -779,7 +779,7 @@ enum FastInitType { FAST_INIT_SILENT_TYPE = 2; } -// LINT.IfChanged +// LINT.IfChange /** The type of desktop notification event. */ enum DesktopNotification { DESKTOP_NOTIFICATION_UNKNOWN = 0; From d7069843306783f8af4a44145820ed996d1374a2 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Tue, 24 Oct 2023 14:57:03 -0700 Subject: [PATCH 053/683] [Sharing] add an enum value for SYNC_PURPOSE. PiperOrigin-RevId: 576294050 --- proto/sharing_enums.proto | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proto/sharing_enums.proto b/proto/sharing_enums.proto index 57858776..fb128bbb 100644 --- a/proto/sharing_enums.proto +++ b/proto/sharing_enums.proto @@ -565,6 +565,8 @@ enum SyncPurpose { SYNC_PURPOSE_ACCOUNT_CHANGE = 15; // When regenerate certificates SYNC_PURPOSE_REGENERATE_CERTIFICATES = 16; + // When Device Contacts consent changes + SYNC_PURPOSE_DEVICE_CONTACTS_CONSENT_CHANGE = 17; } // The device role to trigger the server request. From f93959fd15359ca4d0fc98b5c61a75e2c54a294e Mon Sep 17 00:00:00 2001 From: Hai Shang Date: Tue, 24 Oct 2023 16:59:58 -0700 Subject: [PATCH 054/683] Add more logs for BT. PiperOrigin-RevId: 576329921 --- internal/platform/bluetooth_classic.cc | 36 +++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/internal/platform/bluetooth_classic.cc b/internal/platform/bluetooth_classic.cc index df8b1157..3f313f4b 100644 --- a/internal/platform/bluetooth_classic.cc +++ b/internal/platform/bluetooth_classic.cc @@ -20,23 +20,28 @@ namespace nearby { BluetoothClassicMedium::~BluetoothClassicMedium() { + NEARBY_LOG(INFO, "~BluetoothClassicMedium: observer_list_ size: %d", + observer_list_.size()); if (!observer_list_.empty()) { impl_->RemoveObserver(this); } StopDiscovery(); + NEARBY_LOG(INFO, "eof ~BluetoothClassicMedium"); } BluetoothSocket BluetoothClassicMedium::ConnectToService( BluetoothDevice& remote_device, const std::string& service_uuid, CancellationFlag* cancellation_flag) { NEARBY_LOG(INFO, - "BluetoothClassicMedium::ConnectToService: device=%p [impl=%p]", - &remote_device, &remote_device.GetImpl()); + "BluetoothClassicMedium::ConnectToService: service_uuid=%p, " + "device=%p, [impl=%p]", + service_uuid.c_str(), &remote_device, &remote_device.GetImpl()); return BluetoothSocket(impl_->ConnectToService( remote_device.GetImpl(), service_uuid, cancellation_flag)); } bool BluetoothClassicMedium::StartDiscovery(DiscoveryCallback callback) { + NEARBY_LOG(INFO, "BluetoothClassicMedium::StartDiscovery"); MutexLock lock(&mutex_); if (discovery_enabled_) { NEARBY_LOG(INFO, "BT Discovery already enabled; impl=%p", &GetImpl()); @@ -45,6 +50,8 @@ bool BluetoothClassicMedium::StartDiscovery(DiscoveryCallback callback) { bool success = impl_->StartDiscovery({ .device_discovered_cb = [this](api::BluetoothDevice& device) { + NEARBY_LOG(VERBOSE, "BT .device_discovered_cb for %p", + device.GetName().c_str()); MutexLock lock(&mutex_); auto pair = devices_.emplace( &device, absl::make_unique()); @@ -62,6 +69,8 @@ bool BluetoothClassicMedium::StartDiscovery(DiscoveryCallback callback) { }, .device_name_changed_cb = [this](api::BluetoothDevice& device) { + NEARBY_LOG(VERBOSE, "BT .device_name_changed_cb for %p", + device.GetName().c_str()); MutexLock lock(&mutex_); // If the device is not already in devices_, we should not be able // to change its name. @@ -74,6 +83,8 @@ bool BluetoothClassicMedium::StartDiscovery(DiscoveryCallback callback) { }, .device_lost_cb = [this](api::BluetoothDevice& device) { + NEARBY_LOG(VERBOSE, "BT .device_lost_cb for %p", + device.GetName().c_str()); MutexLock lock(&mutex_); auto item = devices_.extract(&device); if (!item) { @@ -92,12 +103,13 @@ bool BluetoothClassicMedium::StartDiscovery(DiscoveryCallback callback) { discovery_callback_ = std::move(callback); devices_.clear(); discovery_enabled_ = true; - NEARBY_LOG(INFO, "BT Discovery enabled; impl=%p", &GetImpl()); } + NEARBY_LOG(INFO, "BT StartDiscovery result:%d; impl=%p", success, &GetImpl()); return success; } bool BluetoothClassicMedium::StopDiscovery() { + NEARBY_LOG(INFO, "BT StopDiscovery; impl=%p", &GetImpl()); MutexLock lock(&mutex_); if (!discovery_enabled_) return true; discovery_enabled_ = false; @@ -108,28 +120,36 @@ bool BluetoothClassicMedium::StopDiscovery() { } void BluetoothClassicMedium::AddObserver(Observer* observer) { + NEARBY_LOG(INFO, "BT AddObserver; impl=%p", &GetImpl()); MutexLock lock(&mutex_); if (observer_list_.empty()) { impl_->AddObserver(this); } observer_list_.AddObserver(observer); + NEARBY_LOG(INFO, "BT AddObserver done"); } void BluetoothClassicMedium::RemoveObserver(Observer* observer) { + NEARBY_LOG(INFO, "BT RemoveObserver; impl=%p", &GetImpl()); MutexLock lock(&mutex_); observer_list_.RemoveObserver(observer); if (observer_list_.empty()) { impl_->RemoveObserver(this); } + NEARBY_LOG(INFO, "BT RemoveObserver done"); } // api::BluetoothClassicMedium::Observer methods void BluetoothClassicMedium::DeviceAdded(api::BluetoothDevice& device) { + NEARBY_LOG(VERBOSE, "BT DeviceAdded; name=%p, address=%p", + device.GetName().c_str(), device.GetMacAddress().c_str()); BluetoothDevice bt_device(&device); for (auto* observer : observer_list_.GetObservers()) { observer->DeviceAdded(bt_device); } } void BluetoothClassicMedium::DeviceRemoved(api::BluetoothDevice& device) { + NEARBY_LOG(VERBOSE, "BT DeviceRemoved; name=%p, address=%p", + device.GetName().c_str(), device.GetMacAddress().c_str()); BluetoothDevice bt_device(&device); for (auto* observer : observer_list_.GetObservers()) { observer->DeviceRemoved(bt_device); @@ -137,6 +157,9 @@ void BluetoothClassicMedium::DeviceRemoved(api::BluetoothDevice& device) { } void BluetoothClassicMedium::DeviceAddressChanged( api::BluetoothDevice& device, absl::string_view old_address) { + NEARBY_LOG( + VERBOSE, "BT DeviceAddressChanged; name=%p, address=%p, old_address=%p", + device.GetName().c_str(), device.GetMacAddress().c_str(), old_address); BluetoothDevice bt_device(&device); for (auto* observer : observer_list_.GetObservers()) { observer->DeviceAddressChanged(bt_device, old_address); @@ -144,6 +167,9 @@ void BluetoothClassicMedium::DeviceAddressChanged( } void BluetoothClassicMedium::DevicePairedChanged(api::BluetoothDevice& device, bool new_paired_status) { + NEARBY_LOG(VERBOSE, "BT DevicePairedChanged; name=%p, address=%p, status=%d", + device.GetName().c_str(), device.GetMacAddress().c_str(), + new_paired_status); BluetoothDevice bt_device(&device); for (auto* observer : observer_list_.GetObservers()) { observer->DevicePairedChanged(bt_device, new_paired_status); @@ -151,6 +177,10 @@ void BluetoothClassicMedium::DevicePairedChanged(api::BluetoothDevice& device, } void BluetoothClassicMedium::DeviceConnectedStateChanged( api::BluetoothDevice& device, bool connected) { + NEARBY_LOG( + VERBOSE, + "BT DeviceConnectedStateChanged: name=%p, address=%p, connected=%d", + device.GetName().c_str(), device.GetMacAddress().c_str(), connected); BluetoothDevice bt_device(&device); for (auto* observer : observer_list_.GetObservers()) { observer->DeviceConnectedStateChanged(bt_device, connected); From 629e7ba7c964a62c97f6a882bffaec3c8490bb1e Mon Sep 17 00:00:00 2001 From: hai007 Date: Wed, 25 Oct 2023 11:33:42 -0700 Subject: [PATCH 055/683] Disable Intel PIE for github Opensource repo PiperOrigin-RevId: 576593321 --- .../platform/implementation/windows/BUILD | 7 ++++-- .../implementation/windows/wifi_intel.cc | 23 +++++++++++++++++-- .../implementation/windows/wifi_intel.h | 11 +++++++-- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/internal/platform/implementation/windows/BUILD b/internal/platform/implementation/windows/BUILD index e58ad6a9..dbacfd8e 100644 --- a/internal/platform/implementation/windows/BUILD +++ b/internal/platform/implementation/windows/BUILD @@ -105,6 +105,7 @@ cc_library( "wifi_intel.h", "wifi_lan.h", ], + copts = ["-DNO_INTEL_PIE"], visibility = ["//visibility:private"], deps = [ "//internal/platform:base", @@ -114,7 +115,6 @@ cc_library( "//internal/platform/implementation:comm", "//internal/platform/implementation:types", "//internal/platform/implementation/windows/generated:types", - "//third_party/intel/pie", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/container:flat_hash_set", @@ -189,7 +189,10 @@ cc_library( ], # This is the temporary solution to solve compilation error of Win32 WFDxxx() related API. # WFD API is only support after _WIN32_WINNT_WIN8, but the current lexan _WIN32_WINNT is set to _WIN32_WINNT_WIN7 - copts = ["-Ithird_party/nearby/internal/platform/implementation/windows/generated -D_WIN32_WINNT=_WIN32_WINNT_WIN10 -DWINVER=_WIN32_WINNT_WIN10"], + copts = [ + "-DNO_INTEL_PIE", + "-Ithird_party/nearby/internal/platform/implementation/windows/generated -D_WIN32_WINNT=_WIN32_WINNT_WIN10 -DWINVER=_WIN32_WINNT_WIN10", + ], defines = ["_SILENCE_CLANG_COROUTINE_MESSAGE"], visibility = [ "//connections:__subpackages__", diff --git a/internal/platform/implementation/windows/wifi_intel.cc b/internal/platform/implementation/windows/wifi_intel.cc index 688b09fb..432c1a3d 100644 --- a/internal/platform/implementation/windows/wifi_intel.cc +++ b/internal/platform/implementation/windows/wifi_intel.cc @@ -32,11 +32,13 @@ #include #include +#ifndef NO_INTEL_PIE #include "absl/strings/str_format.h" #include "third_party/intel/pie/include/PieApiTypes.h" #include "third_party/intel/pie/include/PieDefinitions.h" #include "third_party/intel/pie/include/PieErrorMacro.h" #include "internal/platform/logging.h" +#endif namespace nearby { namespace windows { @@ -81,12 +83,14 @@ namespace { } \ } +#ifndef NO_INTEL_PIE #define PIE_API_DLL L"\\MurocApi.dll" #define ERROR_ const wchar_t PIE_HW_ID_[] = L"SWC\\VID_8086&PID_PIE&SID_0001\0"; const wchar_t PIE_DLL_PATH_HINT[] = L"PiePathHint"; +#endif } // namespace - +#ifndef NO_INTEL_PIE typedef MUROC_RET(APIENTRY* WIFIGETADAPTERLIST)( // NOLINT PINTEL_WIFI_HEADER pHeader, void** pAdapterList); typedef MUROC_RET(APIENTRY* REGISTERINTELCB)( @@ -124,6 +128,7 @@ void WINAPI IntelEventHandler(MurocDefs::INTEL_EVENT iEvent, // NOLINT // because the CB comes from another thread MurocDefs::INTEL_CALLBACK g_intel_event_cb_handle = {IntelEventHandler, nullptr}; +#endif WifiIntel& WifiIntel::GetInstance() { static std::aligned_storage_t storage; @@ -133,6 +138,7 @@ WifiIntel& WifiIntel::GetInstance() { void WifiIntel::Start() { NEARBY_LOGS(INFO) << "WifiIntel::Start()"; +#ifndef NO_INTEL_PIE muroc_api_dll_handle_ = PIEDllLoader(); if ((muroc_api_dll_handle_ != nullptr)) { NEARBY_LOGS(INFO) << "Load PIE_API_DLL completed successfully"; @@ -146,10 +152,14 @@ void WifiIntel::Start() { SAFEFREELIBRARY(muroc_api_dll_handle_); } } +#else + NEARBY_LOGS(INFO) << "NO_INTEL_PIE found, skip"; +#endif } void WifiIntel::Stop() { NEARBY_LOGS(INFO) << "WifiIntel::Stop()"; +#ifndef NO_INTEL_PIE if (intel_wifi_valid_) { NEARBY_LOGS(INFO) << "Deregister Intel Callback, free Adapters Memory " "List, free Muroc Api Dll handler."; @@ -157,9 +167,13 @@ void WifiIntel::Stop() { FreeMemoryList(muroc_api_dll_handle_, p_all_adapters_); SAFEFREELIBRARY(muroc_api_dll_handle_); } +#else + NEARBY_LOGS(INFO) << "NO_INTEL_PIE found, skip"; +#endif } uint8_t WifiIntel::GetGOChannel() { +#ifndef NO_INTEL_PIE WIFIPANQUERYPREFFEDCHANNELSETTING WifiPanQueryPreferredChannelSettingFunc = nullptr; uint8_t channel = 0; @@ -205,8 +219,13 @@ uint8_t WifiIntel::GetGOChannel() { } return channel; +#else + NEARBY_LOGS(INFO) << "NO_INTEL_PIE found, return -1"; + return -1; +#endif } +#ifndef NO_INTEL_PIE wchar_t* GetEntireRegistryDeviceList() { CONFIGRET configRet = CR_SUCCESS; wchar_t* pDeviceList = nullptr; @@ -573,6 +592,6 @@ void FreeMemoryList(HINSTANCE murocApiDllHandle, void* ptr) { } } } - +#endif } // namespace windows } // namespace nearby diff --git a/internal/platform/implementation/windows/wifi_intel.h b/internal/platform/implementation/windows/wifi_intel.h index c7995aad..03562b12 100644 --- a/internal/platform/implementation/windows/wifi_intel.h +++ b/internal/platform/implementation/windows/wifi_intel.h @@ -18,18 +18,22 @@ // clang-format off #include #include +#include // clang-format on // Intel WIFI PIE headers +#ifndef NO_INTEL_PIE #include "third_party/intel/pie/include/IntelSdkVersionInfo.h" #include "third_party/intel/pie/include/PieApiErrors.h" #include "third_party/intel/pie/include/PieDefinitions.h" +#endif #include "internal/platform/logging.h" namespace nearby { namespace windows { - +#ifndef NO_INTEL_PIE using ::MurocDefs::PINTEL_ADAPTER_LIST_V120; +#endif // Container of Intel WIFI to utilize Intel PIE SDK API class WifiIntel { @@ -42,6 +46,7 @@ class WifiIntel { void Start(); void Stop(); uint8_t GetGOChannel(); + private: // This is a singleton object, for which destructor will never be called. // Constructor will be invoked once from Instance() static method. @@ -50,12 +55,14 @@ class WifiIntel { WifiIntel() = default; ~WifiIntel() = default; +#ifndef NO_INTEL_PIE HINSTANCE PIEDllLoader(); - bool intel_wifi_valid_ = false; HINSTANCE muroc_api_dll_handle_ = nullptr; HADAPTER wifi_adapter_handle_ = 0; PINTEL_ADAPTER_LIST_V120 p_all_adapters_ = nullptr; +#endif + bool intel_wifi_valid_ = false; }; } // namespace windows From c1e5f47e3f35521debdcbb4c675ebccf3ea9b28a Mon Sep 17 00:00:00 2001 From: hai007 Date: Wed, 25 Oct 2023 19:44:15 -0700 Subject: [PATCH 056/683] [Analytics] Add analytics for subsequent pairing but entering pairing mode Add is_in_paired_history field when the event is SECRET_HANDSHAKE LOG_STORAGE_INCREASE(GB/week): <1 1200000 perday * 7 days * (2+1 [tag+bool] + 2+8 [tag+int64] + 2+8 [tag+int64] + 2+1 [tag+bool]) bytes/record Single record size (average): 26 bytes PiperOrigin-RevId: 576717056 --- internal/proto/analytics/fast_pair_log.proto | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/internal/proto/analytics/fast_pair_log.proto b/internal/proto/analytics/fast_pair_log.proto index cfea1892..38897940 100644 --- a/internal/proto/analytics/fast_pair_log.proto +++ b/internal/proto/analytics/fast_pair_log.proto @@ -169,4 +169,13 @@ message FastPairLog { optional int32 sass_connection_state = 22; optional bool is_pair_triggered_by_settings = 23; + + // The nearby mainline tethering module version. + optional int64 nearby_mainline_tethering_version = 24; + + // The nearby nano app version for offload. + optional int64 nearby_nano_app_version = 25; + + // For the SECRET_HANDSHAKE event, is the pairing device in paired history. + optional bool is_in_paired_history = 26; } From 42043ee856d2f26bc9ea0c9894162276d56b5f73 Mon Sep 17 00:00:00 2001 From: hai007 Date: Tue, 31 Oct 2023 23:19:40 -0700 Subject: [PATCH 057/683] Add more log for Intel PIE API calling PiperOrigin-RevId: 578409693 --- .../platform/implementation/windows/wifi_hotspot_medium.cc | 6 +++++- internal/platform/implementation/windows/wifi_intel.cc | 7 ++++--- internal/platform/implementation/windows/wifi_intel.h | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/internal/platform/implementation/windows/wifi_hotspot_medium.cc b/internal/platform/implementation/windows/wifi_hotspot_medium.cc index a7108a21..e8d61d3e 100644 --- a/internal/platform/implementation/windows/wifi_hotspot_medium.cc +++ b/internal/platform/implementation/windows/wifi_hotspot_medium.cc @@ -263,12 +263,16 @@ bool WifiHotspotMedium::StartWifiHotspot( WifiIntel& intel_wifi{WifiIntel::GetInstance()}; intel_wifi.Start(); int GO_channel = static_cast(intel_wifi.GetGOChannel()); - NEARBY_LOGS(INFO) << "Hotspot is running on channel: " << GO_channel; + NEARBY_LOGS(INFO) + << "Intel PIE enabled, Hotspot is running on channel: " + << GO_channel; intel_wifi.Stop(); hotspot_credentials_->SetFrequency( WifiUtils::ConvertChannelToFrequencyMhz(GO_channel, WifiBandType::kUnknown)); } else { + NEARBY_LOGS(INFO) + << "Intel PIE disabled, Can't extract Hotspot channel info!"; hotspot_credentials_->SetFrequency(-1); } return true; diff --git a/internal/platform/implementation/windows/wifi_intel.cc b/internal/platform/implementation/windows/wifi_intel.cc index 432c1a3d..8517826d 100644 --- a/internal/platform/implementation/windows/wifi_intel.cc +++ b/internal/platform/implementation/windows/wifi_intel.cc @@ -34,6 +34,7 @@ #ifndef NO_INTEL_PIE #include "absl/strings/str_format.h" +#include "third_party/intel/pie/include/PieApiErrors.h" #include "third_party/intel/pie/include/PieApiTypes.h" #include "third_party/intel/pie/include/PieDefinitions.h" #include "third_party/intel/pie/include/PieErrorMacro.h" @@ -172,11 +173,11 @@ void WifiIntel::Stop() { #endif } -uint8_t WifiIntel::GetGOChannel() { +int8_t WifiIntel::GetGOChannel() { #ifndef NO_INTEL_PIE WIFIPANQUERYPREFFEDCHANNELSETTING WifiPanQueryPreferredChannelSettingFunc = nullptr; - uint8_t channel = 0; + int8_t channel = -1; DWORD dwError = ERROR_SUCCESS; // NOLINT MUROC_RET murocApiRetVal = IWLAN_E_FAILURE; // NOLINT INTEL_WIFI_HEADER intelWifiHeader; @@ -210,7 +211,7 @@ uint8_t WifiIntel::GetGOChannel() { if (intelGOChan.goState == MurocDefs::INTEL_GO_CURRENT_CHANNEL_ACTIVE) { channel = intelGOChan.channel; } else { - NEARBY_LOGS(INFO) << "No active GO found, return 0"; + NEARBY_LOGS(INFO) << "No active GO found, return -1"; } } else { NEARBY_LOGS(INFO) << "Calling WifiPanQueryPreferredChannelSetting API " diff --git a/internal/platform/implementation/windows/wifi_intel.h b/internal/platform/implementation/windows/wifi_intel.h index 03562b12..577df76f 100644 --- a/internal/platform/implementation/windows/wifi_intel.h +++ b/internal/platform/implementation/windows/wifi_intel.h @@ -45,7 +45,7 @@ class WifiIntel { bool IsValid() const { return intel_wifi_valid_; } void Start(); void Stop(); - uint8_t GetGOChannel(); + int8_t GetGOChannel(); private: // This is a singleton object, for which destructor will never be called. From 5dacb56a0c85f90455cea9b0b9068f3feb7263ac Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Thu, 2 Nov 2023 19:56:39 -0700 Subject: [PATCH 058/683] [Connections] Impl to auto connect once the auth compound result is FAILURE. PiperOrigin-RevId: 579049556 --- proto/connections_enums.proto | 1 + 1 file changed, 1 insertion(+) diff --git a/proto/connections_enums.proto b/proto/connections_enums.proto index 6873d7dc..ccc7aa7d 100644 --- a/proto/connections_enums.proto +++ b/proto/connections_enums.proto @@ -170,6 +170,7 @@ enum DisconnectionReason { SHUTDOWN = 5; UNFINISHED = 6; PREV_CHANNEL_DISCONNECTION_IN_RECONNECT = 7; + AUTHENTICATION_FAILURE = 8; } // The type of a Payload. From 3d11defc4a4392e7986bc15bd4979770353cd7d4 Mon Sep 17 00:00:00 2001 From: Anthony Rueda Date: Wed, 8 Nov 2023 20:15:33 -0800 Subject: [PATCH 059/683] [Presence] Add device ID to `DeviceIdentityMetaData` PiperOrigin-RevId: 580758850 --- internal/proto/metadata.proto | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/proto/metadata.proto b/internal/proto/metadata.proto index b341e200..ec4efbe4 100644 --- a/internal/proto/metadata.proto +++ b/internal/proto/metadata.proto @@ -38,6 +38,10 @@ message DeviceIdentityMetaData { // The instance type (user profile) related to the metadata. InstanceType instance_type = 4; + + // The device_id from the MultideviceParameters file of the broadcasting + // device + bytes device_id = 5; } // The metadata of a device. From a83fbe3ebb47980e204c39cf23f20813e2048a2f Mon Sep 17 00:00:00 2001 From: hai007 Date: Wed, 8 Nov 2023 21:33:53 -0800 Subject: [PATCH 060/683] Correct event types for SendDesktopNotification and SendDesktopTransferEvent PiperOrigin-RevId: 580773405 --- proto/sharing_enums.proto | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/proto/sharing_enums.proto b/proto/sharing_enums.proto index fb128bbb..bb2fa688 100644 --- a/proto/sharing_enums.proto +++ b/proto/sharing_enums.proto @@ -30,7 +30,7 @@ option objc_class_prefix = "GNSHP"; // in NearbyClearcutLogger (for android, or clearcut_event_logger as the // equivalence for Windows) for all events (may exclude settings), and // session_id for a pair of events (start and end of a session). -// Next id: 66 +// Next id: 67 enum EventType { UNKNOWN_EVENT_TYPE = 0; @@ -241,6 +241,10 @@ enum EventType { // Show allow permission auto access UI SHOW_ALLOW_PERMISSION_AUTO_ACCESS = 65; + // UI events for transferring files with desktop applications. It includes + // event types such as DESKTOP_TRANSFER_EVENT_SEND_TYPE_SELECT_A_DEVICE. + SEND_DESKTOP_TRANSFER_EVENT = 66; + // LINT.ThenChange(//depot/google3/location/nearby/proto/nearby_event_codes.proto:SharingEventCode) } From e876b68d90b6ce420f20ab49f84b253fbe4d71c2 Mon Sep 17 00:00:00 2001 From: hai007 Date: Wed, 15 Nov 2023 19:01:30 -0800 Subject: [PATCH 061/683] 1. log client_flow_id into ClientSession 2. In NS, passing the saved advertising flow id into NC so the client_flow_id in receiver side could be the same as the NS one, which could have the correct records mapping between the NS and NC. PiperOrigin-RevId: 582876537 --- internal/proto/analytics/connections_log.proto | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/proto/analytics/connections_log.proto b/internal/proto/analytics/connections_log.proto index e2e194c7..68c1f0d0 100644 --- a/internal/proto/analytics/connections_log.proto +++ b/internal/proto/analytics/connections_log.proto @@ -63,6 +63,9 @@ message ConnectionsLog { // Zero or more StrategySessions. repeated StrategySession strategy_session = 2; + + // The client session flow id. + optional int64 client_flow_id = 3 /* type = ST_SESSION_ID */; } // One round of a particular Strategy done by a client. From 41a2821099953ebe4321807d06b6848958c77af2 Mon Sep 17 00:00:00 2001 From: Crisrael Lucero Date: Thu, 16 Nov 2023 22:13:47 -0800 Subject: [PATCH 062/683] Create PresenceDevice constructor that takes in an endpoint ID PiperOrigin-RevId: 583266968 --- presence/presence_device.cc | 4 ++++ presence/presence_device.h | 2 ++ presence/presence_device_test.cc | 6 ++++++ 3 files changed, 12 insertions(+) diff --git a/presence/presence_device.cc b/presence/presence_device.cc index afbec278..4e246b45 100644 --- a/presence/presence_device.cc +++ b/presence/presence_device.cc @@ -17,6 +17,7 @@ #include #include +#include "absl/strings/string_view.h" #include "absl/types/variant.h" #include "connections/implementation/proto/offline_wire_formats.pb.h" #include "internal/interop/device.h" @@ -91,6 +92,9 @@ int ConvertToAndroidIdentityType(nearby::internal::IdentityType identity_type) { } } // namespace +PresenceDevice::PresenceDevice(absl::string_view endpoint_id) noexcept + : endpoint_id_(endpoint_id) {} + PresenceDevice::PresenceDevice(Metadata metadata) noexcept : discovery_timestamp_(nearby::SystemClock::ElapsedRealtime()), device_motion_(DeviceMotion()), diff --git a/presence/presence_device.h b/presence/presence_device.h index 231ecffb..0acc331d 100644 --- a/presence/presence_device.h +++ b/presence/presence_device.h @@ -18,6 +18,7 @@ #include #include +#include "absl/strings/string_view.h" #include "absl/time/time.h" #include "internal/interop/device.h" #include "internal/proto/credential.pb.h" @@ -35,6 +36,7 @@ class PresenceDevice : public nearby::NearbyDevice { using Metadata = ::nearby::internal::Metadata; public: + explicit PresenceDevice(absl::string_view endpoint_id) noexcept; explicit PresenceDevice(Metadata metadata) noexcept; explicit PresenceDevice(DeviceMotion device_motion, Metadata metadata) noexcept; diff --git a/presence/presence_device_test.cc b/presence/presence_device_test.cc index 8c6d1d71..68a8e143 100644 --- a/presence/presence_device_test.cc +++ b/presence/presence_device_test.cc @@ -41,6 +41,7 @@ constexpr float kTestConfidence = 0.1; constexpr absl::string_view kMacAddr = "\x4C\x8B\x1D\xCE\xBA\xD1"; constexpr int kDataElementType = DataElement::kBatteryFieldType; constexpr absl::string_view kDataElementValue = "15"; +constexpr char kEndpointId[] = "endpoint_id"; constexpr int kTestAction = 3; Metadata CreateTestMetadata() { @@ -53,6 +54,11 @@ Metadata CreateTestMetadata() { return metadata; } +TEST(PresenceDeviceTest, EndpointIdConstructor) { + PresenceDevice device(kEndpointId); + EXPECT_EQ(device.GetEndpointId(), kEndpointId); +} + TEST(PresenceDeviceTest, DefaultMotionEquals) { Metadata metadata = CreateTestMetadata(); PresenceDevice device1(metadata); From 8987ddd461731b47f7580e56ad3c0d57e5fbcc0e Mon Sep 17 00:00:00 2001 From: Hai Shang Date: Tue, 21 Nov 2023 14:26:23 -0800 Subject: [PATCH 063/683] Add more logs for bwu_manager PiperOrigin-RevId: 584429491 --- connections/implementation/bwu_manager.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/connections/implementation/bwu_manager.cc b/connections/implementation/bwu_manager.cc index 78ab4992..7e37862c 100644 --- a/connections/implementation/bwu_manager.cc +++ b/connections/implementation/bwu_manager.cc @@ -40,6 +40,7 @@ #include "internal/platform/count_down_latch.h" #include "internal/platform/feature_flags.h" #include "internal/platform/logging.h" +#include "proto/connections_enums.pb.h" namespace nearby { namespace connections { @@ -349,7 +350,7 @@ void BwuManager::OnEndpointDisconnect(ClientProxy* client, DisconnectionReason reason) { NEARBY_LOGS(INFO) << "BwuManager has processed endpoint disconnection for endpoint " - << endpoint_id; + << endpoint_id << " with reason " << DisconnectionReason_Name(reason); RunOnBwuManagerThread("bwu-on-endpoint-disconnect", [this, client, service_id, endpoint_id, barrier]() mutable { From 6ee53db8f5fc8ca5ddf53081cf31426171f2669a Mon Sep 17 00:00:00 2001 From: Hai Shang Date: Wed, 22 Nov 2023 10:43:32 -0800 Subject: [PATCH 064/683] Internal fix on p2p_cluster_pcp_handler PiperOrigin-RevId: 584669043 --- connections/implementation/mediums/ble.cc | 76 ++++++++++++++++++- connections/implementation/mediums/ble.h | 13 ++++ .../implementation/mediums/ble_test.cc | 18 +++++ .../mediums/bluetooth_classic.cc | 5 +- .../implementation/p2p_cluster_pcp_handler.cc | 71 +++++++++++++++-- 5 files changed, 176 insertions(+), 7 deletions(-) diff --git a/connections/implementation/mediums/ble.cc b/connections/implementation/mediums/ble.cc index c6667050..a9d79609 100644 --- a/connections/implementation/mediums/ble.cc +++ b/connections/implementation/mediums/ble.cc @@ -14,6 +14,7 @@ #include "connections/implementation/mediums/ble.h" +#include #include #include #include @@ -76,7 +77,7 @@ bool Ble::StartAdvertising(const std::string& service_id, if (!radio_.IsEnabled()) { NEARBY_LOGS(INFO) - << "Can't start BLE scanning because Bluetooth was never turned on"; + << "Can't start BLE adveertising because Bluetooth was never turned on"; return false; } @@ -138,6 +139,79 @@ bool Ble::StopAdvertising(const std::string& service_id) { return ret; } +bool Ble::StartLegacyAdvertising( + const std::string& input_service_id, const std::string& local_endpoint_id, + const std::string& fast_advertisement_service_uuid) { + NEARBY_LOGS(INFO) << "StartLegacyAdvertising: " << input_service_id.c_str() + << ", local_endpoint_id: " << local_endpoint_id.c_str(); + MutexLock lock(&mutex_); + std::string service_id = input_service_id + "-Legacy"; + + if (IsAdvertisingLocked(service_id)) { + NEARBY_LOGS(INFO) + << "Failed to BLE legacy advertise because we're already advertising."; + return false; + } + + if (!radio_.IsEnabled()) { + NEARBY_LOGS(INFO) << "Can't start BLE legacy advertising because Bluetooth " + "was never turned on"; + return false; + } + + if (!IsAvailableLocked()) { + NEARBY_LOGS(INFO) + << "Can't turn on BLE legacy advertising. BLE is not available."; + return false; + } + // TODO(hais) improve working dummy set to feed proper hash value. + std::array encoded_legacy_char_array = { + 0x51, 0x43, 0x41, 0x41, 0x41, 0x42, 0x41, 0x43, 0x41, 0x41, 0x41, 0x44, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41}; + ByteArray encoded_bytes{encoded_legacy_char_array}; + + NEARBY_LOGS(INFO) << "Turning on BLE advertising (advertisement size=" + << encoded_bytes.size() + << "): " << absl::BytesToHexString(encoded_bytes.data()) + << ", service id=" << service_id + << ", fast advertisement service uuid=" + << fast_advertisement_service_uuid; + + if (!medium_.StartAdvertising(service_id, encoded_bytes, + fast_advertisement_service_uuid)) { + NEARBY_LOGS(ERROR) + << "Failed to turn on BLE advertising with advertisement bytes=" + << absl::BytesToHexString(encoded_bytes.data()) + << ", size=" << encoded_bytes.size() + << ", fast advertisement service uuid=" + << fast_advertisement_service_uuid; + return false; + } + + advertising_info_.Add(service_id); + return true; +} + +bool Ble::StopLegacyAdvertising(const std::string& input_service_id) { + NEARBY_LOGS(INFO) << "StopLegacyAdvertising:" << input_service_id.c_str(); + MutexLock lock(&mutex_); + + std::string service_id = input_service_id + "-Legacy"; + if (!IsAdvertisingLocked(service_id)) { + NEARBY_LOGS(INFO) + << "Can't turn off BLE legacy advertising; it is already off"; + return false; + } + + NEARBY_LOGS(INFO) << "Turned off BLE legacy advertising with service id=" + << service_id; + bool ret = medium_.StopAdvertising(service_id); + // Reset our bundle of advertising state to mark that we're no longer + // advertising. + advertising_info_.Remove(service_id); + return ret; +} + bool Ble::IsAdvertising(const std::string& service_id) { MutexLock lock(&mutex_); diff --git a/connections/implementation/mediums/ble.h b/connections/implementation/mediums/ble.h index a855b8b3..2502f92b 100644 --- a/connections/implementation/mediums/ble.h +++ b/connections/implementation/mediums/ble.h @@ -53,6 +53,19 @@ class Ble { bool StopAdvertising(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_); + // (TODO:hais) remove this after ble_v2 refactor + // Sets custom advertisement data, and then enables Ble advertising. + // Returns true, if data is successfully set, and false otherwise. + bool StartLegacyAdvertising( + const std::string& service_id, const std::string& local_endpoint_id, + const std::string& fast_advertisement_service_uuid) + ABSL_LOCKS_EXCLUDED(mutex_); + + // (TODO:hais) remove this after ble_v2 refactor + // Disables Ble advertising. + bool StopLegacyAdvertising(const std::string& service_id) + ABSL_LOCKS_EXCLUDED(mutex_); + bool IsAdvertising(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_); // Enables Ble scanning mode. Will report any discoverable peripherals in diff --git a/connections/implementation/mediums/ble_test.cc b/connections/implementation/mediums/ble_test.cc index 51673a77..03a4b7e4 100644 --- a/connections/implementation/mediums/ble_test.cc +++ b/connections/implementation/mediums/ble_test.cc @@ -247,6 +247,24 @@ TEST_F(BleTest, CanStartDiscovery) { env_.Stop(); } +TEST_F(BleTest, CanStartAndStopLegacyAdvertising) { + env_.Start(); + BluetoothRadio radio_a; + Ble ble_a{radio_a}; + radio_a.Enable(); + std::string service_id(kServiceID); + std::string legacy_service_id(std::string{kServiceID} + "-Legacy"); + std::string device_a_endpoint_id{"1A1A"}; + std::string fast_advertisement_service_uuid(kFastAdvertisementServiceUuid); + EXPECT_TRUE(ble_a.StartLegacyAdvertising(service_id, device_a_endpoint_id, + fast_advertisement_service_uuid)); + EXPECT_FALSE(ble_a.IsAdvertising(service_id)); + EXPECT_TRUE(ble_a.IsAdvertising(legacy_service_id)); + EXPECT_TRUE(ble_a.StopLegacyAdvertising(service_id)); + EXPECT_FALSE(ble_a.IsAdvertising(legacy_service_id)); + env_.Stop(); +} + } // namespace } // namespace connections } // namespace nearby diff --git a/connections/implementation/mediums/bluetooth_classic.cc b/connections/implementation/mediums/bluetooth_classic.cc index 34803fd8..0c6e86a7 100644 --- a/connections/implementation/mediums/bluetooth_classic.cc +++ b/connections/implementation/mediums/bluetooth_classic.cc @@ -76,6 +76,8 @@ bool BluetoothClassic::IsAvailableLocked() const { } bool BluetoothClassic::TurnOnDiscoverability(const std::string& device_name) { + NEARBY_LOGS(INFO) << "Turning on BT discoverability with device_name=" + << device_name; MutexLock lock(&mutex_); if (device_name.empty()) { @@ -126,6 +128,7 @@ bool BluetoothClassic::TurnOnDiscoverability(const std::string& device_name) { } bool BluetoothClassic::TurnOffDiscoverability() { + NEARBY_LOGS(INFO) << "Turning off Bluetooth discoverability."; MutexLock lock(&mutex_); if (!IsDiscoverable()) { @@ -136,7 +139,7 @@ bool BluetoothClassic::TurnOffDiscoverability() { RestoreScanMode(); RestoreDeviceName(); - NEARBY_LOGS(INFO) << "Turned Bluetooth discoverability off"; + NEARBY_LOGS(INFO) << "Turned Bluetooth discoverability off."; return true; } diff --git a/connections/implementation/p2p_cluster_pcp_handler.cc b/connections/implementation/p2p_cluster_pcp_handler.cc index da91affa..c06c6340 100644 --- a/connections/implementation/p2p_cluster_pcp_handler.cc +++ b/connections/implementation/p2p_cluster_pcp_handler.cc @@ -36,8 +36,10 @@ #include "connections/status.h" #include "internal/flags/nearby_flags.h" #include "internal/interop/device.h" +#include "internal/platform/implementation/platform.h" #include "internal/platform/logging.h" #include "internal/platform/nsd_service_info.h" +#include "internal/platform/os_name.h" #include "internal/platform/types.h" #include "proto/connections_enums.pb.h" @@ -140,9 +142,35 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartAdvertisingImpl( local_endpoint_info, web_rtc_state); if (bluetooth_medium != location::nearby::proto::connections::UNKNOWN_MEDIUM) { - NEARBY_LOG(INFO, "P2pClusterPcpHandler::StartAdvertisingImpl: BT added"); - mediums_started_successfully.push_back(bluetooth_medium); - bluetooth_classic_advertiser_client_id_ = client->GetClientId(); + NEARBY_LOG(INFO, + "P2pClusterPcpHandler::StartAdvertisingImpl: BT started"); + + // TODO(hais): update this after ble_v2 refactor. + if (api::ImplementationPlatform::GetCurrentOS() == + api::OSName::kChromeOS) { + if (ble_medium_.StartLegacyAdvertising( + service_id, local_endpoint_id, + advertising_options.fast_advertisement_service_uuid)) { + NEARBY_LOGS(INFO) << "P2pClusterPcpHandler::StartAdvertisingImpl: " + "Ble legacy started advertising"; + NEARBY_LOG(INFO, + "P2pClusterPcpHandler::StartAdvertisingImpl: BT added"); + mediums_started_successfully.push_back(bluetooth_medium); + bluetooth_classic_advertiser_client_id_ = client->GetClientId(); + } else { + // TODO(hais): update this after ble_v2 refactor. + NEARBY_LOG(WARNING, + "P2pClusterPcpHandler::StartAdvertisingImpl: BLE legacy " + "failed, revert BTC"); + bluetooth_medium_.TurnOffDiscoverability(); + bluetooth_medium_.StopAcceptingConnections(service_id); + } + } else { + NEARBY_LOG(INFO, + "P2pClusterPcpHandler::StartAdvertisingImpl: BT added"); + mediums_started_successfully.push_back(bluetooth_medium); + bluetooth_classic_advertiser_client_id_ = client->GetClientId(); + } } } @@ -192,6 +220,10 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartAdvertisingImpl( Status P2pClusterPcpHandler::StopAdvertisingImpl(ClientProxy* client) { if (client->GetClientId() == bluetooth_classic_advertiser_client_id_) { bluetooth_medium_.TurnOffDiscoverability(); + // TODO(hais): update this after ble_v2 refactor. + if (api::ImplementationPlatform::GetCurrentOS() == api::OSName::kChromeOS) { + ble_medium_.StopLegacyAdvertising(client->GetAdvertisingServiceId()); + } bluetooth_classic_advertiser_client_id_ = 0; } else { NEARBY_LOGS(INFO) << "Skipped BT TurnOffDiscoverability for client=" @@ -1235,6 +1267,10 @@ P2pClusterPcpHandler::UpdateAdvertisingOptionsImpl( mediums_->GetBluetoothClassic().TurnOffDiscoverability(); mediums_->GetBluetoothClassic().StopAcceptingConnections( std::string(service_id)); + // TODO(hais): update this after ble_v2 refactor. + if (api::ImplementationPlatform::GetCurrentOS() == api::OSName::kChromeOS) { + mediums_->GetBle().StopLegacyAdvertising(std::string(service_id)); + } } // restart @@ -1300,7 +1336,30 @@ P2pClusterPcpHandler::UpdateAdvertisingOptionsImpl( std::string(local_endpoint_id), ByteArray(std::string(local_endpoint_info)), web_rtc_state) != Medium::UNKNOWN_MEDIUM) { - restarted_mediums.push_back(Medium::BLUETOOTH); + // TODO(hais): update this after ble_v2 refactor. + if (api::ImplementationPlatform::GetCurrentOS() == + api::OSName::kChromeOS) { + if (ble_medium_.StartLegacyAdvertising( + std::string(service_id), std::string(local_endpoint_id), + advertising_options.fast_advertisement_service_uuid)) { + NEARBY_LOGS(INFO) + << "P2pClusterPcpHandler::UpdateAdvertisingOptionsImpl: " + "Ble legacy started advertising"; + NEARBY_LOG( + INFO, + "P2pClusterPcpHandler::UpdateAdvertisingOptionsImpl: BT added"); + restarted_mediums.push_back(Medium::BLUETOOTH); + } else { + NEARBY_LOG(WARNING, + "P2pClusterPcpHandler::UpdateAdvertisingOptionsImpl: " + "BLE legacy " + "failed, revert BTC"); + bluetooth_medium_.TurnOffDiscoverability(); + bluetooth_medium_.StopAcceptingConnections(std::string(service_id)); + } + } else { + restarted_mediums.push_back(Medium::BLUETOOTH); + } } else { return StartOperationResult{.status = {Status::kBluetoothError}, .mediums = restarted_mediums}; @@ -1726,7 +1785,8 @@ Medium P2pClusterPcpHandler::StartBleAdvertising( << absl::BytesToHexString(local_endpoint_info.data()) << "), client=" << client->GetClientId() << " generated BleAdvertisement with service_id=" - << service_id; + << service_id << ", bytes: " + << absl::BytesToHexString(advertisement_bytes.data()); if (!ble_medium_.StartAdvertising( service_id, advertisement_bytes, @@ -1742,6 +1802,7 @@ Medium P2pClusterPcpHandler::StartBleAdvertising( } NEARBY_LOGS(INFO) << "In startBleAdvertising(" << absl::BytesToHexString(local_endpoint_info.data()) + << ", fast_advertisement: " << fast_advertisement << "), client=" << client->GetClientId() << " started BLE Advertising with BleAdvertisement " << absl::BytesToHexString(advertisement_bytes.data()); From c26a53e38477d2e9cef228025f3d99c705401350 Mon Sep 17 00:00:00 2001 From: hai007 Date: Wed, 22 Nov 2023 18:48:13 -0800 Subject: [PATCH 065/683] 1. log connectionTokens into ClientSession 2. In 1:1 share, this connectionToken value will be the same as that one in the ConnectionAttempt (same as the BandwidthUpgradeAttempt or the EstablishedConnection). 3. In group share, this connectionToken value will be the combination of all the connectionTokens in above point 2 (separated by comma). PiperOrigin-RevId: 584767628 --- internal/proto/analytics/connections_log.proto | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/proto/analytics/connections_log.proto b/internal/proto/analytics/connections_log.proto index 68c1f0d0..4ed168f2 100644 --- a/internal/proto/analytics/connections_log.proto +++ b/internal/proto/analytics/connections_log.proto @@ -66,6 +66,10 @@ message ConnectionsLog { // The client session flow id. optional int64 client_flow_id = 3 /* type = ST_SESSION_ID */; + + // All the connection tokens used in this client session. + optional string connection_token = 4 + /* type = ST_SESSION_ID */; } // One round of a particular Strategy done by a client. From 7484132a959b80390c6f4d759d7750e04496c572 Mon Sep 17 00:00:00 2001 From: hai007 Date: Mon, 27 Nov 2023 05:23:56 -0800 Subject: [PATCH 066/683] Fix the following potential warnings: * `-Wdeprecated-declarations` * `-Wfinal-dtor-non-final-class` * `-Werror=inconsistent-missing-override` * `-Wignored-pragmas` * `-Wint-to-void-pointer-cast` * `-Winvalid-offsetof` * `-Wmacro-redefined` * `-Wmicrosoft-template` * `-Wmicrosoft-cast` * `-Wmicrosoft-exception-spec` * `-Wmicrosoft-template-shadow` * `-Wmicrosoft-unqualified-friend` * `-Wmisleading-indentation` * `-Werror=string-conversion` * `-Wunused-result` * `-Wunused-value` * `-Wunused-variable` * `-Wvla-extension` * `-Wnon-virtual-dtor` * `-Wimplicit-fallthrough` PiperOrigin-RevId: 585621864 --- internal/platform/implementation/windows/BUILD | 9 ++++++++- internal/platform/implementation/windows/generated/BUILD | 1 + internal/platform/implementation/windows/mutex.h | 2 +- .../implementation/windows/scheduled_executor.cc | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/internal/platform/implementation/windows/BUILD b/internal/platform/implementation/windows/BUILD index dbacfd8e..91f25e99 100644 --- a/internal/platform/implementation/windows/BUILD +++ b/internal/platform/implementation/windows/BUILD @@ -41,7 +41,11 @@ cc_library( "timer.h", "utils.h", ], - copts = ["-Ithird_party/nearby/internal/platform/implementation/windows/generated"], + copts = [ + "-Ithird_party/nearby/internal/platform/implementation/windows/generated", + "-Wno-non-virtual-dtor", + "-Wno-vla-extension", + ], defines = ["_SILENCE_CLANG_COROUTINE_MESSAGE"], visibility = ["//third_party/nearby/sharing/internal/impl/windows:__pkg__"], deps = [ @@ -192,6 +196,9 @@ cc_library( copts = [ "-DNO_INTEL_PIE", "-Ithird_party/nearby/internal/platform/implementation/windows/generated -D_WIN32_WINNT=_WIN32_WINNT_WIN10 -DWINVER=_WIN32_WINNT_WIN10", + "-Wno-non-virtual-dtor", + "-Wno-unused-variable", + "-Wno-unused-value", ], defines = ["_SILENCE_CLANG_COROUTINE_MESSAGE"], visibility = [ diff --git a/internal/platform/implementation/windows/generated/BUILD b/internal/platform/implementation/windows/generated/BUILD index ae01ef37..1036e17b 100644 --- a/internal/platform/implementation/windows/generated/BUILD +++ b/internal/platform/implementation/windows/generated/BUILD @@ -15,6 +15,7 @@ licenses(["notice"]) cc_library( name = "types", + copts = ["-Wno-non-virtual-dtor"], linkopts = [ "wininet.lib", "advapi32.lib", diff --git a/internal/platform/implementation/windows/mutex.h b/internal/platform/implementation/windows/mutex.h index b9a908be..951ec3bb 100644 --- a/internal/platform/implementation/windows/mutex.h +++ b/internal/platform/implementation/windows/mutex.h @@ -59,7 +59,7 @@ class ABSL_LOCKABLE Mutex : public api::Mutex { std::recursive_mutex& GetRecursiveMutex() { return recursive_mutex_; } private: - friend class ConditionVariable; + friend class ::nearby::ConditionVariable; absl::Mutex mutex_; std::recursive_mutex recursive_mutex_; // The actual mutex allocation Mode mode_; diff --git a/internal/platform/implementation/windows/scheduled_executor.cc b/internal/platform/implementation/windows/scheduled_executor.cc index 8acd677a..731f7398 100644 --- a/internal/platform/implementation/windows/scheduled_executor.cc +++ b/internal/platform/implementation/windows/scheduled_executor.cc @@ -44,7 +44,7 @@ std::shared_ptr ScheduledExecutor::Schedule( } // Cleans completed tasks - std::remove_if( + (void)std::remove_if( scheduled_tasks_.begin(), scheduled_tasks_.end(), [](std::shared_ptr& task) { return task->IsDone(); }); From 7103acb2743acc25968d6ddad019ccaf85656660 Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Mon, 27 Nov 2023 09:06:08 -0800 Subject: [PATCH 067/683] Use standard integer types PiperOrigin-RevId: 585669976 --- internal/platform/implementation/windows/utils.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/platform/implementation/windows/utils.h b/internal/platform/implementation/windows/utils.h index 96b92c94..e6a0d53e 100644 --- a/internal/platform/implementation/windows/utils.h +++ b/internal/platform/implementation/windows/utils.h @@ -75,8 +75,8 @@ const uint16_t kInterfaceTypeWifi = 71; class InspectableReader { public: static bool ReadBoolean(IInspectable inspectable); - static uint16 ReadUint16(IInspectable inspectable); - static uint32 ReadUint32(IInspectable inspectable); + static uint16_t ReadUint16(IInspectable inspectable); + static uint32_t ReadUint32(IInspectable inspectable); static std::string ReadString(IInspectable inspectable); static std::vector ReadStringArray(IInspectable inspectable); }; From 437a048aad2ec2a9abed8aaedf0d45f810ec9f56 Mon Sep 17 00:00:00 2001 From: hai007 Date: Mon, 27 Nov 2023 23:20:26 -0800 Subject: [PATCH 068/683] Add timeout exception error message for L2CAP connecting PiperOrigin-RevId: 585864057 --- proto/connections_enums.proto | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proto/connections_enums.proto b/proto/connections_enums.proto index ccc7aa7d..b0483067 100644 --- a/proto/connections_enums.proto +++ b/proto/connections_enums.proto @@ -829,6 +829,8 @@ enum OperationResultDetail { CONNECTIVITY_L2CAP_SERVER_SOCKET_CREATION_SECURITY_EXCEPTION_FAILURE = 3554; // BT server socket creation failure (SecurityException) CONNECTIVITY_BT_SERVER_SOCKET_CREATION_SECURITY_EXCEPTION_FAILURE = 3555; + // Failed to create L2CAP outgoing socket (TimeoutException on socket#connect) + CONNECTIVITY_L2CAP_CLIENT_SOCKET_CREATION_TIMEOUT_FAILURE = 3556; // Section of CATEGORY_NEARBY_ERROR, from 4500 // NO BLE MAC address associated to the GATT advertisement From 6ebe52a418573084e6e1062a664f311611dea6d6 Mon Sep 17 00:00:00 2001 From: hai007 Date: Tue, 28 Nov 2023 10:07:45 -0800 Subject: [PATCH 069/683] Add Intel PIE based API to set Hotspot client scan channel PiperOrigin-RevId: 586019580 --- .../implementation/mediums/wifi_hotspot.cc | 6 +- .../implementation/mediums/wifi_hotspot.h | 4 +- .../mediums/wifi_hotspot_test.cc | 14 ++- .../wifi_hotspot_bwu_handler.cc | 5 +- .../windows/wifi_hotspot_medium.cc | 44 ++++--- .../implementation/windows/wifi_intel.cc | 109 +++++++++++++++++- .../implementation/windows/wifi_intel.h | 5 +- internal/platform/wifi_hotspot.h | 12 +- internal/platform/wifi_hotspot_test.cc | 17 ++- 9 files changed, 178 insertions(+), 38 deletions(-) diff --git a/connections/implementation/mediums/wifi_hotspot.cc b/connections/implementation/mediums/wifi_hotspot.cc index 8605ad1d..7ef93eae 100644 --- a/connections/implementation/mediums/wifi_hotspot.cc +++ b/connections/implementation/mediums/wifi_hotspot.cc @@ -94,14 +94,16 @@ bool WifiHotspot::IsConnectedToHotspot() { } bool WifiHotspot::ConnectWifiHotspot(const std::string& ssid, - const std::string& password) { + const std::string& password, + int frequency) { MutexLock lock(&mutex_); if (is_connected_to_hotspot_) { NEARBY_LOGS(INFO) << "No need to connect to Hotspot because it is already connected."; return true; } - is_connected_to_hotspot_ = medium_.ConnectWifiHotspot(ssid, password); + is_connected_to_hotspot_ = + medium_.ConnectWifiHotspot(ssid, password, frequency); return is_connected_to_hotspot_; } diff --git a/connections/implementation/mediums/wifi_hotspot.h b/connections/implementation/mediums/wifi_hotspot.h index 6b63eac7..4fac1c9c 100644 --- a/connections/implementation/mediums/wifi_hotspot.h +++ b/connections/implementation/mediums/wifi_hotspot.h @@ -49,8 +49,8 @@ class WifiHotspot { bool StopWifiHotspot() ABSL_LOCKS_EXCLUDED(mutex_); bool IsConnectedToHotspot() ABSL_LOCKS_EXCLUDED(mutex_); - bool ConnectWifiHotspot(const std::string& ssid, const std::string& password) - ABSL_LOCKS_EXCLUDED(mutex_); + bool ConnectWifiHotspot(const std::string& ssid, const std::string& password, + int frequency) ABSL_LOCKS_EXCLUDED(mutex_); bool DisconnectWifiHotspot() ABSL_LOCKS_EXCLUDED(mutex_); // Starts a worker thread, creates a WifiHotspot socket, associates it with a diff --git a/connections/implementation/mediums/wifi_hotspot_test.cc b/connections/implementation/mediums/wifi_hotspot_test.cc index d6057158..2211620d 100644 --- a/connections/implementation/mediums/wifi_hotspot_test.cc +++ b/connections/implementation/mediums/wifi_hotspot_test.cc @@ -15,9 +15,12 @@ #include "connections/implementation/mediums/wifi_hotspot.h" +#include +#include #include #include "gtest/gtest.h" +#include "absl/strings/string_view.h" #include "absl/time/clock.h" #include "internal/platform/medium_environment.h" #include "internal/platform/wifi_hotspot.h" @@ -42,6 +45,7 @@ constexpr absl::string_view kServiceID{"com.google.location.nearby.apps.test"}; constexpr absl::string_view kSsid{"Direct-357a2d8c"}; constexpr absl::string_view kPassword{"12345678"}; constexpr absl::string_view kIp = "123.234.23.1"; +constexpr int kFrequency = 2412; constexpr const size_t kPort = 20; class WifiHotspotTest : public testing::TestWithParam { @@ -86,7 +90,7 @@ TEST_F(WifiHotspotTest, CanConnectDisconnectHotspot) { std::string ssid(kSsid); std::string password(kPassword); - EXPECT_FALSE(wifi_hotspot_a->ConnectWifiHotspot(ssid, password)); + EXPECT_FALSE(wifi_hotspot_a->ConnectWifiHotspot(ssid, password, kFrequency)); EXPECT_TRUE(wifi_hotspot_a->DisconnectWifiHotspot()); } @@ -108,7 +112,8 @@ TEST_P(WifiHotspotTest, CanStartHotspotThatOtherConnect) { wifi_hotspot_a->GetCredentials(service_id); EXPECT_TRUE(wifi_hotspot_b->ConnectWifiHotspot( - hotspot_credentials->GetSSID(), hotspot_credentials->GetPassword())); + hotspot_credentials->GetSSID(), hotspot_credentials->GetPassword(), + hotspot_credentials->GetFrequency())); WifiHotspotSocket socket_client; EXPECT_FALSE(socket_client.IsValid()); @@ -144,7 +149,8 @@ TEST_P(WifiHotspotTest, CanStartHotspotThatOtherCanCancelConnect) { wifi_hotspot_a->GetCredentials(service_id); EXPECT_TRUE(wifi_hotspot_b->ConnectWifiHotspot( - hotspot_credentials->GetSSID(), hotspot_credentials->GetPassword())); + hotspot_credentials->GetSSID(), hotspot_credentials->GetPassword(), + hotspot_credentials->GetFrequency())); WifiHotspotSocket socket_client; EXPECT_FALSE(socket_client.IsValid()); @@ -175,7 +181,7 @@ TEST_F(WifiHotspotTest, CanStartHotspotTheOtherFailConnect) { std::string ssid(kSsid); std::string password(kPassword); - EXPECT_FALSE(wifi_hotspot_b->ConnectWifiHotspot(ssid, password)); + EXPECT_FALSE(wifi_hotspot_b->ConnectWifiHotspot(ssid, password, kFrequency)); EXPECT_TRUE(wifi_hotspot_b->DisconnectWifiHotspot()); EXPECT_TRUE(wifi_hotspot_a->StopWifiHotspot()); diff --git a/connections/implementation/wifi_hotspot_bwu_handler.cc b/connections/implementation/wifi_hotspot_bwu_handler.cc index c81b485f..8f261cbf 100644 --- a/connections/implementation/wifi_hotspot_bwu_handler.cc +++ b/connections/implementation/wifi_hotspot_bwu_handler.cc @@ -115,12 +115,13 @@ WifiHotspotBwuHandler::CreateUpgradedEndpointChannel( const std::string& password = upgrade_path_info_credentials.password(); const std::string& gateway = upgrade_path_info_credentials.gateway(); std::int32_t port = upgrade_path_info_credentials.port(); + std::int32_t frequency = upgrade_path_info_credentials.frequency(); NEARBY_LOGS(INFO) << "Received Hotspot credential SSID: " << ssid << ", Password:" << password << ", Port:" << port - << ", Gateway:" << gateway; + << ", Gateway:" << gateway << ", Frequency:" << frequency; - if (!wifi_hotspot_medium_.ConnectWifiHotspot(ssid, password)) { + if (!wifi_hotspot_medium_.ConnectWifiHotspot(ssid, password, frequency)) { NEARBY_LOGS(ERROR) << "Connect to Hotspot failed"; return nullptr; } diff --git a/internal/platform/implementation/windows/wifi_hotspot_medium.cc b/internal/platform/implementation/windows/wifi_hotspot_medium.cc index e8d61d3e..29d0ab93 100644 --- a/internal/platform/implementation/windows/wifi_hotspot_medium.cc +++ b/internal/platform/implementation/windows/wifi_hotspot_medium.cc @@ -16,8 +16,6 @@ #include #include #include -#include -#include #include "absl/strings/string_view.h" #include "internal/platform/feature_flags.h" @@ -261,15 +259,16 @@ bool WifiHotspotMedium::StartWifiHotspot( platform::config_package_nearby::nearby_platform_feature:: kEnableIntelPieSdk)) { WifiIntel& intel_wifi{WifiIntel::GetInstance()}; - intel_wifi.Start(); - int GO_channel = static_cast(intel_wifi.GetGOChannel()); - NEARBY_LOGS(INFO) - << "Intel PIE enabled, Hotspot is running on channel: " - << GO_channel; - intel_wifi.Stop(); - hotspot_credentials_->SetFrequency( - WifiUtils::ConvertChannelToFrequencyMhz(GO_channel, - WifiBandType::kUnknown)); + if (intel_wifi.Start()) { + int GO_channel = static_cast(intel_wifi.GetGOChannel()); + NEARBY_LOGS(INFO) + << "Intel PIE enabled, Hotspot is running on channel: " + << GO_channel; + intel_wifi.Stop(); + hotspot_credentials_->SetFrequency( + WifiUtils::ConvertChannelToFrequencyMhz(GO_channel, + WifiBandType::kUnknown)); + } } else { NEARBY_LOGS(INFO) << "Intel PIE disabled, Can't extract Hotspot channel info!"; @@ -441,9 +440,17 @@ bool WifiHotspotMedium::ConnectWifiHotspot( // SoftAP is an abbreviation for "software enabled access point". WiFiAvailableNetwork nearby_softap{nullptr}; + + auto channel = WifiUtils::ConvertFrequencyMhzToChannel( + hotspot_credentials_->GetFrequency()); + WifiIntel& intel_wifi{WifiIntel::GetInstance()}; + bool intel_wifi_started = intel_wifi.Start(); + if (intel_wifi_started) { + intel_wifi.SetScanFilter(channel); + } + NEARBY_LOGS(INFO) << "Scanning for Nearby Hotspot SSID: " << hotspot_credentials_->GetSSID(); - // First time scan may not find our target hotspot, try 2 more times can // almost guarantee to find the Hotspot wifi_adapter_.ScanAsync().get(); @@ -453,8 +460,8 @@ bool WifiHotspotMedium::ConnectWifiHotspot( platform::config_package_nearby::nearby_platform_feature:: kWifiHotspotScanMaxRetries); - NEARBY_LOGS(INFO) << "maximum scan retries=" << wifi_hotspot_max_scans; - for (int i = 0; i < wifi_hotspot_max_scans; i++) { + int i; + for (i = 0; i < wifi_hotspot_max_scans; i++) { for (const auto& network : wifi_adapter_.NetworkReport().AvailableNetworks()) { if (!wifi_connected_network_ && !ssid.empty() && @@ -473,12 +480,19 @@ bool WifiHotspotMedium::ConnectWifiHotspot( NEARBY_LOGS(INFO) << "Scan ... "; wifi_adapter_.ScanAsync().get(); } + NEARBY_LOGS(INFO) << "Finish scanning " + << (nearby_softap ? "successfully" : "failed") << " with " + << i+1 << " times trying."; + + if (intel_wifi_started) { + intel_wifi.ResetScanFilter(); + intel_wifi.Stop(); + } if (!nearby_softap) { NEARBY_LOGS(INFO) << "Hotspot is not found"; return false; } - PasswordCredential creds; creds.Password(winrt::to_hstring(hotspot_credentials_->GetPassword())); diff --git a/internal/platform/implementation/windows/wifi_intel.cc b/internal/platform/implementation/windows/wifi_intel.cc index 8517826d..c6dd7aea 100644 --- a/internal/platform/implementation/windows/wifi_intel.cc +++ b/internal/platform/implementation/windows/wifi_intel.cc @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -97,9 +98,13 @@ typedef MUROC_RET(APIENTRY* WIFIGETADAPTERLIST)( // NOLINT typedef MUROC_RET(APIENTRY* REGISTERINTELCB)( MurocDefs::PINTEL_CALLBACK pIntelCallback); typedef MUROC_RET(APIENTRY* GETRADIOSTATE)(HADAPTER hAdapter, bool* bEnabled); -typedef MUROC_RET(APIENTRY* WIFIPANQUERYPREFFEDCHANNELSETTING)( +typedef MUROC_RET(APIENTRY* WIFIPANQUERYPREFERREDCHANNELSETTING)( HADAPTER hAdapter, PINTEL_WIFI_HEADER pHeader, void* pOutQueryPreferredChannel); +typedef MUROC_RET(APIENTRY* WIFILEGACYGOSETSCANFILTER)( + HADAPTER hAdapter, PINTEL_WIFI_HEADER pHeader, void* pInputData); +typedef MUROC_RET(APIENTRY* WIFIPANRESETLEGACYGOSCANFILTER)( + HADAPTER hAdapter, PINTEL_WIFI_HEADER pHeader); typedef MUROC_RET(APIENTRY* DEREGISTERINTELCB)( MurocDefs::INTEL_EVENT_CALLBACK fnCallbac); typedef MUROC_RET(APIENTRY* FREELISTMEMORY)(void* pList); @@ -137,7 +142,7 @@ WifiIntel& WifiIntel::GetInstance() { return *instance; } -void WifiIntel::Start() { +bool WifiIntel::Start() { NEARBY_LOGS(INFO) << "WifiIntel::Start()"; #ifndef NO_INTEL_PIE muroc_api_dll_handle_ = PIEDllLoader(); @@ -156,6 +161,7 @@ void WifiIntel::Start() { #else NEARBY_LOGS(INFO) << "NO_INTEL_PIE found, skip"; #endif + return intel_wifi_valid_; } void WifiIntel::Stop() { @@ -175,7 +181,7 @@ void WifiIntel::Stop() { int8_t WifiIntel::GetGOChannel() { #ifndef NO_INTEL_PIE - WIFIPANQUERYPREFFEDCHANNELSETTING WifiPanQueryPreferredChannelSettingFunc = + WIFIPANQUERYPREFERREDCHANNELSETTING WifiPanQueryPreferredChannelSettingFunc = nullptr; int8_t channel = -1; DWORD dwError = ERROR_SUCCESS; // NOLINT @@ -186,7 +192,7 @@ int8_t WifiIntel::GetGOChannel() { if (!intel_wifi_valid_) return channel; WifiPanQueryPreferredChannelSettingFunc = - (WIFIPANQUERYPREFFEDCHANNELSETTING)GetProcAddress( // NOLINT + (WIFIPANQUERYPREFERREDCHANNELSETTING)GetProcAddress( // NOLINT muroc_api_dll_handle_, "WifiPanQueryPreferredChannelSetting"); @@ -226,6 +232,101 @@ int8_t WifiIntel::GetGOChannel() { #endif } +bool WifiIntel::SetScanFilter(int channel) { +#ifndef NO_INTEL_PIE + WIFILEGACYGOSETSCANFILTER WifiLegacyGoSetScanFilterFunc = + nullptr; + DWORD dwError = ERROR_SUCCESS; // NOLINT + MUROC_RET murocApiRetVal = IWLAN_E_FAILURE; // NOLINT + INTEL_WIFI_HEADER intelWifiHeader; + MurocDefs::WIFI_LEGACY_GO_SCAN_FILTER scanFilter; + + if (channel <= 0) return false; + if (!intel_wifi_valid_) return false; + + NEARBY_LOGS(INFO) << "Set scan channel:" << channel; + WifiLegacyGoSetScanFilterFunc = + (WIFILEGACYGOSETSCANFILTER)GetProcAddress( // NOLINT + muroc_api_dll_handle_, + "WifiLegacyGoSetScanFilter"); + + if (WifiLegacyGoSetScanFilterFunc == nullptr) { + dwError = GetLastError(); // NOLINT + NEARBY_LOGS(INFO) + << "GetProcAddress WifiLegacyGoSetScanFilterFunc error: " + << dwError; + return false; + } + NEARBY_LOGS(VERBOSE) + << "Load WifiLegacyGoSetScanFilterFunc API completed successfully"; + + intelWifiHeader.dwSize = + sizeof(MurocDefs::WIFI_LEGACY_GO_SCAN_FILTER); + memset(&scanFilter, 0, sizeof(scanFilter)); + scanFilter.channel = (UINT8)channel; + murocApiRetVal = WifiLegacyGoSetScanFilterFunc( + wifi_adapter_handle_, &intelWifiHeader, (void*)&scanFilter); + + if (murocApiRetVal == IWLAN_E_SUCCESS) { // NOLINT + NEARBY_LOGS(INFO) << "Calling WifiLegacyGoSetScanFilter API " + "succeeded, set scan channel to " + << channel; + return true; + } + NEARBY_LOGS(INFO) << "Calling WifiLegacyGoSetScanFilter API " + "failed with error: " + << murocApiRetVal; + + return false; +#else + NEARBY_LOGS(INFO) << "NO_INTEL_PIE found, return -1"; + return false; +#endif +} + +bool WifiIntel::ResetScanFilter() { +#ifndef NO_INTEL_PIE + WIFIPANRESETLEGACYGOSCANFILTER WifiPanReSetLegacyGoScanFilterFunc = + nullptr; + DWORD dwError = ERROR_SUCCESS; // NOLINT + MUROC_RET murocApiRetVal = IWLAN_E_FAILURE; // NOLINT + INTEL_WIFI_HEADER intelWifiHeader; + + if (!intel_wifi_valid_) return false; + + WifiPanReSetLegacyGoScanFilterFunc = + (WIFIPANRESETLEGACYGOSCANFILTER)GetProcAddress( // NOLINT + muroc_api_dll_handle_, + "WifiPanReSetLegacyGoScanFilter"); + + if (WifiPanReSetLegacyGoScanFilterFunc == nullptr) { + dwError = GetLastError(); // NOLINT + NEARBY_LOGS(INFO) + << "GetProcAddress WifiPanReSetLegacyGoScanFilterFunc error: " + << dwError; + return false; + } + NEARBY_LOGS(VERBOSE) + << "Load WifiPanReSetLegacyGoScanFilterFunc API completed successfully"; + intelWifiHeader.dwSize = 0; + murocApiRetVal = WifiPanReSetLegacyGoScanFilterFunc( + wifi_adapter_handle_, &intelWifiHeader); + + if (murocApiRetVal == IWLAN_E_SUCCESS) { // NOLINT + NEARBY_LOGS(INFO) << "Calling WifiPanReSetLegacyGoScanFilter API succeeded"; + return true; + } + NEARBY_LOGS(INFO) << "Calling WifiPanQueryPreferredChannelSetting API " + "failed with error: " + << murocApiRetVal; + + return false; +#else + NEARBY_LOGS(INFO) << "NO_INTEL_PIE found, return -1"; + return false; +#endif +} + #ifndef NO_INTEL_PIE wchar_t* GetEntireRegistryDeviceList() { CONFIGRET configRet = CR_SUCCESS; diff --git a/internal/platform/implementation/windows/wifi_intel.h b/internal/platform/implementation/windows/wifi_intel.h index 577df76f..04a9506b 100644 --- a/internal/platform/implementation/windows/wifi_intel.h +++ b/internal/platform/implementation/windows/wifi_intel.h @@ -43,9 +43,12 @@ class WifiIntel { static WifiIntel& GetInstance(); bool IsValid() const { return intel_wifi_valid_; } - void Start(); + bool Start(); void Stop(); int8_t GetGOChannel(); + bool SetScanFilter(int channel); + bool ResetScanFilter(); + private: // This is a singleton object, for which destructor will never be called. diff --git a/internal/platform/wifi_hotspot.h b/internal/platform/wifi_hotspot.h index 88ee985a..187d50da 100644 --- a/internal/platform/wifi_hotspot.h +++ b/internal/platform/wifi_hotspot.h @@ -15,13 +15,16 @@ #ifndef PLATFORM_PUBLIC_WIFI_HOTSPOT_H_ #define PLATFORM_PUBLIC_WIFI_HOTSPOT_H_ +#include #include +#include #include #include -#include "absl/container/flat_hash_map.h" -#include "internal/platform/byte_array.h" +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" #include "internal/platform/cancellation_flag.h" +#include "internal/platform/exception.h" #include "internal/platform/implementation/platform.h" #include "internal/platform/implementation/wifi_hotspot.h" #include "internal/platform/input_stream.h" @@ -170,7 +173,7 @@ class WifiHotspotMedium { } // Returns the port range as a pair of min and max port. - absl::optional> GetDynamicPortRange() { + std::optional> GetDynamicPortRange() { return impl_->GetDynamicPortRange(); } @@ -181,10 +184,11 @@ class WifiHotspotMedium { bool StopWifiHotspot() { return impl_->StopWifiHotspot(); } bool ConnectWifiHotspot(const std::string& ssid, - const std::string& password) { + const std::string& password, int frequency) { MutexLock lock(&mutex_); hotspot_credentials_.SetSSID(ssid); hotspot_credentials_.SetPassword(password); + hotspot_credentials_.SetFrequency(frequency); return impl_->ConnectWifiHotspot(&hotspot_credentials_); } bool DisconnectWifiHotspot() { return impl_->DisconnectWifiHotspot(); } diff --git a/internal/platform/wifi_hotspot_test.cc b/internal/platform/wifi_hotspot_test.cc index a21ee7a8..262f3098 100644 --- a/internal/platform/wifi_hotspot_test.cc +++ b/internal/platform/wifi_hotspot_test.cc @@ -14,15 +14,21 @@ #include "internal/platform/wifi_hotspot.h" +#include #include #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" #include "absl/time/clock.h" +#include "internal/platform/byte_array.h" +#include "internal/platform/cancellation_flag.h" #include "internal/platform/count_down_latch.h" +#include "internal/platform/exception.h" +#include "internal/platform/input_stream.h" #include "internal/platform/logging.h" #include "internal/platform/medium_environment.h" +#include "internal/platform/output_stream.h" #include "internal/platform/wifi_credential.h" namespace nearby { @@ -43,6 +49,7 @@ constexpr absl::string_view kSsid = "Direct-357a2d8c"; constexpr absl::string_view kPassword = "b592f7d3"; constexpr absl::string_view kIp = "123.234.23.1"; constexpr const size_t kPort = 20; +constexpr int kFrequency = 2412; constexpr absl::string_view kData = "ABCD"; constexpr const size_t kChunkSize = 10; @@ -109,7 +116,7 @@ TEST_F(WifiHotspotMediumTest, CanConnectDisconnectHotspot) { std::string password(kPassword); ASSERT_TRUE(wifi_hotspot_a->IsInterfaceValid()); - EXPECT_FALSE(wifi_hotspot_a->ConnectWifiHotspot(ssid, password)); + EXPECT_FALSE(wifi_hotspot_a->ConnectWifiHotspot(ssid, password, kFrequency)); EXPECT_TRUE(wifi_hotspot_a->DisconnectWifiHotspot()); wifi_hotspot_a.reset(); } @@ -125,7 +132,8 @@ TEST_P(WifiHotspotMediumTest, CanStartHotspotThatOtherConnect) { EXPECT_TRUE(wifi_hotspot_a->StartWifiHotspot()); HotspotCredentials* hotspot_credentials = wifi_hotspot_a->GetCredential(); EXPECT_TRUE(wifi_hotspot_b->ConnectWifiHotspot( - hotspot_credentials->GetSSID(), hotspot_credentials->GetPassword())); + hotspot_credentials->GetSSID(), hotspot_credentials->GetPassword(), + hotspot_credentials->GetFrequency())); WifiHotspotServerSocket server_socket = wifi_hotspot_a->ListenForService(); EXPECT_TRUE(server_socket.IsValid()); @@ -191,7 +199,8 @@ TEST_P(WifiHotspotMediumTest, CanStartHotspotThatOtherCanCancelConnect) { EXPECT_TRUE(wifi_hotspot_a->StartWifiHotspot()); HotspotCredentials* hotspot_credentials = wifi_hotspot_a->GetCredential(); EXPECT_TRUE(wifi_hotspot_b->ConnectWifiHotspot( - hotspot_credentials->GetSSID(), hotspot_credentials->GetPassword())); + hotspot_credentials->GetSSID(), hotspot_credentials->GetPassword(), + hotspot_credentials->GetFrequency())); WifiHotspotServerSocket server_socket = wifi_hotspot_a->ListenForService(); EXPECT_TRUE(server_socket.IsValid()); @@ -250,7 +259,7 @@ TEST_F(WifiHotspotMediumTest, CanStartHotspotTheOtherFailConnect) { std::string ssid(kSsid); std::string password(kPassword); - EXPECT_FALSE(wifi_hotspot_b->ConnectWifiHotspot(ssid, password)); + EXPECT_FALSE(wifi_hotspot_b->ConnectWifiHotspot(ssid, password, kFrequency)); EXPECT_TRUE(wifi_hotspot_b->DisconnectWifiHotspot()); EXPECT_TRUE(wifi_hotspot_a->StopWifiHotspot()); From 91197f36839fa7241d89b7c589abd5e1eda591ee Mon Sep 17 00:00:00 2001 From: Anthony Rueda Date: Thu, 30 Nov 2023 17:07:24 -0800 Subject: [PATCH 070/683] [Presence] Deflag use_shared_credential_grpc and deprecate `secret_id` field from LocalCredential and SharedCredential protos PiperOrigin-RevId: 586831590 --- internal/proto/credential.proto | 2 +- internal/proto/local_credential.proto | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/proto/credential.proto b/internal/proto/credential.proto index 42836b1d..d489e6ac 100644 --- a/internal/proto/credential.proto +++ b/internal/proto/credential.proto @@ -47,7 +47,7 @@ enum CredentialType { // LINT.IfChange(SharedCredential) message SharedCredential { // The randomly generated unique id of the public credential. - bytes secret_id = 1; + bytes secret_id = 1 [deprecated = true]; // 32 bytes of secure random bytes used to derive any symmetric keys needed. bytes key_seed = 2; diff --git a/internal/proto/local_credential.proto b/internal/proto/local_credential.proto index 7fbcada0..04819aad 100644 --- a/internal/proto/local_credential.proto +++ b/internal/proto/local_credential.proto @@ -41,7 +41,7 @@ message LocalCredential { // The unique id of (and hashed based on) a pair of Secret Key and // X509Certificate's public key. - bytes secret_id = 1; + bytes secret_id = 1 [deprecated = true]; // Bytes representation of an AES Key owned by local device, to encrypt // local device metadata. From 454d24e837be65937f0b91200d949c804e21529a Mon Sep 17 00:00:00 2001 From: hai007 Date: Mon, 4 Dec 2023 22:20:01 -0800 Subject: [PATCH 071/683] Allow ConnectionOptionsW::GetMediums to actually return the updated mediums_size value. Currently, mediums_size is passed in by value, so updates to it have no effect outside the function. PiperOrigin-RevId: 587942623 --- connections/c/connection_options_w.cc | 4 ++-- connections/c/connection_options_w.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/connections/c/connection_options_w.cc b/connections/c/connection_options_w.cc index 96559460..0d673664 100644 --- a/connections/c/connection_options_w.cc +++ b/connections/c/connection_options_w.cc @@ -19,7 +19,7 @@ namespace nearby::windows { void ConnectionOptionsW::GetMediums(const MediumW* mediums, - size_t mediums_size) const { + size_t* mediums_size) const { // Create a collection of enabled mediums auto allowedMediums = allowed.GetMediums(true); auto iter = allowedMediums.begin(); @@ -28,7 +28,7 @@ void ConnectionOptionsW::GetMediums(const MediumW* mediums, while (iter != allowedMediums.end() && index < MAX_MEDIUMS) { *mediums_[index++] = iter[index]; } - mediums_size = allowed.GetMediums(true).size(); + *mediums_size = allowed.GetMediums(true).size(); return; } diff --git a/connections/c/connection_options_w.h b/connections/c/connection_options_w.h index 9a2f7497..2312b04c 100644 --- a/connections/c/connection_options_w.h +++ b/connections/c/connection_options_w.h @@ -39,7 +39,7 @@ struct DLL_API ConnectionOptionsW : public OptionsBaseW { int keep_alive_interval_millis = 0; int keep_alive_timeout_millis = 0; - void GetMediums(const MediumW*, size_t) const; + void GetMediums(const MediumW*, size_t*) const; private: MediumW* mediums_[MAX_MEDIUMS]; From 3a4f4cde9fa880aaaea8f44002d57223fb32228a Mon Sep 17 00:00:00 2001 From: hai007 Date: Tue, 5 Dec 2023 07:47:26 -0800 Subject: [PATCH 072/683] Avoid manually forward declaring BoringSSL types Per go/cstyle#Forward_Declarations. BoringSSL already provides a forward declarations header. Also tidy up the source file's includes. It seems to only use symbols in aead.h. PiperOrigin-RevId: 588069592 --- internal/crypto_cros/aead.cc | 3 +-- internal/crypto_cros/aead.h | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/internal/crypto_cros/aead.cc b/internal/crypto_cros/aead.cc index 7e0868f9..98bc66c4 100644 --- a/internal/crypto_cros/aead.cc +++ b/internal/crypto_cros/aead.cc @@ -32,8 +32,7 @@ #include "absl/types/span.h" #include "internal/crypto_cros/nearby_base.h" #include "internal/crypto_cros/openssl_util.h" -#include -#include +#include namespace crypto { diff --git a/internal/crypto_cros/aead.h b/internal/crypto_cros/aead.h index fca3ac91..12da8a57 100644 --- a/internal/crypto_cros/aead.h +++ b/internal/crypto_cros/aead.h @@ -26,8 +26,7 @@ #include "absl/types/optional.h" #include "absl/types/span.h" #include "internal/crypto_cros/crypto_export.h" - -struct evp_aead_st; +#include namespace crypto { @@ -87,7 +86,7 @@ class CRYPTO_EXPORT Aead { size_t* output_length, size_t max_output_length) const; absl::optional> key_; - const evp_aead_st* aead_; + const EVP_AEAD* aead_; }; } // namespace crypto From b6759868719571d0f7bab08af8735a6e16750fda Mon Sep 17 00:00:00 2001 From: hai007 Date: Tue, 5 Dec 2023 21:46:35 -0800 Subject: [PATCH 073/683] create a new PacketType "PAYLOAD_ACK" to replace ControlMessage.EventType "PAYLOAD_RECEIVED_ACK" PiperOrigin-RevId: 588287541 --- connections/implementation/proto/offline_wire_formats.proto | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/connections/implementation/proto/offline_wire_formats.proto b/connections/implementation/proto/offline_wire_formats.proto index d0d226bd..42508670 100644 --- a/connections/implementation/proto/offline_wire_formats.proto +++ b/connections/implementation/proto/offline_wire_formats.proto @@ -149,6 +149,7 @@ message PayloadTransferFrame { UNKNOWN_PACKET_TYPE = 0; DATA = 1; CONTROL = 2; + PAYLOAD_ACK = 3; } message PayloadHeader { @@ -183,7 +184,8 @@ message PayloadTransferFrame { UNKNOWN_EVENT_TYPE = 0; PAYLOAD_ERROR = 1; PAYLOAD_CANCELED = 2; - PAYLOAD_RECEIVED_ACK = 3; + // Use PacketType.PAYLOAD_ACK instead + PAYLOAD_RECEIVED_ACK = 3 [deprecated = true]; } optional EventType event = 1; From d710bff241ed5920d202109c158a5f8e0549543c Mon Sep 17 00:00:00 2001 From: hai007 Date: Thu, 7 Dec 2023 19:06:55 -0800 Subject: [PATCH 074/683] Apply result code to payloads PiperOrigin-RevId: 588978332 --- proto/connections_enums.proto | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/proto/connections_enums.proto b/proto/connections_enums.proto index b0483067..dce0f827 100644 --- a/proto/connections_enums.proto +++ b/proto/connections_enums.proto @@ -670,7 +670,7 @@ enum OperationResultDetail { IO_ENDPOINT_IO_ERROR_ON_BLE = 3005; // Payloads IOError due to endpoint get IOException on L2CAP medium // (IOException on Channel#write) - IO_ENDPOINT_IO_ERROR_ON_L2CAP = 3006; + IO_ENDPOINT_IO_ERROR_ON_BLE_L2CAP = 3006; // Payloads IOError due to endpoint get IOException on BT medium (IOException // on Channel#write) IO_ENDPOINT_IO_ERROR_ON_BT = 3007; @@ -831,6 +831,8 @@ enum OperationResultDetail { CONNECTIVITY_BT_SERVER_SOCKET_CREATION_SECURITY_EXCEPTION_FAILURE = 3555; // Failed to create L2CAP outgoing socket (TimeoutException on socket#connect) CONNECTIVITY_L2CAP_CLIENT_SOCKET_CREATION_TIMEOUT_FAILURE = 3556; + // Failed to create connectionFlow + CONNECTIVITY_WEB_RTC_UNSATISFIED_LINK_ERROR = 3557; // Section of CATEGORY_NEARBY_ERROR, from 4500 // NO BLE MAC address associated to the GATT advertisement From dde158887159130bee9e49fbc4d2d5783a935b09 Mon Sep 17 00:00:00 2001 From: Hai Shang Date: Thu, 7 Dec 2023 23:20:02 -0800 Subject: [PATCH 075/683] internal fix PiperOrigin-RevId: 589025655 --- .../implementation/mediums/ble_test.cc | 42 +++++++++++++++++++ internal/platform/ble.cc | 12 +++--- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/connections/implementation/mediums/ble_test.cc b/connections/implementation/mediums/ble_test.cc index 03a4b7e4..c054e911 100644 --- a/connections/implementation/mediums/ble_test.cc +++ b/connections/implementation/mediums/ble_test.cc @@ -247,6 +247,48 @@ TEST_F(BleTest, CanStartDiscovery) { env_.Stop(); } +TEST_F(BleTest, HandleDupeFindingsFromDiscovery) { + env_.Start(); + BluetoothRadio radio_a; + BluetoothRadio radio_b; + Ble ble_a{radio_a}; + Ble ble_b{radio_b}; + radio_a.Enable(); + radio_b.Enable(); + std::string service_id(kServiceID); + ByteArray advertisement_bytes{std::string(kAdvertisementString)}; + std::string fast_advertisement_service_uuid(kFastAdvertisementServiceUuid); + // expecting two discoveries from the same peripheral. + CountDownLatch discovery_latch(2); + // Expecting the peripheral lost will trigger lost_cb. + CountDownLatch lost_latch(1); + + ble_b.StartAdvertising(service_id, advertisement_bytes, + fast_advertisement_service_uuid); + + EXPECT_TRUE(ble_a.StartScanning( + service_id, fast_advertisement_service_uuid, + DiscoveredPeripheralCallback{ + .peripheral_discovered_cb = + [&discovery_latch]( + BlePeripheral& peripheral, const std::string& service_id, + const ByteArray& advertisement_bytes, + bool fast_advertisement) { discovery_latch.CountDown(); }, + .peripheral_lost_cb = + [&lost_latch](BlePeripheral& peripheral, + const std::string& service_id) { + lost_latch.CountDown(); + }, + })); + ble_b.StartAdvertising(service_id, advertisement_bytes, + fast_advertisement_service_uuid); + EXPECT_TRUE(discovery_latch.Await(kWaitDuration).result()); + ble_b.StopAdvertising(service_id); + EXPECT_TRUE(lost_latch.Await(kWaitDuration).result()); + EXPECT_TRUE(ble_a.StopScanning(service_id)); + env_.Stop(); +} + TEST_F(BleTest, CanStartAndStopLegacyAdvertising) { env_.Start(); BluetoothRadio radio_a; diff --git a/internal/platform/ble.cc b/internal/platform/ble.cc index d6792c22..e653c7ae 100644 --- a/internal/platform/ble.cc +++ b/internal/platform/ble.cc @@ -49,13 +49,11 @@ bool BleMedium::StartScanning( auto pair = peripherals_.emplace( &peripheral, absl::make_unique()); auto& context = *pair.first->second; - if (pair.second) { - context.peripheral = BlePeripheral(&peripheral); - discovered_peripheral_callback_.peripheral_discovered_cb( - context.peripheral, service_id, - context.peripheral.GetAdvertisementBytes(service_id), - fast_advertisement); - } + context.peripheral = BlePeripheral(&peripheral); + discovered_peripheral_callback_.peripheral_discovered_cb( + context.peripheral, service_id, + context.peripheral.GetAdvertisementBytes(service_id), + fast_advertisement); }, .peripheral_lost_cb = [this](api::BlePeripheral& peripheral, From 0e7fc8d429a77f46b21c99c6083b976ba828f46c Mon Sep 17 00:00:00 2001 From: Qin Wang Date: Mon, 11 Dec 2023 18:30:25 -0800 Subject: [PATCH 076/683] Disable flaky test //third_party/nearby/fastpair/internal:fast_pair_seeker_impl_test PiperOrigin-RevId: 590018163 --- fastpair/internal/fast_pair_seeker_impl_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fastpair/internal/fast_pair_seeker_impl_test.cc b/fastpair/internal/fast_pair_seeker_impl_test.cc index 09556b8e..6738784a 100644 --- a/fastpair/internal/fast_pair_seeker_impl_test.cc +++ b/fastpair/internal/fast_pair_seeker_impl_test.cc @@ -135,7 +135,7 @@ TEST_F(FastPairSeekerImplTest, StartAndStopFastPairScan) { EXPECT_OK(fast_pair_seeker_->StopFastPairScan()); } -TEST_F(FastPairSeekerImplTest, DiscoverDevice) { +TEST_F(FastPairSeekerImplTest, DISABLED_DiscoverDevice) { FakeProvider provider; CountDownLatch latch(1); fast_pair_seeker_ = std::make_unique( From 0ff449d9fce84c71ee950f798add2a1f470ab2df Mon Sep 17 00:00:00 2001 From: Hai Shang Date: Mon, 11 Dec 2023 19:04:23 -0800 Subject: [PATCH 077/683] internal fix PiperOrigin-RevId: 590025851 --- internal/platform/implementation/g3/ble.cc | 15 +++++++-------- internal/platform/implementation/g3/ble.h | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/internal/platform/implementation/g3/ble.cc b/internal/platform/implementation/g3/ble.cc index f60b2391..ed44c996 100644 --- a/internal/platform/implementation/g3/ble.cc +++ b/internal/platform/implementation/g3/ble.cc @@ -159,14 +159,13 @@ bool BleMedium::StartAdvertising( acceptance_thread_running_.exchange(true); accept_loops_runner_.Execute([&env, this, service_id]() mutable { - if (!accept_loops_runner_.InShutdown()) { - while (true) { - auto client_socket = - server_socket_->Accept(&(this->adapter_->GetPeripheral())); - if (client_socket == nullptr) break; - env.CallBleAcceptedConnectionCallback(*this, *(client_socket.release()), - service_id); - } + while (true) { + if (accept_loops_runner_.InShutdown()) break; + auto client_socket = + server_socket_->Accept(&(this->adapter_->GetPeripheral())); + if (client_socket == nullptr) break; + env.CallBleAcceptedConnectionCallback(*this, *(client_socket.release()), + service_id); } acceptance_thread_running_.exchange(false); }); diff --git a/internal/platform/implementation/g3/ble.h b/internal/platform/implementation/g3/ble.h index 243468ff..e6637005 100644 --- a/internal/platform/implementation/g3/ble.h +++ b/internal/platform/implementation/g3/ble.h @@ -184,7 +184,7 @@ class BleMedium : public api::BleMedium { std::atomic_bool acceptance_thread_running_ = false; // A thread pool dedicated to wait to complete the accept_loops_runner_. - MultiThreadExecutor close_accept_loops_runner_{kMaxConcurrentAcceptLoops}; + MultiThreadExecutor close_accept_loops_runner_{1}; // A server socket is established when start advertising. std::unique_ptr server_socket_; From ceded2da8419b12acf5fc0b827ad85b5c9a0ed8b Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Tue, 12 Dec 2023 09:21:16 -0800 Subject: [PATCH 078/683] Added more logs on bandwidth upgrade PiperOrigin-RevId: 590229747 --- connections/implementation/bwu_manager.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/connections/implementation/bwu_manager.cc b/connections/implementation/bwu_manager.cc index 7e37862c..aef9735f 100644 --- a/connections/implementation/bwu_manager.cc +++ b/connections/implementation/bwu_manager.cc @@ -536,15 +536,24 @@ void BwuManager::OnIncomingConnection( return; } + NEARBY_LOGS(VERBOSE) << "BwuManager successfully received " + "BWU_NEGOTIATION.CLIENT_INTRODUCTION " + "OfflineFrame on EndpointChannel " + << channel->GetName(); + if (!WriteClientIntroductionAckFrame(channel)) { // This was never a fully EstablishedConnection, no need to provide a // closure reason. + NEARBY_LOGS(ERROR) << "BwuManager failed to write" + "BWU_NEGOTIATION.CLIENT_INTRODUCTION_ACK " + "OfflineFrame on EndpointChannel " + << channel->GetName(); channel->Close(); return; } - NEARBY_LOGS(VERBOSE) << "BwuManager successfully received " - "BWU_NEGOTIATION.CLIENT_INTRODUCTION " + NEARBY_LOGS(VERBOSE) << "BwuManager successfully wrote " + "BWU_NEGOTIATION.CLIENT_INTRODUCTION_ACK " "OfflineFrame on EndpointChannel " << channel->GetName(); From 7022e6c5d914ffb46b0f7edc125cc9c651440dfa Mon Sep 17 00:00:00 2001 From: Anay Wadhera Date: Wed, 13 Dec 2023 12:31:42 -0800 Subject: [PATCH 079/683] Create instant on loss advertisement format PiperOrigin-RevId: 590680562 --- Package.swift | 1 + .../implementation/mediums/ble_v2/BUILD | 6 ++ .../ble_v2/instant_on_lost_advertisement.cc | 79 +++++++++++++++++++ .../ble_v2/instant_on_lost_advertisement.h | 63 +++++++++++++++ .../instant_on_lost_advertisement_test.cc | 78 ++++++++++++++++++ 5 files changed, 227 insertions(+) create mode 100644 connections/implementation/mediums/ble_v2/instant_on_lost_advertisement.cc create mode 100644 connections/implementation/mediums/ble_v2/instant_on_lost_advertisement.h create mode 100644 connections/implementation/mediums/ble_v2/instant_on_lost_advertisement_test.cc diff --git a/Package.swift b/Package.swift index e9ceacdc..713cef3e 100644 --- a/Package.swift +++ b/Package.swift @@ -441,6 +441,7 @@ let package = Package( "connections/implementation/mediums/ble_v2/ble_advertisement_header_test.cc", "connections/implementation/mediums/ble_v2/ble_utils_test.cc", "connections/implementation/mediums/ble_v2/discovered_peripheral_tracker_test.cc", + "connections/implementation/mediums/ble_v2/instant_on_lost_advertisement_test.cc", "connections/implementation/mediums/webrtc_peer_id_test.cc", "connections/implementation/mediums/wifi_lan_test.cc", "connections/implementation/mediums/bluetooth_classic_test.cc", diff --git a/connections/implementation/mediums/ble_v2/BUILD b/connections/implementation/mediums/ble_v2/BUILD index c07c66da..dd542fd6 100644 --- a/connections/implementation/mediums/ble_v2/BUILD +++ b/connections/implementation/mediums/ble_v2/BUILD @@ -23,6 +23,7 @@ cc_library( "ble_utils.cc", "bloom_filter.cc", "discovered_peripheral_tracker.cc", + "instant_on_lost_advertisement.cc", ], hdrs = [ "advertisement_read_result.h", @@ -33,6 +34,7 @@ cc_library( "bloom_filter.h", "discovered_peripheral_callback.h", "discovered_peripheral_tracker.h", + "instant_on_lost_advertisement.h", ], copts = ["-DCORE_ADAPTER_DLL"], visibility = [ @@ -54,6 +56,7 @@ cc_library( "@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/numeric:int128", + "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", @@ -72,6 +75,7 @@ cc_test( "ble_utils_test.cc", "bloom_filter_test.cc", "discovered_peripheral_tracker_test.cc", + "instant_on_lost_advertisement_test.cc", ], deps = [ ":ble_v2", @@ -83,7 +87,9 @@ cc_test( "//proto/mediums:ble_frames_cc_proto", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/hash:hash_testing", + "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", + "@com_google_absl//absl/strings:string_view", "@com_google_absl//absl/time", "@com_google_googletest//:gtest_main", ], diff --git a/connections/implementation/mediums/ble_v2/instant_on_lost_advertisement.cc b/connections/implementation/mediums/ble_v2/instant_on_lost_advertisement.cc new file mode 100644 index 00000000..137faf63 --- /dev/null +++ b/connections/implementation/mediums/ble_v2/instant_on_lost_advertisement.cc @@ -0,0 +1,79 @@ +// Copyright 2023 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 "connections/implementation/mediums/ble_v2/instant_on_lost_advertisement.h" + +#include +#include + +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/strings/str_format.h" +#include "absl/strings/string_view.h" +#include "connections/implementation/mediums/ble_v2/ble_advertisement_header.h" + +namespace nearby { +namespace connections { +namespace mediums { + +namespace { +constexpr int kVersion = 0b1; +constexpr int kHashLength = + BleAdvertisementHeader::kAdvertisementHashByteLength; +constexpr int kVersionMask = 0x0e0; +// The header length for the instant on lost advertisement is 1 byte. +constexpr int kTotalLength = 1 + kHashLength; +} // namespace + +absl::StatusOr +InstantOnLostAdvertisement::CreateFromHash( + absl::string_view advertisement_hash) { + if (advertisement_hash.length() != kHashLength) { + return absl::InvalidArgumentError( + absl::StrFormat("Cannot create instant on loss advertisement from " + "invalid hash length %d.", + advertisement_hash.length())); + } + return InstantOnLostAdvertisement(advertisement_hash); +} + +std::string InstantOnLostAdvertisement::ToBytes() const { + // 1. Header + uint8_t header_byte = ((kVersion << 5) & kVersionMask); + // 2. Hash + return absl::StrFormat("%c%s", header_byte, advertisement_hash_); +} + +absl::StatusOr +InstantOnLostAdvertisement::CreateFromBytes(absl::string_view bytes) { + if (bytes.length() != kTotalLength) { + return absl::InvalidArgumentError(absl::StrFormat( + "Cannot create instant on loss advertisement due to invalid length %d", + bytes.length())); + } + // 1. Check header. + uint8_t header_byte = bytes[0]; + int version = (header_byte & kVersionMask) >> 5; + if (version != kVersion) { + return absl::InvalidArgumentError(absl::StrFormat( + "Cannot create instant on loss advertisement from invalid version %d.", + version)); + } + // 2. Get hash, skipping the header (size 1). + return InstantOnLostAdvertisement(bytes.substr(1, kHashLength)); +} + +} // namespace mediums +} // namespace connections +} // namespace nearby diff --git a/connections/implementation/mediums/ble_v2/instant_on_lost_advertisement.h b/connections/implementation/mediums/ble_v2/instant_on_lost_advertisement.h new file mode 100644 index 00000000..0abd6a65 --- /dev/null +++ b/connections/implementation/mediums/ble_v2/instant_on_lost_advertisement.h @@ -0,0 +1,63 @@ +// Copyright 2023 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 THIRD_PARTY_NEARBY_CONNECTIONS_IMPLEMENTATION_MEDIUMS_BLE_V2_INSTANT_ON_LOST_ADVERTISEMENT_H_ +#define THIRD_PARTY_NEARBY_CONNECTIONS_IMPLEMENTATION_MEDIUMS_BLE_V2_INSTANT_ON_LOST_ADVERTISEMENT_H_ + +#include +#include +#include + +#include "absl/status/statusor.h" +#include "absl/strings/string_view.h" + +namespace nearby { +namespace connections { +namespace mediums { + +// Represents an advertisement indicating that a previous BleAdvertisement is no +// longer valid. +// +// Format: +// [VERSION][5 bits reserved][ADVERTISEMENT HASH] +class InstantOnLostAdvertisement { + public: + // Creates an on lost advertisement from an advertisement hash. + static absl::StatusOr CreateFromHash( + absl::string_view advertisement_hash); + + // Creates an InstantOnLostAdvertisement from raw bytes received over-the-air. + static absl::StatusOr CreateFromBytes( + absl::string_view bytes); + + // Returns this instant-on-lost-advertisement in raw string + // (non human-readable) format. + // NOTE: Even though this function returns a string, this is not a UTF-8 + // string, as it contains raw bytes. + std::string ToBytes() const; + + std::string GetHash() const { return advertisement_hash_; } + + private: + explicit InstantOnLostAdvertisement(absl::string_view hash) + : advertisement_hash_(std::string(hash)) {} + + const std::string advertisement_hash_; +}; + +} // namespace mediums +} // namespace connections +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_CONNECTIONS_IMPLEMENTATION_MEDIUMS_BLE_V2_INSTANT_ON_LOST_ADVERTISEMENT_H_ diff --git a/connections/implementation/mediums/ble_v2/instant_on_lost_advertisement_test.cc b/connections/implementation/mediums/ble_v2/instant_on_lost_advertisement_test.cc new file mode 100644 index 00000000..656a4987 --- /dev/null +++ b/connections/implementation/mediums/ble_v2/instant_on_lost_advertisement_test.cc @@ -0,0 +1,78 @@ +// Copyright 2023 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 "connections/implementation/mediums/ble_v2/instant_on_lost_advertisement.h" + +#include + +#include "gmock/gmock.h" +#include "protobuf-matchers/protocol-buffer-matchers.h" +#include "gtest/gtest.h" +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/strings/string_view.h" + +namespace nearby { +namespace connections { +namespace mediums { +namespace { + +constexpr absl::string_view kGoodHash = "\x01\x02\x03\x04"; +constexpr absl::string_view kBadHash = "\x05\x06\x07"; + +using ::testing::status::StatusIs; + +TEST(InstantOnLostAdvertisementTest, + InstantOnLostAdvertisementParsesFromGoodHash) { + absl::StatusOr advertisement = + InstantOnLostAdvertisement::CreateFromHash(kGoodHash); + ASSERT_OK(advertisement); + EXPECT_EQ(advertisement->ToBytes().size(), 5); + + absl::StatusOr des_advertisement = + InstantOnLostAdvertisement::CreateFromBytes(advertisement->ToBytes()); + ASSERT_OK(des_advertisement); + EXPECT_EQ(des_advertisement->GetHash(), kGoodHash); +} + +TEST(InstantOnLostAdvertisementTest, + InstantOnLostAdvertisementFailsParseFromBadHash) { + absl::StatusOr advertisement = + InstantOnLostAdvertisement::CreateFromHash(kBadHash); + EXPECT_THAT(advertisement, StatusIs(absl::StatusCode::kInvalidArgument)); +} + +TEST(InstantOnLostAdvertisementTest, + InstantOnLostAdvertisementFailsParseFromLessBytes) { + EXPECT_THAT(InstantOnLostAdvertisement::CreateFromBytes(kGoodHash), + StatusIs(absl::StatusCode::kInvalidArgument)); +} + +TEST(InstantOnLostAdvertisementTest, + InstantOnLostAdvertisementFailsParseBadVersion) { + absl::StatusOr advertisement = + InstantOnLostAdvertisement::CreateFromHash(kGoodHash); + ASSERT_OK(advertisement); + // Set version to 0. + std::string advertisement_bytes = advertisement->ToBytes(); + advertisement_bytes[0] = 0x05; + + EXPECT_THAT(InstantOnLostAdvertisement::CreateFromBytes(advertisement_bytes), + StatusIs(absl::StatusCode::kInvalidArgument)); +} + +} // namespace +} // namespace mediums +} // namespace connections +} // namespace nearby From 5fee66b487b8845d20efccfe5602bf11329cb7d4 Mon Sep 17 00:00:00 2001 From: hai007 Date: Wed, 13 Dec 2023 20:57:59 -0800 Subject: [PATCH 080/683] Rename OperationResultDetail to be OperationResultCode PiperOrigin-RevId: 590803695 --- proto/connections_enums.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proto/connections_enums.proto b/proto/connections_enums.proto index dce0f827..b38965f4 100644 --- a/proto/connections_enums.proto +++ b/proto/connections_enums.proto @@ -441,7 +441,7 @@ enum OperationResultCategory { // This enum is not used to determine success rate, but for devs to understand // occurrences of and operation failure details -enum OperationResultDetail { +enum OperationResultCode { // Section of CATEGORY_UNKNOWN and CATEGORY_SUCCESS, from 0 to 499 // DETAIL_UNKNOWN should not happen in normal case DETAIL_UNKNOWN = 0; From 85091845a8471a776df9461d476f733304b13c8e Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Thu, 14 Dec 2023 21:54:05 -0800 Subject: [PATCH 081/683] Turn AccountManager into pure abstract interface. PiperOrigin-RevId: 591143389 --- internal/platform/implementation/BUILD | 3 + .../platform/implementation/account_manager.h | 84 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 internal/platform/implementation/account_manager.h diff --git a/internal/platform/implementation/BUILD b/internal/platform/implementation/BUILD index d1743993..b672f4b0 100644 --- a/internal/platform/implementation/BUILD +++ b/internal/platform/implementation/BUILD @@ -16,6 +16,7 @@ licenses(["notice"]) cc_library( name = "types", hdrs = [ + "account_manager.h", "atomic_boolean.h", "atomic_reference.h", "bluetooth_adapter.h", @@ -41,6 +42,7 @@ cc_library( visibility = [ "//connections/implementation/analytics:__subpackages__", "//fastpair:__subpackages__", + "//internal/account:__pkg__", "//internal/crypto_cros:__pkg__", "//internal/platform:__pkg__", "//internal/platform/implementation:__subpackages__", @@ -57,6 +59,7 @@ cc_library( "//internal/platform:base", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/functional:any_invocable", + "@com_google_absl//absl/status", "@com_google_absl//absl/strings", "@com_google_absl//absl/time", "@com_google_absl//absl/types:span", diff --git a/internal/platform/implementation/account_manager.h b/internal/platform/implementation/account_manager.h new file mode 100644 index 00000000..80c58fdd --- /dev/null +++ b/internal/platform/implementation/account_manager.h @@ -0,0 +1,84 @@ +// Copyright 2022 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_API_ACCOUNT_MANAGER_H_ +#define PLATFORM_API_ACCOUNT_MANAGER_H_ + +#include +#include + +#include "absl/functional/any_invocable.h" +#include "absl/status/status.h" +#include "absl/strings/string_view.h" + +namespace nearby { + +// AccountManager manages the accounts are used to access Nearby backend. +// In current design, AccountManager only support one active account. +class AccountManager { + public: + // Describes a Nearby account. The account class will have more properties + // and methods in the future based on the new feature added. + struct Account { + std::string id; // The unique identify of the account. + std::string display_name; + std::string family_name; + std::string given_name; + std::string picture_url; + std::string email; + }; + + // Observes the activity of the account manager. + class Observer { + public: + virtual ~Observer() = default; + + virtual void OnLoginSucceeded(absl::string_view account_id) = 0; + virtual void OnLogoutSucceeded(absl::string_view account_id) = 0; + }; + + virtual ~AccountManager() = default; + + // Gets current active account. If no login user, return std::nullopt. + virtual std::optional GetCurrentAccount() = 0; + + // Initializes the login process for a Google account. + // |login_success_callback| is called when the login succeeded. Account + // information is passed to callback. + // |login_failure_callback| is called when the login fails. + virtual void Login(absl::AnyInvocable login_success_callback, + absl::AnyInvocable login_failure_callback) = 0; + + // Logs out current active account. |logout_callback| is called when logout is + // completed. + virtual void Logout( + absl::AnyInvocable logout_callback) = 0; + + // Gets access token for the active account. + // |success_callback| is called when an access token is fetched successfully. + // |failure_callback| is called when fetching an access token failed. + // + // Returns false if account_id is empty or callback is null. + virtual bool GetAccessToken( + absl::string_view account_id, + absl::AnyInvocable success_callback, + absl::AnyInvocable failure_callback) = 0; + + virtual void AddObserver(Observer* observer) = 0; + virtual void RemoveObserver(Observer* observer) = 0; +}; + +} // namespace nearby + +#endif // PLATFORM_API_ACCOUNT_MANAGER_H_ From cf69c87d950fa46af226d0f30ef6f88000e5604c Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Mon, 18 Dec 2023 11:40:09 -0800 Subject: [PATCH 082/683] Cleanup FakeAccountManager. - Remove unnecessary deps. PiperOrigin-RevId: 591964328 --- fastpair/internal/fast_pair_seeker_impl_test.cc | 17 ++--------------- .../fastpair/fast_pair_pairer_impl_test.cc | 14 +------------- fastpair/pairing/pairer_broker_impl_test.cc | 14 +------------- .../server_access/fast_pair_client_impl_test.cc | 14 +------------- 4 files changed, 5 insertions(+), 54 deletions(-) diff --git a/fastpair/internal/fast_pair_seeker_impl_test.cc b/fastpair/internal/fast_pair_seeker_impl_test.cc index 6738784a..f3e11089 100644 --- a/fastpair/internal/fast_pair_seeker_impl_test.cc +++ b/fastpair/internal/fast_pair_seeker_impl_test.cc @@ -26,7 +26,6 @@ #include "absl/status/status.h" #include "absl/strings/escaping.h" #include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/fast_pair_prefs.h" #include "fastpair/fast_pair_events.h" #include "fastpair/fast_pair_seeker.h" #include "fastpair/message_stream/fake_gatt_callbacks.h" @@ -41,8 +40,6 @@ #include "internal/platform/logging.h" #include "internal/platform/medium_environment.h" #include "internal/platform/single_thread_executor.h" -#include "internal/platform/task_runner_impl.h" -#include "internal/test/google3_only/fake_authentication_manager.h" namespace nearby { namespace fastpair { @@ -85,12 +82,7 @@ class FastPairRepositoryObserver : public FastPairRepository::Observer { class FastPairSeekerImplTest : public testing::Test { protected: - FastPairSeekerImplTest() { - task_runner_ = std::make_unique(1); - preferences_manager_ = std::make_unique( - kFastPairPreferencesFilePath); - authentication_manager_ = std::make_unique(); - } + FastPairSeekerImplTest() = default; void SetUp() override { NEARBY_LOG_SET_SEVERITY(VERBOSE); @@ -98,9 +90,7 @@ class FastPairSeekerImplTest : public testing::Test { kModelId, absl::HexStringToBytes(kBobPublicKey)); repository_->SetResultOfIsDeviceSavedToAccount( absl::NotFoundError("not found")); - account_manager_ = std::make_unique( - preferences_manager_.get(), prefs::kNearbyFastPairUsersName, - authentication_manager_.get(), task_runner_.get()); + account_manager_ = std::make_unique(); AccountManager::Account account; account.id = kTestAccountId; account_manager_->SetAccount(account); @@ -116,9 +106,6 @@ class FastPairSeekerImplTest : public testing::Test { MediumEnvironmentStarter env_; SingleThreadExecutor executor_; - std::unique_ptr preferences_manager_; - std::unique_ptr authentication_manager_; - std::unique_ptr task_runner_; std::unique_ptr account_manager_; FastPairDeviceRepository devices_{&executor_}; std::unique_ptr repository_; diff --git a/fastpair/pairing/fastpair/fast_pair_pairer_impl_test.cc b/fastpair/pairing/fastpair/fast_pair_pairer_impl_test.cc index d2eac0e5..8fa4dbde 100644 --- a/fastpair/pairing/fastpair/fast_pair_pairer_impl_test.cc +++ b/fastpair/pairing/fastpair/fast_pair_pairer_impl_test.cc @@ -34,7 +34,6 @@ #include "fastpair/common/account_key.h" #include "fastpair/common/device_metadata.h" #include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/fast_pair_prefs.h" #include "fastpair/common/fast_pair_version.h" #include "fastpair/common/protocol.h" #include "fastpair/crypto/decrypted_passkey.h" @@ -54,8 +53,6 @@ #include "internal/platform/count_down_latch.h" #include "internal/platform/medium_environment.h" #include "internal/platform/single_thread_executor.h" -#include "internal/platform/task_runner_impl.h" -#include "internal/test/google3_only/fake_authentication_manager.h" namespace nearby { namespace fastpair { @@ -137,18 +134,12 @@ class FastPairPairerImplTest : public testing::Test { FastPairPairerImplTest() { FastPairDataEncryptorImpl::Factory::SetFactoryForTesting( &fake_data_encryptor_factory_); - task_runner_ = std::make_unique(1); - preferences_manager_ = std::make_unique( - kFastPairPreferencesFilePath); - authentication_manager_ = std::make_unique(); } void SetUp() override { env_.Start(); // Setups seeker device. mediums_ = std::make_unique(); - account_manager_ = std::make_unique( - preferences_manager_.get(), prefs::kNearbyFastPairUsersName, - authentication_manager_.get(), task_runner_.get()); + account_manager_ = std::make_unique(); // Setups provider device. adapter_provider_ = std::make_unique(); @@ -384,9 +375,6 @@ class FastPairPairerImplTest : public testing::Test { private: MediumEnvironment& env_{MediumEnvironment::Instance()}; Mutex mutex_; - std::unique_ptr preferences_manager_; - std::unique_ptr authentication_manager_; - std::unique_ptr task_runner_; std::unique_ptr bt_provider_; std::unique_ptr adapter_provider_; std::unique_ptr gatt_server_; diff --git a/fastpair/pairing/pairer_broker_impl_test.cc b/fastpair/pairing/pairer_broker_impl_test.cc index d1d98648..334e290a 100644 --- a/fastpair/pairing/pairer_broker_impl_test.cc +++ b/fastpair/pairing/pairer_broker_impl_test.cc @@ -24,7 +24,6 @@ #include "gtest/gtest.h" #include "absl/functional/bind_front.h" #include "fastpair//handshake/fast_pair_handshake_lookup.h" -#include "fastpair/common/fast_pair_prefs.h" #include "fastpair/common/pair_failure.h" #include "fastpair/crypto/decrypted_passkey.h" #include "fastpair/crypto/decrypted_response.h" @@ -42,8 +41,6 @@ #include "internal/platform/ble_v2.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/medium_environment.h" -#include "internal/platform/task_runner_impl.h" -#include "internal/test/google3_only/fake_authentication_manager.h" namespace nearby { namespace fastpair { @@ -180,19 +177,13 @@ class PairerBrokerImplTest : public testing::Test { PairerBrokerImplTest() { FastPairDataEncryptorImpl::Factory::SetFactoryForTesting( &fake_data_encryptor_factory_); - task_runner_ = std::make_unique(1); - preferences_manager_ = std::make_unique( - kFastPairPreferencesFilePath); - authentication_manager_ = std::make_unique(); } void SetUp() override { env_.Start(); // Setups seeker device. mediums_ = std::make_unique(); - account_manager_ = std::make_unique( - preferences_manager_.get(), prefs::kNearbyFastPairUsersName, - authentication_manager_.get(), task_runner_.get()); + account_manager_ = std::make_unique(); // Setups provider device. adapter_provider_ = std::make_unique(); @@ -416,9 +407,6 @@ class PairerBrokerImplTest : public testing::Test { private: MediumEnvironment& env_{MediumEnvironment::Instance()}; Mutex mutex_; - std::unique_ptr preferences_manager_; - std::unique_ptr authentication_manager_; - std::unique_ptr task_runner_; std::unique_ptr bt_provider_; std::unique_ptr adapter_provider_; std::unique_ptr gatt_server_; diff --git a/fastpair/server_access/fast_pair_client_impl_test.cc b/fastpair/server_access/fast_pair_client_impl_test.cc index 255cfa18..80665de0 100644 --- a/fastpair/server_access/fast_pair_client_impl_test.cc +++ b/fastpair/server_access/fast_pair_client_impl_test.cc @@ -36,7 +36,6 @@ #include "fastpair/common/account_key.h" #include "fastpair/common/device_metadata.h" #include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/fast_pair_prefs.h" #include "fastpair/common/fast_pair_switches.h" #include "fastpair/common/protocol.h" #include "fastpair/proto/data.proto.h" @@ -45,7 +44,6 @@ #include "fastpair/proto/proto_builder.h" #include "fastpair/server_access/fast_pair_client.h" #include "fastpair/server_access/fast_pair_http_notifier.h" -#include "internal/account/account_manager.h" #include "internal/account/fake_account_manager.h" #include "internal/auth/auth_status_util.h" #include "internal/auth/authentication_manager.h" @@ -55,9 +53,6 @@ #include "internal/network/http_status_code.h" #include "internal/network/url.h" #include "internal/platform/device_info.h" -#include "internal/platform/task_runner.h" -#include "internal/platform/task_runner_impl.h" -#include "internal/preferences/preferences_manager.h" #include "internal/test/fake_device_info.h" #include "internal/test/google3_only/fake_authentication_manager.h" @@ -147,16 +142,11 @@ class FastPairClientImplTest : public ::testing::Test, public FastPairHttpNotifier::Observer { protected: FastPairClientImplTest() { - preferences_manager_ = std::make_unique( - kFastPairPreferencesFilePath); authentication_manager_ = std::make_unique(); AccountManager::Account account; account.id = kTestAccountId; - account_manager_ = std::make_unique( - preferences_manager_.get(), prefs::kNearbyFastPairUsersName, - authentication_manager_.get(), task_runner_.get()); + account_manager_ = std::make_unique(); account_manager_->SetAccount(account); - task_runner_ = std::make_unique(1); device_info_ = std::make_unique(); } @@ -235,12 +225,10 @@ class FastPairClientImplTest : public ::testing::Test, std::optional delete_device_request_; std::optional delete_device_response_; - std::unique_ptr preferences_manager_; std::unique_ptr authentication_manager_; std::unique_ptr account_manager_; std::unique_ptr fast_pair_client_; std::unique_ptr device_info_; - std::unique_ptr task_runner_; ::testing::NiceMock* http_client_; std::unique_ptr mock_http_client_; FastPairHttpNotifier notifier_; From 32740f8591a568a2e3a6f54b018cd0874e5af2ff Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Mon, 18 Dec 2023 17:29:11 -0800 Subject: [PATCH 083/683] Move FakeAccountManager to nearby/internal/test PiperOrigin-RevId: 592055356 --- fastpair/BUILD | 2 +- fastpair/fast_pair_service_test.cc | 14 ++- fastpair/internal/BUILD | 3 +- .../internal/fast_pair_seeker_impl_test.cc | 4 +- fastpair/pairing/BUILD | 3 +- fastpair/pairing/fastpair/BUILD | 3 +- .../fastpair/fast_pair_pairer_impl_test.cc | 2 +- fastpair/pairing/pairer_broker_impl_test.cc | 2 +- fastpair/server_access/BUILD | 1 - .../fast_pair_client_impl_test.cc | 2 +- internal/base/BUILD | 1 + internal/test/BUILD | 3 + internal/test/fake_account_manager.cc | 112 ++++++++++++++++++ internal/test/fake_account_manager.h | 75 ++++++++++++ 14 files changed, 208 insertions(+), 19 deletions(-) create mode 100644 internal/test/fake_account_manager.cc create mode 100644 internal/test/fake_account_manager.h diff --git a/fastpair/BUILD b/fastpair/BUILD index 453b6db5..8f1c42aa 100644 --- a/fastpair/BUILD +++ b/fastpair/BUILD @@ -132,7 +132,7 @@ cc_test( "//fastpair/internal", "//fastpair/message_stream:fake_provider", "//fastpair/plugins:fake_fast_pair_plugin", - "//internal/account:test_support", + "//internal/account", "//internal/network:types", "//internal/platform:test_util", "//internal/platform:types", diff --git a/fastpair/fast_pair_service_test.cc b/fastpair/fast_pair_service_test.cc index 8a3407a6..7ab94f97 100644 --- a/fastpair/fast_pair_service_test.cc +++ b/fastpair/fast_pair_service_test.cc @@ -25,11 +25,12 @@ #include "fastpair/internal/fast_pair_seeker_impl.h" #include "fastpair/message_stream/fake_provider.h" #include "fastpair/plugins/fake_fast_pair_plugin.h" -#include "internal/account/fake_account_manager.h" +#include "internal/account/account_manager_impl.h" #include "internal/network/http_client.h" #include "internal/platform/device_info.h" #include "internal/platform/logging.h" #include "internal/platform/medium_environment.h" +#include "internal/test/fake_account_manager.h" #include "internal/test/fake_device_info.h" #include "internal/test/fake_http_client.h" #include "internal/test/google3_only/fake_authentication_manager.h" @@ -48,8 +49,9 @@ using ::testing::status::StatusIs; class FastPairServiceTest : public ::testing::Test { protected: FastPairServiceTest() { - AccountManagerImpl::Factory::SetFactoryForTesting( - &account_manager_factory_); + AccountManagerImpl::Factory::SetFactoryForTesting([]() { + return std::make_unique(); + }); http_client_ = std::make_unique(); device_info_ = std::make_unique(); authentication_manager_ = @@ -61,7 +63,10 @@ class FastPairServiceTest : public ::testing::Test { GetAuthManager()->EnableSyncMode(); } - void TearDown() override { MediumEnvironment::Instance().Stop(); } + void TearDown() override { + AccountManagerImpl::Factory::SetFactoryForTesting(nullptr); + MediumEnvironment::Instance().Stop(); + } nearby::FakeAuthenticationManager* GetAuthManager() { return reinterpret_cast( @@ -84,7 +89,6 @@ class FastPairServiceTest : public ::testing::Test { GetHttpClient()->SetResponseForSyncRequest(response); } - FakeAccountManager::Factory account_manager_factory_; std::unique_ptr authentication_manager_; std::unique_ptr http_client_; std::unique_ptr device_info_; diff --git a/fastpair/internal/BUILD b/fastpair/internal/BUILD index 3742f983..65041ef1 100644 --- a/fastpair/internal/BUILD +++ b/fastpair/internal/BUILD @@ -44,11 +44,10 @@ cc_test( "//fastpair/repository", "//fastpair/repository:device_repository", "//fastpair/repository:test_support", - "//internal/account:test_support", "//internal/platform:test_util", "//internal/platform:types", "//internal/platform/implementation/g3", # build_cleaner: keep - "//internal/test/google3_only:test", + "//internal/test", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/status", "@com_google_absl//absl/strings", diff --git a/fastpair/internal/fast_pair_seeker_impl_test.cc b/fastpair/internal/fast_pair_seeker_impl_test.cc index f3e11089..f49f262b 100644 --- a/fastpair/internal/fast_pair_seeker_impl_test.cc +++ b/fastpair/internal/fast_pair_seeker_impl_test.cc @@ -35,11 +35,11 @@ #include "fastpair/repository/fake_fast_pair_repository.h" #include "fastpair/repository/fast_pair_device_repository.h" #include "fastpair/repository/fast_pair_repository.h" -#include "internal/account/fake_account_manager.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/logging.h" #include "internal/platform/medium_environment.h" #include "internal/platform/single_thread_executor.h" +#include "internal/test/fake_account_manager.h" namespace nearby { namespace fastpair { @@ -55,8 +55,6 @@ constexpr absl::string_view kBobPublicKey = "F7D496A62ECA416351540AA343BC690A6109F551500666B83B1251FB84FA2860795EBD63D3" "B8836F44A9A3E28BB34017E015F5979305D849FDF8DE10123B61D2"; constexpr absl::string_view kPasskey = "123456"; -constexpr absl::string_view kFastPairPreferencesFilePath = - "Google/Nearby/FastPair"; constexpr absl::string_view kTestAccountId = "test_account_id"; using ::testing::status::StatusIs; diff --git a/fastpair/pairing/BUILD b/fastpair/pairing/BUILD index 65a485aa..ab0fe961 100644 --- a/fastpair/pairing/BUILD +++ b/fastpair/pairing/BUILD @@ -60,14 +60,13 @@ cc_test( "//fastpair/proto:fastpair_cc_proto", "//fastpair/repository:test_support", "//internal/account", - "//internal/account:test_support", "//internal/auth:credential", "//internal/base:bluetooth_address", "//internal/platform:comm", "//internal/platform:test_util", "//internal/platform:types", "//internal/platform/implementation/g3", # build_cleaner: keep - "//internal/test/google3_only:test", + "//internal/test", "@boringssl//:crypto", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/functional:bind_front", diff --git a/fastpair/pairing/fastpair/BUILD b/fastpair/pairing/fastpair/BUILD index c748b211..b584b20d 100644 --- a/fastpair/pairing/fastpair/BUILD +++ b/fastpair/pairing/fastpair/BUILD @@ -58,14 +58,13 @@ cc_test( "//fastpair/proto:fastpair_cc_proto", "//fastpair/repository:test_support", "//internal/account", - "//internal/account:test_support", "//internal/auth:credential", "//internal/base:bluetooth_address", "//internal/platform:comm", "//internal/platform:test_util", "//internal/platform:types", "//internal/platform/implementation/g3", # build_cleaner: keep - "//internal/test/google3_only:test", + "//internal/test", "@boringssl//:crypto", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/functional:any_invocable", diff --git a/fastpair/pairing/fastpair/fast_pair_pairer_impl_test.cc b/fastpair/pairing/fastpair/fast_pair_pairer_impl_test.cc index 8fa4dbde..19e31b5d 100644 --- a/fastpair/pairing/fastpair/fast_pair_pairer_impl_test.cc +++ b/fastpair/pairing/fastpair/fast_pair_pairer_impl_test.cc @@ -46,13 +46,13 @@ #include "fastpair/pairing/fastpair/fast_pair_pairer.h" #include "fastpair/proto/fastpair_rpcs.proto.h" #include "fastpair/repository/fake_fast_pair_repository.h" -#include "internal/account/fake_account_manager.h" #include "internal/base/bluetooth_address.h" #include "internal/platform/ble_v2.h" #include "internal/platform/bluetooth_adapter.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/medium_environment.h" #include "internal/platform/single_thread_executor.h" +#include "internal/test/fake_account_manager.h" namespace nearby { namespace fastpair { diff --git a/fastpair/pairing/pairer_broker_impl_test.cc b/fastpair/pairing/pairer_broker_impl_test.cc index 334e290a..4a138f31 100644 --- a/fastpair/pairing/pairer_broker_impl_test.cc +++ b/fastpair/pairing/pairer_broker_impl_test.cc @@ -36,11 +36,11 @@ #include "fastpair/internal/mediums/mediums.h" #include "fastpair/proto/fastpair_rpcs.proto.h" #include "fastpair/repository/fake_fast_pair_repository.h" -#include "internal/account/fake_account_manager.h" #include "internal/base/bluetooth_address.h" #include "internal/platform/ble_v2.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/medium_environment.h" +#include "internal/test/fake_account_manager.h" namespace nearby { namespace fastpair { diff --git a/fastpair/server_access/BUILD b/fastpair/server_access/BUILD index 6ca7f1dc..939df87f 100644 --- a/fastpair/server_access/BUILD +++ b/fastpair/server_access/BUILD @@ -93,7 +93,6 @@ cc_test( "//fastpair/proto:fastpair_cc_proto", "//fastpair/proto:proto_builder", "//internal/account", - "//internal/account:test_support", "//internal/auth:credential", "//internal/auth:types", "//internal/network:types", diff --git a/fastpair/server_access/fast_pair_client_impl_test.cc b/fastpair/server_access/fast_pair_client_impl_test.cc index 80665de0..e8b86a60 100644 --- a/fastpair/server_access/fast_pair_client_impl_test.cc +++ b/fastpair/server_access/fast_pair_client_impl_test.cc @@ -44,7 +44,6 @@ #include "fastpair/proto/proto_builder.h" #include "fastpair/server_access/fast_pair_client.h" #include "fastpair/server_access/fast_pair_http_notifier.h" -#include "internal/account/fake_account_manager.h" #include "internal/auth/auth_status_util.h" #include "internal/auth/authentication_manager.h" #include "internal/network/http_client.h" @@ -53,6 +52,7 @@ #include "internal/network/http_status_code.h" #include "internal/network/url.h" #include "internal/platform/device_info.h" +#include "internal/test/fake_account_manager.h" #include "internal/test/fake_device_info.h" #include "internal/test/google3_only/fake_authentication_manager.h" diff --git a/internal/base/BUILD b/internal/base/BUILD index a07f30d3..35d66268 100644 --- a/internal/base/BUILD +++ b/internal/base/BUILD @@ -15,6 +15,7 @@ cc_library( "//internal/account:__subpackages__", "//internal/interop:__pkg__", "//internal/platform:__pkg__", + "//internal/test:__pkg__", "//location/nearby/cpp/experiments:__subpackages__", "//location/nearby/cpp/sharing:__subpackages__", "//third_party/nearby/sharing:__subpackages__", diff --git a/internal/test/BUILD b/internal/test/BUILD index e3227fe4..7512570d 100644 --- a/internal/test/BUILD +++ b/internal/test/BUILD @@ -17,6 +17,7 @@ licenses(["notice"]) cc_library( name = "test", srcs = [ + "fake_account_manager.cc", "fake_clock.cc", "fake_single_thread_executor.cc", "fake_task_runner.cc", @@ -24,6 +25,7 @@ cc_library( "fake_webrtc.cc", ], hdrs = [ + "fake_account_manager.h", "fake_clock.h", "fake_data_set.h", "fake_device_info.h", @@ -39,6 +41,7 @@ cc_library( ], visibility = ["//visibility:public"], deps = [ + "//internal/base", "//internal/base:bluetooth_address", "//internal/data:data_manager", "//internal/network:types", diff --git a/internal/test/fake_account_manager.cc b/internal/test/fake_account_manager.cc new file mode 100644 index 00000000..91ac547c --- /dev/null +++ b/internal/test/fake_account_manager.cc @@ -0,0 +1,112 @@ +// Copyright 2022 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 "internal/test/fake_account_manager.h" + +#include +#include + +#include "absl/functional/any_invocable.h" +#include "absl/status/status.h" +#include "absl/strings/string_view.h" +#include "internal/platform/implementation/account_manager.h" + +namespace nearby { + +std::optional FakeAccountManager::GetCurrentAccount() { + if (user_name_.has_value()) { + return account_; + } + return std::nullopt; +} + +void FakeAccountManager::Login( + absl::AnyInvocable login_success_callback, + absl::AnyInvocable login_failure_callback) { + if (account_.has_value()) { + login_success_callback(*account_); + UpdateCurrentUser(account_->id); + NotifyLogin(account_->id); + return; + } + + login_failure_callback(); +} + +void FakeAccountManager::Logout( + absl::AnyInvocable logout_callback) { + if (is_logout_success_) { + std::string account_id = account_->id; + SetAccount(std::nullopt); + logout_callback(absl::OkStatus()); + NotifyLogout(account_id); + return; + } + + logout_callback(absl::NotFoundError("No account login.")); +} + +bool FakeAccountManager::GetAccessToken( + absl::string_view account_id, + absl::AnyInvocable success_callback, + absl::AnyInvocable failure_callback) { + if (!account_.has_value()) { + failure_callback(absl::UnavailableError("No current user.")); + return false; + } + success_callback(account_id); + return true; +} + +void FakeAccountManager::SetAccount(std::optional account) { + account_ = account; + if (account_.has_value()) { + UpdateCurrentUser(account_->id); + } else { + ClearCurrentUser(); + } +} + +void FakeAccountManager::UpdateCurrentUser(absl::string_view current_user) { + user_name_ = current_user; +} + +void FakeAccountManager::ClearCurrentUser() { + user_name_.reset(); +} + +void FakeAccountManager::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void FakeAccountManager::RemoveObserver(Observer* observer) { + if (!observers_.HasObserver(observer)) { + return; + } + observers_.RemoveObserver(observer); +} + +void FakeAccountManager::NotifyLogin(absl::string_view account_id) { + for (const auto& observer : observers_.GetObservers()) { + observer->OnLoginSucceeded(account_id); + } +} + +void FakeAccountManager::NotifyLogout(absl::string_view account_id) { + for (const auto& observer : observers_.GetObservers()) { + observer->OnLogoutSucceeded(account_id); + } +} + +} // namespace nearby diff --git a/internal/test/fake_account_manager.h b/internal/test/fake_account_manager.h new file mode 100644 index 00000000..a1e5791c --- /dev/null +++ b/internal/test/fake_account_manager.h @@ -0,0 +1,75 @@ +// Copyright 2022 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 THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_ACCOUNT_MANAGER_H_ +#define THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_ACCOUNT_MANAGER_H_ + +#include +#include + +#include "absl/functional/any_invocable.h" +#include "absl/status/status.h" +#include "absl/strings/string_view.h" +#include "internal/base/observer_list.h" +#include "internal/platform/implementation/account_manager.h" + +namespace nearby { + +// A fake implementation of FakeAccountManager, along with a fake +// factory, to be used in tests. +class FakeAccountManager : public AccountManager { + public: + FakeAccountManager() = default; + ~FakeAccountManager() override = default; + + std::optional GetCurrentAccount() override; + + void Login(absl::AnyInvocable login_success_callback, + absl::AnyInvocable login_failure_callback) override; + + void Logout(absl::AnyInvocable logout_callback) override; + + bool GetAccessToken( + absl::string_view account_id, + absl::AnyInvocable success_callback, + absl::AnyInvocable failure_callback) override; + void AddObserver(Observer* observer) override; + void RemoveObserver(Observer* observer) override; + + // Methods to set API response. + void SetAccount(std::optional account); + + void SetLogoutSuccess(bool is_logout_success) { + is_logout_success_ = is_logout_success; + } + + private: + // Updates current username to preference. + void UpdateCurrentUser(absl::string_view current_user); + void ClearCurrentUser(); + void NotifyLogin(absl::string_view account_id); + void NotifyLogout(absl::string_view account_id); + + // Login will fail when account_ is empty. + std::optional account_; + + // Logout will fail when is_logout_success_ is false; + bool is_logout_success_ = true; + nearby::ObserverList observers_; + std::optional user_name_; +}; + +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_ACCOUNT_MANAGER_H_ From 63e744e1338412c5ad17094f22445c6dfe71de6e Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Mon, 18 Dec 2023 19:10:52 -0800 Subject: [PATCH 084/683] Finish migrating account_manager.h to new location. PiperOrigin-RevId: 592074168 --- fastpair/BUILD | 1 + fastpair/fast_pair_service.h | 2 +- fastpair/pairing/BUILD | 2 +- fastpair/pairing/fastpair/BUILD | 2 +- fastpair/pairing/fastpair/fast_pair_pairer_impl.h | 2 +- fastpair/pairing/pairer_broker_impl.h | 2 +- fastpair/retroactive/BUILD | 2 +- fastpair/retroactive/retroactive_pairing_detector_impl.cc | 2 +- fastpair/retroactive/retroactive_pairing_detector_impl.h | 2 +- fastpair/server_access/BUILD | 1 - fastpair/server_access/fast_pair_client_impl.cc | 2 +- fastpair/server_access/fast_pair_client_impl.h | 2 +- internal/platform/implementation/windows/webrtc.h | 2 +- 13 files changed, 12 insertions(+), 12 deletions(-) diff --git a/fastpair/BUILD b/fastpair/BUILD index 8f1c42aa..fb5c746b 100644 --- a/fastpair/BUILD +++ b/fastpair/BUILD @@ -112,6 +112,7 @@ cc_library( "//internal/platform:base", "//internal/platform:types", "//internal/platform/flags:platform_flags", + "//internal/platform/implementation:types", "//internal/preferences", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/status", diff --git a/fastpair/fast_pair_service.h b/fastpair/fast_pair_service.h index ee5e4520..10c95cf0 100644 --- a/fastpair/fast_pair_service.h +++ b/fastpair/fast_pair_service.h @@ -27,10 +27,10 @@ #include "fastpair/server_access/fast_pair_client.h" #include "fastpair/server_access/fast_pair_http_notifier.h" #include "fastpair/repository/fast_pair_repository.h" -#include "internal/account/account_manager.h" #include "internal/auth/authentication_manager.h" #include "internal/network/http_client.h" #include "internal/platform/device_info.h" +#include "internal/platform/implementation/account_manager.h" #include "internal/platform/single_thread_executor.h" #include "internal/platform/task_runner.h" #include "internal/preferences/preferences_manager.h" diff --git a/fastpair/pairing/BUILD b/fastpair/pairing/BUILD index ab0fe961..e643d7c4 100644 --- a/fastpair/pairing/BUILD +++ b/fastpair/pairing/BUILD @@ -33,9 +33,9 @@ cc_library( "//fastpair/handshake", "//fastpair/internal/mediums", "//fastpair/pairing/fastpair:pairing", - "//internal/account", "//internal/base", "//internal/platform:types", + "//internal/platform/implementation:types", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/functional:bind_front", "@com_google_absl//absl/synchronization", diff --git a/fastpair/pairing/fastpair/BUILD b/fastpair/pairing/fastpair/BUILD index b584b20d..999f839e 100644 --- a/fastpair/pairing/fastpair/BUILD +++ b/fastpair/pairing/fastpair/BUILD @@ -34,9 +34,9 @@ cc_library( "//fastpair/handshake", "//fastpair/internal/mediums", "//fastpair/repository", - "//internal/account", "//internal/platform:comm", "//internal/platform:types", + "//internal/platform/implementation:types", "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/time", ], diff --git a/fastpair/pairing/fastpair/fast_pair_pairer_impl.h b/fastpair/pairing/fastpair/fast_pair_pairer_impl.h index 9024e636..dd7d87c9 100644 --- a/fastpair/pairing/fastpair/fast_pair_pairer_impl.h +++ b/fastpair/pairing/fastpair/fast_pair_pairer_impl.h @@ -26,8 +26,8 @@ #include "fastpair/handshake/fast_pair_handshake.h" #include "fastpair/internal/mediums/mediums.h" #include "fastpair/pairing/fastpair/fast_pair_pairer.h" -#include "internal/account/account_manager.h" #include "internal/platform/bluetooth_classic.h" +#include "internal/platform/implementation/account_manager.h" #include "internal/platform/single_thread_executor.h" #include "internal/platform/timer_impl.h" diff --git a/fastpair/pairing/pairer_broker_impl.h b/fastpair/pairing/pairer_broker_impl.h index 0c88d975..3fc28106 100644 --- a/fastpair/pairing/pairer_broker_impl.h +++ b/fastpair/pairing/pairer_broker_impl.h @@ -24,8 +24,8 @@ #include "fastpair/internal/mediums/mediums.h" #include "fastpair/pairing/fastpair/fast_pair_pairer.h" #include "fastpair/pairing/pairer_broker.h" -#include "internal/account/account_manager.h" #include "internal/base/observer_list.h" +#include "internal/platform/implementation/account_manager.h" #include "internal/platform/single_thread_executor.h" #include "internal/platform/timer_impl.h" diff --git a/fastpair/retroactive/BUILD b/fastpair/retroactive/BUILD index 63315b12..257aa853 100644 --- a/fastpair/retroactive/BUILD +++ b/fastpair/retroactive/BUILD @@ -38,10 +38,10 @@ cc_library( "//fastpair/pairing", "//fastpair/repository", "//fastpair/repository:device_repository", - "//internal/account", "//internal/base", "//internal/platform:comm", "//internal/platform:types", + "//internal/platform/implementation:types", "//third_party/magic_enum", "@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/status", diff --git a/fastpair/retroactive/retroactive_pairing_detector_impl.cc b/fastpair/retroactive/retroactive_pairing_detector_impl.cc index 40b4c579..5bcffb73 100644 --- a/fastpair/retroactive/retroactive_pairing_detector_impl.cc +++ b/fastpair/retroactive/retroactive_pairing_detector_impl.cc @@ -22,7 +22,7 @@ #include "fastpair/internal/mediums/mediums.h" #include "fastpair/repository/fast_pair_repository.h" -#include "internal/account/account_manager.h" +#include "internal/platform/implementation/account_manager.h" namespace nearby { namespace fastpair { diff --git a/fastpair/retroactive/retroactive_pairing_detector_impl.h b/fastpair/retroactive/retroactive_pairing_detector_impl.h index 7c876f86..796fb347 100644 --- a/fastpair/retroactive/retroactive_pairing_detector_impl.h +++ b/fastpair/retroactive/retroactive_pairing_detector_impl.h @@ -19,9 +19,9 @@ #include "fastpair/internal/mediums/mediums.h" #include "fastpair/repository/fast_pair_device_repository.h" #include "fastpair/retroactive/retroactive_pairing_detector.h" -#include "internal/account/account_manager.h" #include "internal/base/observer_list.h" #include "internal/platform/bluetooth_classic.h" +#include "internal/platform/implementation/account_manager.h" #include "internal/platform/single_thread_executor.h" namespace nearby { diff --git a/fastpair/server_access/BUILD b/fastpair/server_access/BUILD index 939df87f..8c22188a 100644 --- a/fastpair/server_access/BUILD +++ b/fastpair/server_access/BUILD @@ -32,7 +32,6 @@ cc_library( "//fastpair/common", "//fastpair/proto:fastpair_cc_proto", "//fastpair/proto:proto_to_json", - "//internal/account", "//internal/auth:credential", "//internal/auth:types", "//internal/base", diff --git a/fastpair/server_access/fast_pair_client_impl.cc b/fastpair/server_access/fast_pair_client_impl.cc index 21590686..515c65f1 100644 --- a/fastpair/server_access/fast_pair_client_impl.cc +++ b/fastpair/server_access/fast_pair_client_impl.cc @@ -27,7 +27,6 @@ #include "absl/synchronization/notification.h" #include "fastpair/common/fast_pair_switches.h" #include "fastpair/server_access/fast_pair_http_notifier.h" -#include "internal/account/account_manager.h" #include "internal/auth/auth_status_util.h" #include "internal/auth/authentication_manager.h" #include "internal/network/http_client.h" @@ -35,6 +34,7 @@ #include "internal/network/http_response.h" #include "internal/network/url.h" #include "internal/platform/device_info.h" +#include "internal/platform/implementation/account_manager.h" #include "internal/platform/implementation/device_info.h" #include "internal/platform/logging.h" diff --git a/fastpair/server_access/fast_pair_client_impl.h b/fastpair/server_access/fast_pair_client_impl.h index d86e8276..f24a965d 100644 --- a/fastpair/server_access/fast_pair_client_impl.h +++ b/fastpair/server_access/fast_pair_client_impl.h @@ -24,11 +24,11 @@ #include "absl/strings/string_view.h" #include "fastpair/server_access/fast_pair_client.h" #include "fastpair/server_access/fast_pair_http_notifier.h" -#include "internal/account/account_manager.h" #include "internal/auth/authentication_manager.h" #include "internal/network/http_client.h" #include "internal/network/url.h" #include "internal/platform/device_info.h" +#include "internal/platform/implementation/account_manager.h" namespace nearby { namespace fastpair { diff --git a/internal/platform/implementation/windows/webrtc.h b/internal/platform/implementation/windows/webrtc.h index 50f0b32f..ae9c76cf 100644 --- a/internal/platform/implementation/windows/webrtc.h +++ b/internal/platform/implementation/windows/webrtc.h @@ -17,7 +17,7 @@ #include -#include "internal/account/account_manager.h" +#include "internal/platform/implementation/account_manager.h" #include "internal/platform/implementation/webrtc.h" namespace nearby { From 850c3e2788015668572249d205d91d6af78c5739 Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Tue, 19 Dec 2023 08:44:45 -0800 Subject: [PATCH 085/683] Fixed the bug of passing connection request info PiperOrigin-RevId: 592248269 --- connections/c/core_adapter.cc | 2 +- connections/dart/core_adapter_dart.cc | 4 +++- connections/dart/core_adapter_dart.h | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/connections/c/core_adapter.cc b/connections/c/core_adapter.cc index 920c7aa4..4897ffe9 100644 --- a/connections/c/core_adapter.cc +++ b/connections/c/core_adapter.cc @@ -44,7 +44,7 @@ void StartAdvertising(Core *pCore, const char *service_id, } connections::ConnectionRequestInfo crInfo; - crInfo.endpoint_info = ByteArray(info.endpoint_info); + crInfo.endpoint_info = ByteArray(info.endpoint_info, info.endpoint_info_size); crInfo.listener = std::move(*(info.listener.GetImpl())); connections::AdvertisingOptions advertising_options; diff --git a/connections/dart/core_adapter_dart.cc b/connections/dart/core_adapter_dart.cc index 149b9f1f..e91e9a62 100644 --- a/connections/dart/core_adapter_dart.cc +++ b/connections/dart/core_adapter_dart.cc @@ -14,6 +14,7 @@ #include "connections/dart/core_adapter_dart.h" +#include #include #include @@ -424,7 +425,8 @@ void StartAdvertisingDart( ConnectionRequestInfoW info{ connection_request_info_dart.endpoint_info, - strlen(connection_request_info_dart.endpoint_info), listener}; + static_cast(connection_request_info_dart.endpoint_info_size), + listener}; ResultCallbackW callback; SetResultCallback(callback, result_cb); diff --git a/connections/dart/core_adapter_dart.h b/connections/dart/core_adapter_dart.h index 63d7aa64..e74f5a8b 100644 --- a/connections/dart/core_adapter_dart.h +++ b/connections/dart/core_adapter_dart.h @@ -132,6 +132,7 @@ struct ConnectionListenerDart { struct ConnectionRequestInfoDart { // LINT.IfChange + int endpoint_info_size; char *endpoint_info; ConnectionListenerDart connection_listener; // LINT.ThenChange(//depot/google3/location/nearby/apps/helloconnections/plugins/nearby_connections/platform/lib/types/connection_request_info.dart) From 16cb7f70b3a8b8b04440b7b96534e11df964ca60 Mon Sep 17 00:00:00 2001 From: hai007 Date: Tue, 19 Dec 2023 14:26:19 -0800 Subject: [PATCH 086/683] Implement Auto-reconnect after disconnection [1] PiperOrigin-RevId: 592344338 --- Package.swift | 2 + connections/implementation/BUILD | 6 + .../implementation/bluetooth_bwu_handler.cc | 1 + .../implementation/bluetooth_bwu_test.cc | 126 +++ connections/implementation/client_proxy.cc | 44 +- connections/implementation/client_proxy.h | 19 + .../flags/nearby_connections_feature_flags.h | 4 + connections/implementation/offline_frames.cc | 28 + connections/implementation/offline_frames.h | 2 + .../implementation/offline_frames_test.cc | 37 + .../implementation/p2p_cluster_pcp_handler.cc | 1 + .../implementation/reconnect_manager.cc | 864 ++++++++++++++++++ .../implementation/reconnect_manager.h | 237 +++++ .../implementation/reconnect_manager_test.cc | 149 +++ .../implementation/service_id_constants.h | 33 + connections/implementation/simulation_user.h | 21 +- internal/platform/feature_flags.h | 8 + internal/platform/implementation/BUILD | 1 + 18 files changed, 1576 insertions(+), 7 deletions(-) create mode 100644 connections/implementation/bluetooth_bwu_test.cc create mode 100644 connections/implementation/reconnect_manager.cc create mode 100644 connections/implementation/reconnect_manager.h create mode 100644 connections/implementation/reconnect_manager_test.cc diff --git a/Package.swift b/Package.swift index 713cef3e..394ea817 100644 --- a/Package.swift +++ b/Package.swift @@ -429,6 +429,7 @@ let package = Package( "connections/implementation/payload_manager_test.cc", "connections/implementation/offline_frames_validator_test.cc", "connections/implementation/service_controller_router_test.cc", + "connections/implementation/bluetooth_bwu_test.cc", "connections/implementation/wifi_direct_bwu_test.cc", "connections/implementation/wifi_hotspot_test.cc", "connections/implementation/analytics/analytics_recorder_test.cc", @@ -461,6 +462,7 @@ let package = Package( "connections/implementation/pcp_manager_test.cc", "connections/implementation/ble_advertisement_test.cc", "connections/implementation/base_endpoint_channel_test.cc", + "connections/implementation/reconnect_manager_test.cc", "connections/v3/connections_device_test.cc", "connections/v3/connections_device_provider_test.cc", "connections/implementation/connections_authentication_transport_test.cc", diff --git a/connections/implementation/BUILD b/connections/implementation/BUILD index 4a42d633..2564fbf8 100644 --- a/connections/implementation/BUILD +++ b/connections/implementation/BUILD @@ -42,6 +42,7 @@ cc_library( "p2p_star_pcp_handler.cc", "payload_manager.cc", "pcp_manager.cc", + "reconnect_manager.cc", "service_controller_router.cc", "webrtc_bwu_handler.cc", "webrtc_bwu_handler_stub.cc", @@ -85,6 +86,7 @@ cc_library( "pcp.h", "pcp_handler.h", "pcp_manager.h", + "reconnect_manager.h", "service_controller.h", "service_controller_router.h", "service_id_constants.h", @@ -130,6 +132,7 @@ cc_library( "//internal/platform:util", "//internal/platform/implementation:comm", "//internal/platform/implementation:platform", + "//internal/platform/implementation:types", "//internal/proto/analytics:connections_log_cc_proto", "//proto:connections_enums_cc_proto", "@com_google_absl//absl/base:core_headers", @@ -138,6 +141,7 @@ cc_library( "@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/functional:bind_front", + "@com_google_absl//absl/log:check", "@com_google_absl//absl/memory", "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", @@ -204,6 +208,7 @@ cc_test( "base_endpoint_channel_test.cc", "base_pcp_handler_test.cc", "ble_advertisement_test.cc", + "bluetooth_bwu_test.cc", "bluetooth_device_name_test.cc", "bwu_manager_test.cc", "client_proxy_test.cc", @@ -219,6 +224,7 @@ cc_test( "p2p_point_to_point_pcp_handler_test.cc", "payload_manager_test.cc", "pcp_manager_test.cc", + "reconnect_manager_test.cc", "service_controller_router_test.cc", "wifi_direct_bwu_test.cc", "wifi_hotspot_test.cc", diff --git a/connections/implementation/bluetooth_bwu_handler.cc b/connections/implementation/bluetooth_bwu_handler.cc index 21328239..7b71e610 100644 --- a/connections/implementation/bluetooth_bwu_handler.cc +++ b/connections/implementation/bluetooth_bwu_handler.cc @@ -93,6 +93,7 @@ BluetoothBwuHandler::CreateUpgradedEndpointChannel( return nullptr; } + client->SetBluetoothMacAddress(endpoint_id, mac_address); return channel; } diff --git a/connections/implementation/bluetooth_bwu_test.cc b/connections/implementation/bluetooth_bwu_test.cc new file mode 100644 index 00000000..6b0b9897 --- /dev/null +++ b/connections/implementation/bluetooth_bwu_test.cc @@ -0,0 +1,126 @@ +// Copyright 2022 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 + +#include "gtest/gtest.h" +#include "absl/time/time.h" +#include "connections/implementation/bwu_handler.h" +#include "connections/implementation/bluetooth_bwu_handler.h" +#include "connections/implementation/client_proxy.h" +#include "connections/implementation/endpoint_channel.h" +#include "connections/implementation/mediums/mediums.h" +#include "connections/implementation/offline_frames.h" +#include "internal/platform/byte_array.h" +#include "internal/platform/count_down_latch.h" +#include "internal/platform/exception.h" +#include "internal/platform/feature_flags.h" +#include "internal/platform/logging.h" +#include "internal/platform/medium_environment.h" +#include "internal/platform/single_thread_executor.h" + +namespace nearby { +namespace connections { + +namespace { +using ::location::nearby::connections::OfflineFrame; +constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000); +} // namespace + +class BluetoothBwuTest : public testing::Test { + protected: + BluetoothBwuTest() { env_.Start(); } + ~BluetoothBwuTest() override { env_.Stop(); } + + MediumEnvironment& env_{MediumEnvironment::Instance()}; +}; + +TEST_F(BluetoothBwuTest, CanCreateBwuHandler) { + ClientProxy client; + Mediums mediums; + + auto handler = std::make_unique(mediums, nullptr); + + handler->InitializeUpgradedMediumForEndpoint(&client, /*service_id=*/"B", + /*endpoint_id=*/"2"); + handler->RevertInitiatorState(); + SUCCEED(); + handler.reset(); +} + +TEST_F(BluetoothBwuTest, SoftAPBWUInit_STACreateEndpointChannel) { + CountDownLatch start_latch(1); + CountDownLatch accept_latch(1); + CountDownLatch end_latch(1); + + ClientProxy client_1, client_2; + Mediums mediums_1, mediums_2; + ExceptionOr upgrade_frame; + + auto handler_1 = std::make_unique( + mediums_1, [&](ClientProxy* client, + std::unique_ptr + mutable_connection) { + NEARBY_LOGS(WARNING) << "Server socket connection accept call back"; + accept_latch.CountDown(); + EXPECT_TRUE(end_latch.Await(kWaitDuration).result()); + }); + + // client_1 works as Bluetooth Server Device + SingleThreadExecutor server_executor; + server_executor.Execute([&]() { + ByteArray upgrade_path_available_frame = + handler_1->InitializeUpgradedMediumForEndpoint(&client_1, + /*service_id=*/"A", + /*endpoint_id=*/"1"); + EXPECT_FALSE(upgrade_path_available_frame.Empty()); + + upgrade_frame = parser::FromBytes(upgrade_path_available_frame); + start_latch.CountDown(); + }); + + // client_2 works as Bluetooth Client Device which will connect to client_1 + SingleThreadExecutor client_executor; + // Wait till client_1 started as Bluetooth and then connect to it + EXPECT_TRUE(start_latch.Await(kWaitDuration).result()); + std::unique_ptr handler_2 = + std::make_unique(mediums_2, nullptr); + + client_executor.Execute([&]() { + auto bwu_frame = + upgrade_frame.result().v1().bandwidth_upgrade_negotiation(); + + std::unique_ptr new_channel = + handler_2->CreateUpgradedEndpointChannel(&client_2, /*service_id=*/"A", + /*endpoint_id=*/"1", + bwu_frame.upgrade_path_info()); + if (!FeatureFlags::GetInstance().GetFlags().enable_cancellation_flag) { + EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); + EXPECT_EQ(new_channel->GetMedium(), + location::nearby::proto::connections::Medium::BLUETOOTH); + } else { + accept_latch.CountDown(); + EXPECT_EQ(new_channel, nullptr); + } + EXPECT_FALSE(mediums_2.GetBluetoothClassic().GetMacAddress().empty()); + handler_2->RevertResponderState(/*service_id=*/"A"); + end_latch.CountDown(); + }); + + EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); + EXPECT_TRUE(end_latch.Await(kWaitDuration).result()); +} + +} // namespace connections +} // namespace nearby diff --git a/connections/implementation/client_proxy.cc b/connections/implementation/client_proxy.cc index c86ae99f..3cd87094 100644 --- a/connections/implementation/client_proxy.cc +++ b/connections/implementation/client_proxy.cc @@ -74,12 +74,14 @@ ClientProxy::ClientProxy(::nearby::analytics::EventLogger* event_logger) supports_safe_to_disconnect_ = NearbyFlags::GetInstance().GetBoolFlag( config_package_nearby::nearby_connections_feature:: kEnableSafeToDisconnect); + support_auto_reconnect_ = NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_connections_feature::kEnableAutoReconnect); local_safe_to_disconnect_version_ = NearbyFlags::GetInstance().GetInt64Flag( config_package_nearby::nearby_connections_feature:: kSafeToDisconnectVersion); NEARBY_LOGS(INFO) << "[safe-to-disconnect]: Local enabled: " << supports_safe_to_disconnect_ - << "; Version_: " << local_safe_to_disconnect_version_; + << "; Version: " << local_safe_to_disconnect_version_; } ClientProxy::~ClientProxy() { Reset(); } @@ -120,6 +122,18 @@ std::string ClientProxy::GetConnectionToken(const std::string& endpoint_id) { return {}; } +std::optional ClientProxy::GetBluetoothMacAddress( + const std::string& endpoint_id) { + auto item = bluetooth_mac_addresses_.find(endpoint_id); + if (item != bluetooth_mac_addresses_.end()) return item->second; + return std::nullopt; +} + +void ClientProxy::SetBluetoothMacAddress( + const std::string& endpoint_id, const std::string& bluetooth_mac_address) { + bluetooth_mac_addresses_[endpoint_id] = bluetooth_mac_address; +} + std::string ClientProxy::GenerateLocalEndpointId() { if (high_vis_mode_) { if (!local_high_vis_mode_cache_endpoint_id_.empty()) { @@ -611,6 +625,24 @@ std::int32_t ClientProxy::GetNumIncomingConnections() const { .size(); } +bool ClientProxy::IsIncomingConnection(const std::string& endpoint_id) const { + MutexLock lock(&mutex_); + const ConnectionPair* item = LookupConnection(endpoint_id); + if (item != nullptr && item->first.status == Connection::kConnected) { + return item->first.is_incoming; + } + return false; +} + +bool ClientProxy::IsOutgoingConnection(const std::string& endpoint_id) const { + MutexLock lock(&mutex_); + const ConnectionPair* item = LookupConnection(endpoint_id); + if (item != nullptr && item->first.status == Connection::kConnected) { + return !item->first.is_incoming; + } + return false; +} + bool ClientProxy::HasPendingConnectionToEndpoint( const std::string& endpoint_id) const { MutexLock lock(&mutex_); @@ -848,6 +880,15 @@ bool ClientProxy::IsSafeToDisconnectEnabled(absl::string_view endpoint_id) { .min_nc_version_supports_safe_to_disconnect); } +bool ClientProxy::IsAutoReconnectEnabled(absl::string_view endpoint_id) { + return IsSupportAutoReconnect() && + GetRemoteSafeToDisconnectVersion(endpoint_id).has_value() && + (GetRemoteSafeToDisconnectVersion(endpoint_id) >= + FeatureFlags::GetInstance() + .GetFlags() + .min_nc_version_supports_auto_reconnect); +} + bool ClientProxy::IsPayloadReceivedAckEnabled(absl::string_view endpoint_id) { return IsSupportSafeToDisconnect() && GetRemoteSafeToDisconnectVersion(endpoint_id).has_value() && @@ -929,6 +970,7 @@ void ClientProxy::RemoveAllEndpoints() { // just remove without notifying. connections_.clear(); cancellation_flags_.clear(); + bluetooth_mac_addresses_.clear(); OnSessionComplete(); } diff --git a/connections/implementation/client_proxy.h b/connections/implementation/client_proxy.h index ff6a8c4d..00067c0a 100644 --- a/connections/implementation/client_proxy.h +++ b/connections/implementation/client_proxy.h @@ -23,6 +23,7 @@ #include #include "absl/functional/any_invocable.h" +#include "absl/strings/string_view.h" #include "connections/advertising_options.h" #include "connections/discovery_options.h" #include "connections/implementation/analytics/analytics_recorder.h" @@ -74,6 +75,10 @@ class ClientProxy final { } std::string GetConnectionToken(const std::string& endpoint_id); + std::optional GetBluetoothMacAddress( + const std::string& endpoint_id); + void SetBluetoothMacAddress(const std::string& endpoint_id, + const std::string& bluetooth_mac_address); const NearbyDevice* GetLocalDevice(); NearbyDeviceProvider* GetLocalDeviceProvider() { if (external_device_provider_ != nullptr) { @@ -188,6 +193,10 @@ class ClientProxy final { std::int32_t GetNumOutgoingConnections() const; // Returns the number of endpoints that are connected and incoming. std::int32_t GetNumIncomingConnections() const; + // Returns true if endpoint is incoming connection. + bool IsIncomingConnection(const std::string& endpoint_id) const; + // Returns true if endpoint is outgoing connection. + bool IsOutgoingConnection(const std::string& endpoint_id) const; // If true, then we're in the process of approving (or rejecting) a // connection. No payloads should be sent until isConnectedToEndpoint() // returns true. @@ -270,6 +279,11 @@ class ClientProxy final { const bool& IsSupportSafeToDisconnect() const { return supports_safe_to_disconnect_; } + + bool IsSupportAutoReconnect() const { + return support_auto_reconnect_; + } + const std::int32_t& GetLocalSafeToDisconnectVersion() const { return local_safe_to_disconnect_version_; } @@ -279,6 +293,7 @@ class ClientProxy final { absl::string_view endpoint_id, const std::int32_t& safe_to_disconnect_version); bool IsSafeToDisconnectEnabled(absl::string_view endpoint_id); + bool IsAutoReconnectEnabled(absl::string_view endpoint_id); bool IsPayloadReceivedAckEnabled(absl::string_view endpoint_id); private: @@ -415,6 +430,9 @@ class ClientProxy final { // Maps endpoint_id to endpoint connection state. absl::flat_hash_map connections_; + // Maps endpoint_id to Bluetooth Mac Addresses. + absl::flat_hash_map bluetooth_mac_addresses_; + // A cache of endpoint ids that we've already notified the discoverer of. We // check this cache before calling onEndpointFound() so that we don't notify // the client multiple times for the same endpoint. This would otherwise @@ -443,6 +461,7 @@ class ClientProxy final { // For Nearby Connections' own device provider. std::unique_ptr connections_device_provider_; bool supports_safe_to_disconnect_; + bool support_auto_reconnect_; std::int32_t local_safe_to_disconnect_version_; }; diff --git a/connections/implementation/flags/nearby_connections_feature_flags.h b/connections/implementation/flags/nearby_connections_feature_flags.h index ecab2dd4..6990b431 100644 --- a/connections/implementation/flags/nearby_connections_feature_flags.h +++ b/connections/implementation/flags/nearby_connections_feature_flags.h @@ -49,6 +49,10 @@ constexpr auto kEnablePayloadManagerToSkipChunkUpdate = constexpr auto kEnableSafeToDisconnect = flags::Flag(kConfigPackage, "45425789", false); +// Enable/Disable auto_reconnect feature. +constexpr auto kEnableAutoReconnect = + flags::Flag(kConfigPackage, "45427690", false); + // When true, allows to enable payload-received-ack protocol. constexpr auto kEnablePayloadReceivedAck = flags::Flag(kConfigPackage, "45425840", false); diff --git a/connections/implementation/offline_frames.cc b/connections/implementation/offline_frames.cc index 5f5f86d9..ca468be2 100644 --- a/connections/implementation/offline_frames.cc +++ b/connections/implementation/offline_frames.cc @@ -23,6 +23,7 @@ #include "connections/implementation/flags/nearby_connections_feature_flags.h" #include "connections/implementation/offline_frames_validator.h" #include "connections/implementation/proto/offline_wire_formats.pb.h" +#include "connections/medium_selector.h" #include "connections/status.h" #include "internal/flags/nearby_flags.h" #include "internal/platform/byte_array.h" @@ -43,6 +44,7 @@ using ::location::nearby::connections::OfflineFrame; using ::location::nearby::connections::OsInfo; using ::location::nearby::connections::PayloadTransferFrame; using ::location::nearby::connections::V1Frame; +using ::location::nearby::connections::AutoReconnectFrame; ByteArray ToBytes(OfflineFrame&& frame) { ByteArray bytes(frame.ByteSizeLong()); @@ -469,6 +471,32 @@ ByteArray ForDisconnection(bool request_safe_to_disconnect, return ToBytes(std::move(frame)); } +ByteArray ForAutoReconnectIntroduction(const std::string& endpoint_id) { + OfflineFrame frame; + + frame.set_version(OfflineFrame::V1); + auto* v1_frame = frame.mutable_v1(); + v1_frame->set_type(V1Frame::AUTO_RECONNECT); + auto* auto_reconnect = v1_frame->mutable_auto_reconnect(); + auto_reconnect->set_endpoint_id(endpoint_id); + auto_reconnect->set_event_type(AutoReconnectFrame::CLIENT_INTRODUCTION); + + return ToBytes(std::move(frame)); +} + +ByteArray ForAutoReconnectIntroductionAck(const std::string& endpoint_id) { + OfflineFrame frame; + + frame.set_version(OfflineFrame::V1); + auto* v1_frame = frame.mutable_v1(); + v1_frame->set_type(V1Frame::AUTO_RECONNECT); + auto* auto_reconnect = v1_frame->mutable_auto_reconnect(); + auto_reconnect->set_endpoint_id(endpoint_id); + auto_reconnect->set_event_type(AutoReconnectFrame::CLIENT_INTRODUCTION_ACK); + + return ToBytes(std::move(frame)); +} + UpgradePathInfo::Medium MediumToUpgradePathInfoMedium(Medium medium) { switch (medium) { case Medium::MDNS: diff --git a/connections/implementation/offline_frames.h b/connections/implementation/offline_frames.h index 9d1a7d6f..c34fcc85 100644 --- a/connections/implementation/offline_frames.h +++ b/connections/implementation/offline_frames.h @@ -101,6 +101,8 @@ ByteArray ForBwuSafeToClose(); ByteArray ForKeepAlive(); ByteArray ForDisconnection(bool request_safe_to_disconnect, bool ack_safe_to_disconnect); +ByteArray ForAutoReconnectIntroduction(const std::string& endpoint_id); +ByteArray ForAutoReconnectIntroductionAck(const std::string& endpoint_id); UpgradePathInfo::Medium MediumToUpgradePathInfoMedium(Medium medium); Medium UpgradePathInfoMediumToMedium(UpgradePathInfo::Medium medium); diff --git a/connections/implementation/offline_frames_test.cc b/connections/implementation/offline_frames_test.cc index fea92f95..f70723cb 100644 --- a/connections/implementation/offline_frames_test.cc +++ b/connections/implementation/offline_frames_test.cc @@ -559,6 +559,43 @@ TEST(OfflineFramesTest, CanGenerateDisconnection) { EXPECT_THAT(message, EqualsProto(kExpected)); } +TEST(OfflineFramesTest, CanGenerateAutoReconnectIntroduction) { + constexpr absl::string_view kExpected = + R"pb( + version: V1 + v1: < + type: AUTO_RECONNECT + auto_reconnect: < + event_type: CLIENT_INTRODUCTION + endpoint_id: "ABC" + > + >)pb"; + ByteArray bytes = ForAutoReconnectIntroduction(std::string(kEndpointId)); + auto response = FromBytes(bytes); + ASSERT_TRUE(response.ok()); + OfflineFrame message = response.result(); + EXPECT_THAT(message, EqualsProto(kExpected)); +} + +TEST(OfflineFramesTest, CanGenerateAutoReconnectIntroductionAck) { + constexpr absl::string_view kExpected = + R"pb( + version: V1 + v1: < + type: AUTO_RECONNECT + auto_reconnect: < + event_type: CLIENT_INTRODUCTION_ACK + endpoint_id: "ABC" + > + >)pb"; + ByteArray bytes = ForAutoReconnectIntroductionAck(std::string(kEndpointId)); + auto response = FromBytes(bytes); + ASSERT_TRUE(response.ok()); + OfflineFrame message = response.result(); + EXPECT_THAT(message, EqualsProto(kExpected)); +} + + } // namespace } // namespace parser } // namespace connections diff --git a/connections/implementation/p2p_cluster_pcp_handler.cc b/connections/implementation/p2p_cluster_pcp_handler.cc index c06c6340..eefeed08 100644 --- a/connections/implementation/p2p_cluster_pcp_handler.cc +++ b/connections/implementation/p2p_cluster_pcp_handler.cc @@ -1641,6 +1641,7 @@ BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::BluetoothConnectImpl( NEARBY_LOGS(VERBOSE) << "Client" << client->GetClientId() << " created Bluetooth endpoint channel to endpoint(id=" << endpoint->endpoint_id << ")."; + client->SetBluetoothMacAddress(endpoint->endpoint_id, device.GetMacAddress()); return BasePcpHandler::ConnectImplResult{ .medium = Medium::BLUETOOTH, .status = {Status::kSuccess}, diff --git a/connections/implementation/reconnect_manager.cc b/connections/implementation/reconnect_manager.cc new file mode 100644 index 00000000..f5e6b6cc --- /dev/null +++ b/connections/implementation/reconnect_manager.cc @@ -0,0 +1,864 @@ +// Copyright 2023 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 "connections/implementation/reconnect_manager.h" + +#include +#include +#include +#include + +#include "securegcm/ukey2_handshake.h" +#include "absl/functional/any_invocable.h" +#include "absl/functional/bind_front.h" +#include "internal/platform/mutex.h" +#include "internal/platform/mutex_lock.h" +#ifndef NEARBY_CHROMIUM +#ifndef NEARBY_SWIFTPM +#include "absl/log/check.h" // nogncheck +#endif +#endif +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" +#include "connections/implementation/bluetooth_endpoint_channel.h" +#include "connections/implementation/client_proxy.h" +#include "connections/implementation/encryption_runner.h" +#include "connections/implementation/endpoint_channel.h" +#include "connections/implementation/endpoint_channel_manager.h" +#include "connections/implementation/mediums/mediums.h" +#include "connections/implementation/offline_frames.h" +#include "connections/implementation/service_id_constants.h" +#include "internal/platform/bluetooth_adapter.h" +#include "internal/platform/bluetooth_classic.h" +#include "internal/platform/byte_array.h" +#include "internal/platform/cancelable_alarm.h" +#include "internal/platform/cancellation_flag_listener.h" +#include "internal/platform/count_down_latch.h" +#include "internal/platform/exception.h" +#include "internal/platform/feature_flags.h" +#include "internal/platform/implementation/system_clock.h" +#include "internal/platform/logging.h" +#include "proto/connections_enums.pb.h" + +namespace nearby { +namespace connections { +constexpr absl::string_view TAG = "[ReconnectManager]"; + +ReconnectManager::ReconnectManager(Mediums& mediums, + EndpointChannelManager& channel_manager) + : mediums_(&mediums), channel_manager_(&channel_manager) {} + +ReconnectManager::~ReconnectManager() { Shutdown(); } + +bool ReconnectManager::AutoReconnect( + ClientProxy* client, const std::string& endpoint_id, + AutoReconnectCallback& callback, + bool send_disconnection_notification, + DisconnectionReason disconnection_reason) { + if (!client->IsAutoReconnectEnabled(endpoint_id)) { + return false; + } + + if (resumed_endpoints_.contains(endpoint_id)) { + NEARBY_LOGS(INFO) << TAG << "AutoReconnect is not needed for endpoint_id = " + << endpoint_id + << ", since it's just reconnected successfully."; + return true; + } + + auto endpoint_channel = channel_manager_->GetChannelForEndpoint(endpoint_id); + if (endpoint_channel == nullptr) { + NEARBY_LOGS(INFO) + << TAG << " endpoint_channel shouldn't be null for endpoint_id = " + << endpoint_id; + return false; + } + Medium medium = endpoint_channel->GetMedium(); + + bool is_incoming = client->IsIncomingConnection(endpoint_id); + if (is_incoming == client->IsOutgoingConnection(endpoint_id)) { + NEARBY_LOGS(INFO) + << TAG << " autoReconnect failed for medium: " + << location::nearby::proto::connections::Medium_Name(medium) + << " because there is no existing incoming/outgoing connection, " + "is_incoming_connection = " + << is_incoming << ", is_outgoing_connection = " + << client->IsOutgoingConnection(endpoint_id); + return false; + } + std::string reconnect_service_id = + WrapInitiatorReconnectServiceId(endpoint_channel->GetServiceId()); + endpoint_id_metadata_map_.emplace( + endpoint_id, + ReconnectMetadata(is_incoming, std::move(callback), + send_disconnection_notification, disconnection_reason, + reconnect_service_id)); + NEARBY_LOGS(INFO) << TAG << "add a new endpoint_id " << endpoint_id + << " into metadata_by_service_id_map."; + + if (Start(is_incoming, client, endpoint_id, reconnect_service_id, medium)) { + resumed_endpoints_.emplace(endpoint_id); + + auto time_out = FeatureFlags::GetInstance() + .GetFlags() + .auto_reconnect_skip_duplicated_endpoint_duration; + std::make_unique( + absl::StrCat("RemoveSuccessfulResumedEndpointId for ", endpoint_id), + [this, endpoint_id, time_out]() { + NEARBY_LOGS(INFO) + << TAG << "Timeout after " << time_out + << "ms. RemoveSuccessfulResumedEndpointId for " << endpoint_id; + resumed_endpoints_.erase(endpoint_id); + }, + time_out, &alarm_executor_); + + return true; + } + + ClearReconnectData(client, reconnect_service_id, is_incoming); + return false; +} + +bool ReconnectManager::Start(bool is_incoming, ClientProxy* client, + const std::string& endpoint_id, + const std::string& reconnect_service_id, + Medium medium) { + auto retry_delay_millis = + FeatureFlags::GetInstance().GetFlags().auto_reconnect_retry_delay_millis; + auto reconnect_retry_num = + FeatureFlags::GetInstance().GetFlags().auto_reconnect_retry_attempts; + NEARBY_LOGS(INFO) << TAG << " " << (is_incoming ? "rehost" : "reconnect") + << " for medium: " + << location::nearby::proto::connections::Medium_Name( + medium) + << " for endpoint_id " << endpoint_id << " started..."; + bool final_result = false; + CountDownLatch latch(1); + reconnect_executor_.Execute( + "reconnect-start", + [this, &final_result, is_incoming, client, &endpoint_id, + &reconnect_service_id, retry_delay_millis, reconnect_retry_num, medium, + &latch]() mutable { + for (int i = 0; i < reconnect_retry_num; ++i) { + if (client->GetCancellationFlag(endpoint_id)->Cancelled()) { + NEARBY_LOGS(INFO) + << TAG << " Stop retry, Endpoint connection is cancelled"; + break; + } + if (RunOnce(is_incoming, client, endpoint_id, reconnect_service_id, + medium)) { + final_result = true; + break; + } + SystemClock::Sleep(retry_delay_millis); + } + NEARBY_LOGS(INFO) << "Reconnect " + << (final_result ? "succeeded" : "failed"); + latch.CountDown(); + }); + latch.Await(); + return final_result; +} + +bool ReconnectManager::RunOnce(bool is_incoming, ClientProxy* client, + const std::string& endpoint_id, + const std::string& reconnect_service_id, + Medium medium) { + bool result = false; + switch (medium) { + case Medium::BLUETOOTH: { + BluetoothImpl bluetooth_impl(client, endpoint_id, reconnect_service_id, + is_incoming, medium, mediums_, + channel_manager_, *this); + result = bluetooth_impl.Run(); + } break; + + default: + NEARBY_LOGS(INFO) << "AutoReconnect not implemented yet for " + << location::nearby::proto::connections::Medium_Name( + medium); + + break; + } + return result; +} + +void ReconnectManager::ClearReconnectData( + ClientProxy* client, const std::string& reconnect_service_id, + bool is_incoming) { + for (auto& item : endpoint_id_metadata_map_) { + if (item.second.reconnect_service_id == reconnect_service_id && + item.second.is_incoming == is_incoming) { + if (item.second.reconnect_cb.on_reconnect_failure_cb) { + item.second.reconnect_cb.on_reconnect_failure_cb( + client, item.first, item.second.send_disconnection_notification, + item.second.disconnection_reason); + } + } + NEARBY_LOGS(INFO) << TAG << "erase endpoint_id " << item.first; + endpoint_id_metadata_map_.erase(item.first); + } +} + +void ReconnectManager::Shutdown() { + NEARBY_LOGS(INFO) << TAG << "Initiating shutdown of ReconnectManager."; + { + MutexLock lock(&mutex_); + listen_timeout_alarm_by_service_id_.clear(); + } + new_endpoint_channels_.clear(); + endpoint_id_metadata_map_.clear(); + resumed_endpoints_.clear(); + + alarm_executor_.Shutdown(); + reconnect_executor_.Shutdown(); + encryption_cb_executor_.Shutdown(); + incoming_connection_cb_executor_.Shutdown(); + NEARBY_LOGS(INFO) << TAG << "ReconnectManager has shut down."; +} + +bool ReconnectManager::BaseMediumImpl::Run() { + if (!IsMediumRadioOn()) { + NEARBY_LOGS(INFO) << TAG + << location::nearby::proto::connections::Medium_Name( + medium_) + << " radio is turned off, try later"; + return false; + } + + if (client_->IsConnectedToEndpoint(endpoint_id_)) { + NEARBY_LOGS(INFO) << TAG + << "ReconnectBluetooth is not needed since it's already " + "connected to the RemoteDevice: "; + return true; + } + + auto previou_channel = channel_manager_->GetChannelForEndpoint(endpoint_id_); + if (previou_channel == nullptr) { + NEARBY_LOGS(INFO) + << TAG + << "ReconnectionManager didn't find a previous EndpointChannel " + "for " + << endpoint_id_ << " in this run, stop Reconnection!"; + return false; + } + previou_channel->Close( + DisconnectionReason::PREV_CHANNEL_DISCONNECTION_IN_RECONNECT); + + return is_incoming_ ? RehostForIncomingConnections() + : ReconnectToRemoteDevice(); +} + +bool ReconnectManager::BaseMediumImpl::RehostForIncomingConnections() { + auto time_out = + FeatureFlags::GetInstance().GetFlags().auto_reconnect_timeout_millis; + auto cancellation_flag = client_->GetCancellationFlag(endpoint_id_); + if (!IsListeningForIncomingConnections()) { + NEARBY_LOGS(INFO) << "Start rehosting for: " << reconnect_service_id_; + if (!StartListeningForIncomingConnections()) { + NEARBY_LOGS(ERROR) + << TAG + << "Rehost failed since " + "StartListeningForIncomingConnections return false."; + return false; + } + { + MutexLock lock(&reconnect_manager_.mutex_); + reconnect_manager_ + .listen_timeout_alarm_by_service_id_[reconnect_service_id_] = + std::make_unique( + absl::StrCat("Rehost listen timeout for ", reconnect_service_id_), + [this, time_out]() { + NEARBY_LOGS(INFO) + << "Timeout after " << time_out + << "ms. Stop listening for incoming " + "Connections for serviceId " + << reconnect_service_id_ << " for rehost, initiated by " + << endpoint_id_ + << ", unregister all still not connected endpointIds."; + StopListeningIfAllConnected( + reconnect_service_id_, + [this]() { StopListeningForIncomingConnections(); }, + /* forceStop= */ true); + }, + time_out, &reconnect_manager_.alarm_executor_); + } + } else { + NEARBY_LOGS(INFO) << "Rehosting is not needed since it's already " + "rehosts for: " + << reconnect_service_id_; + } + + if (cancellation_flag == nullptr) { + return true; + } + if (cancellation_flag->Cancelled()) { + StopListeningIfAllConnected( + reconnect_service_id_, + [this]() { StopListeningForIncomingConnections(); }, + /* forceStop= */ false); + return false; + } + auto cancellation_listener = + std::make_unique( + cancellation_flag, [this]() { + NEARBY_LOGS(INFO) << "Calling CancellationFlagListener."; + ProcessFailedReconnection(endpoint_id_, [this]() { + StopListeningForIncomingConnections(); + }); + }); + + std::make_unique( + absl::StrCat(TAG, " unregisterOnCancelListener"), + [cancellation_listener = std::move(cancellation_listener)]() mutable { + // clean up the listener after auto reconnect is done. + cancellation_listener.reset(); + }, + time_out, &reconnect_manager_.alarm_executor_); + return true; +} + +bool ReconnectManager::BaseMediumImpl::ReconnectToRemoteDevice() { + if (!ConnectOverMedium()) { + NEARBY_LOGS(INFO) << TAG << "Connect over medium " + << location::nearby::proto::connections::Medium_Name( + medium_) + << " failed."; + return false; + } + NEARBY_LOGS(INFO) << TAG << "Write CLIENT_INTRODUCTION frame"; + Exception write_exception = reconnect_channel_->Write( + parser::ForAutoReconnectIntroduction(endpoint_id_)); + if (!write_exception.Ok()) { + NEARBY_LOGS(ERROR) + << TAG << "Failed to write forAutoReconnectClientIntroductionEvent."; + QuietlyCloseChannelAndSocket(); + return false; + } + if (!ReadClientIntroductionAckFrame(reconnect_channel_.get())) { + NEARBY_LOGS(ERROR) << TAG << "Failed to read ClientIntroductionAck frame."; + QuietlyCloseChannelAndSocket(); + return false; + } + if (ReplaceChannelForEndpoint(client_, endpoint_id_, + std::move(reconnect_channel_), + SupportEncryptionDisabled(), nullptr)) { + NEARBY_LOGS(INFO) << TAG + << " successfully rebuild the outgoing connection with " + << location::nearby::proto::connections::Medium_Name( + medium_) + << " for the endpointId:" << endpoint_id_; + return true; + } + NEARBY_LOGS(INFO) + << TAG << " ReplaceChannelForEndpoint for the outgoing connection with " + << location::nearby::proto::connections::Medium_Name(medium_) + << " for the endpointId:" << endpoint_id_ << " failed. Please retry"; + return false; +} + +void ReconnectManager::BaseMediumImpl::OnIncomingConnection( + const std::string& reconnect_service_id) { + NEARBY_LOGS(INFO) << TAG << "Received reconnection successfully"; + reconnect_manager_.incoming_connection_cb_executor_.Execute( + "OnIncomingConnection", [this]() { + auto incoming_endpoin_id = + ReadClientIntroductionFrame(reconnect_channel_.get()); + if (incoming_endpoin_id.empty()) { + NEARBY_LOGS(ERROR) << TAG << "read ClientIntroductionFrame failed"; + QuietlyCloseChannelAndSocket(); + return; + } + NEARBY_LOGS(INFO) << TAG << "Write CLIENT_INTRODUCTION_ACK frame"; + Exception write_exception = reconnect_channel_->Write( + parser::ForAutoReconnectIntroductionAck(endpoint_id_)); + if (!write_exception.Ok()) { + NEARBY_LOGS(ERROR) + << TAG + << "Failed to write forAutoReconnectClientIntroductionAckEvent."; + QuietlyCloseChannelAndSocket(); + return; + } + if (ReplaceChannelForEndpoint( + client_, endpoint_id_, std::move(reconnect_channel_), + SupportEncryptionDisabled(), + [this]() { StopListeningForIncomingConnections(); })) { + NEARBY_LOGS(INFO) + << TAG << " successfully rebuild the incoming connection with " + << location::nearby::proto::connections::Medium_Name(medium_) + << " for the endpointId:" << endpoint_id_; + return; + } + QuietlyCloseChannelAndSocket(); + NEARBY_LOGS(INFO) + << TAG + << " ReplaceChannelForEndpoint for the incoming connection with " + << location::nearby::proto::connections::Medium_Name(medium_) + << " for the endpointId:" << endpoint_id_ + << " failed. Please retry"; + return; + }); +} + +std::string ReconnectManager::BaseMediumImpl::ReadClientIntroductionFrame( + EndpointChannel* endpoint_channel) { + NEARBY_LOGS(INFO) << TAG << "Read CLIENT_INTRODUCTION frame"; + + auto timeout = FeatureFlags::GetInstance() + .GetFlags() + .safe_to_disconnect_auto_resume_timeout_millis; + CancelableAlarm timeout_alarm( + "ReconnectManager::ReadClientIntroductionFrame", + [timeout, endpoint_channel]() { + NEARBY_LOGS(ERROR) << "In ReconnectManager, failed to read the " + "ClientIntroductionFrame after " + << timeout + << ". Timing out and closing EndpointChannel " + << endpoint_channel->GetType(); + endpoint_channel->Close(); + }, + timeout, &reconnect_manager_.alarm_executor_); + + auto data = endpoint_channel->Read(); + timeout_alarm.Cancel(); + if (!data.ok()) { + NEARBY_LOGS(ERROR) + << "Data read fail when expecting a ClientIntroductionFrame from " + "EndpointChannel " + << endpoint_channel->GetType(); + return {}; + } + auto transfer(parser::FromBytes(data.result())); + if (!transfer.ok()) { + NEARBY_LOGS(ERROR) << "Attempted to read a ClientIntroductionFrame from " + "EndpointChannel " + << endpoint_channel->GetType() + << ", but was unable to obtain any OfflineFrame."; + return {}; + } + OfflineFrame frame = transfer.result(); + if (!frame.has_v1() || !frame.v1().has_auto_reconnect()) { + NEARBY_LOGS(ERROR) << "In ReadClientIntroductionFrame(), eExpected a " + "AUTO_RECONNECT v1 OfflineFrame but got a " + << parser::GetFrameType(frame) << " frame instead."; + return {}; + } + if (frame.v1().auto_reconnect().event_type() != + AutoReconnectFrame::CLIENT_INTRODUCTION) { + NEARBY_LOGS(ERROR) << "In ReadClientIntroductionFrame(), expected a " + "CLIENT_INTRODUCTION " + "v1 OfflineFrame but got a AUTO_RECONNECT frame " + "with eventType " + << frame.v1().auto_reconnect().event_type() + << " instead."; + return {}; + } + return frame.v1().auto_reconnect().endpoint_id(); +} + +bool ReconnectManager::BaseMediumImpl::ReadClientIntroductionAckFrame( + EndpointChannel* endpoint_channel) { + NEARBY_LOGS(INFO) << TAG << "Read CLIENT_INTRODUCTION_ACK frame"; + + auto timeout = FeatureFlags::GetInstance() + .GetFlags() + .safe_to_disconnect_auto_resume_timeout_millis; + CancelableAlarm timeout_alarm( + "ReconnectManager::ReadClientIntroductionAckFrame", + [timeout, endpoint_channel]() { + NEARBY_LOGS(ERROR) << "In ReconnectManager, failed to read the " + "ClientIntroductionAckFrame after " + << timeout + << ". Timing out and closing EndpointChannel " + << endpoint_channel->GetType(); + endpoint_channel->Close(); + }, + timeout, &reconnect_manager_.alarm_executor_); + + auto data = endpoint_channel->Read(); + timeout_alarm.Cancel(); + if (!data.ok()) return false; + auto transfer(parser::FromBytes(data.result())); + if (!transfer.ok()) { + NEARBY_LOGS(ERROR) << "Attempted to read a ClientIntroductionAckFrame from " + "EndpointChannel " + << endpoint_channel->GetType() + << ", but was unable to obtain any OfflineFrame."; + return false; + } + OfflineFrame frame = transfer.result(); + if (!frame.has_v1() || !frame.v1().has_auto_reconnect()) { + NEARBY_LOGS(ERROR) << "In ReadClientIntroductionAckFrame(), eExpected a " + "AUTO_RECONNECT v1 OfflineFrame but got a " + << parser::GetFrameType(frame) << " frame instead."; + return false; + } + if (frame.v1().auto_reconnect().event_type() != + AutoReconnectFrame::CLIENT_INTRODUCTION_ACK) { + NEARBY_LOGS(ERROR) << "In ReadClientIntroductionAckFrame(), expected a " + "CLIENT_INTRODUCTION_ACK " + "v1 OfflineFrame but got a AUTO_RECONNECT frame " + "with eventType " + << frame.v1().auto_reconnect().event_type() + << " instead."; + return false; + } + return true; +} + +bool ReconnectManager::BaseMediumImpl::ReplaceChannelForEndpoint( + ClientProxy* client, const std::string& endpoint_id, + std::unique_ptr new_channel, + bool support_encryption_disabled, + absl::AnyInvocable stop_listening_incoming_connection) { + auto& endpoint_id_metadata_map = reconnect_manager_.endpoint_id_metadata_map_; + auto reconnect_metadata = endpoint_id_metadata_map.find(endpoint_id); + if (reconnect_metadata == endpoint_id_metadata_map.end()) { + NEARBY_LOGS(ERROR) << TAG << "ReconnectMetadata is null for endpointId: " + << endpoint_id << " ,please retry!"; + return false; + } + + EndpointChannel* endpoint_channel = + reconnect_manager_.new_endpoint_channels_ + .emplace(endpoint_id, std::move(new_channel)) + .first->second.get(); + replace_channel_succeed_ = false; + wait_encryption_to_finish_ = std::make_unique(1); + if (reconnect_metadata->second.is_incoming) { + reconnect_manager_.encryption_runner_.StartServer( + client, endpoint_id, endpoint_channel, GetResultListener()); + } else { + reconnect_manager_.encryption_runner_.StartClient( + client, endpoint_id, endpoint_channel, GetResultListener()); + } + wait_encryption_to_finish_->Await( + FeatureFlags::GetInstance().GetFlags().auto_reconnect_timeout_millis); + + NEARBY_LOGS(INFO) << TAG + << "replace_channel_succeed_: " << replace_channel_succeed_ + << " for endpointId: " << endpoint_id; + + if (replace_channel_succeed_) { + ProcessSuccessfulReconnection( + endpoint_id, [this]() { StopListeningForIncomingConnections(); }); + client->GetAnalyticsRecorder().OnConnectionEstablished( + endpoint_id, endpoint_channel->GetMedium(), + client->GetConnectionToken(endpoint_id)); + } else { + ProcessFailedReconnection( + endpoint_id, [this]() { StopListeningForIncomingConnections(); }); + } + reconnect_manager_.new_endpoint_channels_.erase(endpoint_id); + return replace_channel_succeed_; +} + +EncryptionRunner::ResultListener +ReconnectManager::BaseMediumImpl::GetResultListener() { + return { + .on_success_cb = + [this](const std::string& endpoint_id, + std::unique_ptr ukey2, + const std::string& auth_token, + const ByteArray& raw_auth_token) { + reconnect_manager_.encryption_cb_executor_.Execute( + "encryption-success", + [this, endpoint_id, raw_ukey2 = ukey2.release(), auth_token, + raw_auth_token]() mutable { + OnEncryptionSuccessRunnable( + endpoint_id, + std::unique_ptr(raw_ukey2), + auth_token, raw_auth_token); + wait_encryption_to_finish_->CountDown(); + }); + }, + .on_failure_cb = + [this](const std::string& endpoint_id, EndpointChannel* channel) { + reconnect_manager_.encryption_cb_executor_.Execute( + "encryption-failure", [this, endpoint_id, channel]() mutable { + NEARBY_LOGS(ERROR) + << "Encryption failed for endpoint_id=" << endpoint_id + << " on medium=" + << location::nearby::proto::connections::Medium_Name( + channel->GetMedium()); + OnEncryptionFailureRunnable(endpoint_id, channel); + wait_encryption_to_finish_->CountDown(); + }); + }, + }; +} + +void ReconnectManager::BaseMediumImpl::OnEncryptionSuccessRunnable( + const std::string& endpoint_id, + std::unique_ptr ukey2, + const std::string& auth_token, const ByteArray& raw_auth_token) { + auto item = reconnect_manager_.new_endpoint_channels_.find(endpoint_id); + if (item == reconnect_manager_.new_endpoint_channels_.end()) { + NEARBY_LOGS(INFO) << "TAG" + << "OnEncryptionSuccess failed, new_endpoint_channel is " + "null for Endpoint:" + << endpoint_id; + return; + } + if (!ukey2) { + NEARBY_LOGS(INFO) + << "TAG" + << "OnEncryptionSuccess failed, ukey2 is null for Endpoint:" + << endpoint_id; + return; + } + + // After both parties accepted connection (presumably after verifying & + // matching security tokens), we are allowed to extract the shared key. + bool succeeded = ukey2->VerifyHandshake(); + CHECK(succeeded); // If this fails, it's a UKEY2 protocol bug. + auto context = ukey2->ToConnectionContext(); + CHECK(context); // there is no way how this can fail, if Verify succeeded. + // If it did, it's a UKEY2 protocol bug. + + if (!reconnect_manager_.channel_manager_->EncryptChannelForEndpoint( + endpoint_id, std::move(context))) { + NEARBY_LOGS(INFO) << "TAG" + << "new_endpoint_channel failed to update " + "EncryptionContext for Endpoint:" + << endpoint_id; + return; + } + auto previous_channel = + reconnect_manager_.channel_manager_->GetChannelForEndpoint(endpoint_id); + if (previous_channel == nullptr) { + NEARBY_LOGS(INFO) + << "TAG" + << "ReconnectionManager didn't find a previous EndpointChannel for " + << endpoint_id + << " when registering the new EndpointChannel, stop Reconnection!"; + item->second->Close(DisconnectionReason::UNFINISHED); + return; + } + reconnect_manager_.channel_manager_->ReplaceChannelForEndpoint( + client_, endpoint_id, std::move(item->second), + SupportEncryptionDisabled()); + replace_channel_succeed_ = true; +} + +void ReconnectManager::BaseMediumImpl::OnEncryptionFailureRunnable( + const std::string& endpoint_id, EndpointChannel* endpoint_channel) { + NEARBY_LOGS(INFO) + << "TAG" + << "new_endpoint_channel failed to use encryption for Endpoint:" + << endpoint_id; +} + +void ReconnectManager::BaseMediumImpl::ProcessSuccessfulReconnection( + const std::string& endpoint_id, + absl::AnyInvocable stop_listening_incoming_connection) { + auto& endpoint_id_metadata_map = reconnect_manager_.endpoint_id_metadata_map_; + auto reconnect_metadata = endpoint_id_metadata_map.find(endpoint_id); + if (reconnect_metadata == endpoint_id_metadata_map.end()) { + NEARBY_LOGS(ERROR) << TAG + << "when ProcessSuccessfulReconnection, endpoint_id: " + << endpoint_id + << " is already removed fromendpoint_id_metadata_map."; + return; + } + + auto medatdata = std::move(reconnect_metadata->second); + endpoint_id_metadata_map.erase(reconnect_metadata); + auto& callback = medatdata.reconnect_cb; + if (callback.on_reconnect_success_cb) { + callback.on_reconnect_success_cb(client_, endpoint_id); + } else { + NEARBY_LOGS(ERROR) << TAG + << "when ProcessSuccessfulReconnection, endpoint_id: " + << endpoint_id + << " callback.on_reconnect_success_cb is null"; + } + + if (medatdata.is_incoming && + stop_listening_incoming_connection) { + StopListeningIfAllConnected(medatdata.reconnect_service_id, + std::move(stop_listening_incoming_connection), + /* forceStop= */ false); + } +} +void ReconnectManager::BaseMediumImpl::ProcessFailedReconnection( + const std::string& endpoint_id, + absl::AnyInvocable stop_listening_incoming_connection) {} + +void ReconnectManager::BaseMediumImpl::StopListeningIfAllConnected( + const std::string& reconnect_service_id, + absl::AnyInvocable stop_listening_incoming_connection, + bool force_stop) { + if (!force_stop && HasPendingIncomingConnections(reconnect_service_id)) { + return; + } + CancelClearHostTimeoutAlarm(reconnect_service_id); + stop_listening_incoming_connection(); + ClearReconnectData(reconnect_service_id, /* is_incoming= */ true); + NEARBY_LOGS(INFO) << TAG + << " No more pending incoming connections, " + "stop_listening_incoming_connection for " + << reconnect_service_id << " before timeout."; +} + +bool ReconnectManager::BaseMediumImpl::HasPendingIncomingConnections( + const std::string& reconnect_service_id) { + for (auto& item : reconnect_manager_.endpoint_id_metadata_map_) { + if (item.second.reconnect_service_id == reconnect_service_id && + item.second.is_incoming) { + return true; + } + } + return false; +} + +void ReconnectManager::BaseMediumImpl:: + CancelClearHostTimeoutAlarm(const std::string& service_id) { + MutexLock lock(&reconnect_manager_.mutex_); + auto item = + reconnect_manager_.listen_timeout_alarm_by_service_id_.find(service_id); + if (item == reconnect_manager_.listen_timeout_alarm_by_service_id_.end()) + return; + + if (item->second->IsValid()) { + item->second->Cancel(); + item->second.reset(); + } + reconnect_manager_.listen_timeout_alarm_by_service_id_.erase(item); +} +void ReconnectManager::BaseMediumImpl:: + ClearReconnectData(const std::string& service_id, bool is_incoming) { + auto& metadata_map = reconnect_manager_.endpoint_id_metadata_map_; + for (auto item = metadata_map.begin(); item != metadata_map.end(); ) { + if (item->second.reconnect_service_id == service_id && is_incoming) { + auto& callback = item->second.reconnect_cb.on_reconnect_failure_cb; + if (callback) + callback(client_, item->first, + item->second.send_disconnection_notification, + item->second.disconnection_reason); + metadata_map.erase(item); + } else { + ++item; + } + } +} + +bool ReconnectManager::BluetoothImpl::IsMediumRadioOn() const { + return bluetooth_medium_.IsAvailable(); +} + +bool ReconnectManager::BluetoothImpl::IsListeningForIncomingConnections() + const { + return bluetooth_medium_.IsAcceptingConnections(reconnect_service_id_); +} + +bool ReconnectManager::BluetoothImpl::StartListeningForIncomingConnections() { + if (!bluetooth_medium_.StartAcceptingConnections( + reconnect_service_id_, + absl::bind_front( + &ReconnectManager::BluetoothImpl::OnIncomingBluetoothConnection, this, + client_))) { + NEARBY_LOGS(ERROR) + << "ReconnectManager::BluetoothImpl couldn't initiate the " + "BLUETOOTH reconnect for endpoint " + << endpoint_id_ + << " because it failed to start listening for " + "incoming Bluetooth connections."; + return false; + } + NEARBY_LOGS(INFO) << "ReconnectManager::BluetoothImpl successfully started " + "listening for incoming " + "reconnection on service_id=" + << reconnect_service_id_ << " for endpoint " + << endpoint_id_; + return true; +} + +void ReconnectManager::BluetoothImpl::OnIncomingBluetoothConnection( + ClientProxy* client, const std::string& upgrade_service_id, + BluetoothSocket socket) { + reconnect_channel_ = std::make_unique( + upgrade_service_id, /*channel_name=*/upgrade_service_id, socket); + if (reconnect_channel_ == nullptr) { + NEARBY_LOGS(ERROR) << TAG + << "Create new endpointChannel for incoming socket " + "failed, close the socket"; + + socket.Close(); + return; + } + bluetooth_socket_ = std::move(socket); + + NEARBY_LOGS(INFO) + << TAG << "Create new endpointChannel successfully for incoming socket."; + + OnIncomingConnection(upgrade_service_id); +} + +void ReconnectManager::BluetoothImpl::StopListeningForIncomingConnections() { + bluetooth_medium_.StopAcceptingConnections(reconnect_service_id_); +} + +bool ReconnectManager::BluetoothImpl::ConnectOverMedium() { + std::optional remote_mac_address = + client_->GetBluetoothMacAddress(endpoint_id_); + if (!remote_mac_address.has_value()) { + NEARBY_LOGS(INFO) + << "ReconnectBluetooth failed since remoteMacAddress is empty"; + return false; + } + auto& bluetooth_medium = mediums_->GetBluetoothClassic(); + BluetoothDevice remote_bluetooth_device = + bluetooth_medium.GetRemoteDevice(remote_mac_address.value()); + if (!remote_bluetooth_device.IsValid()) { + NEARBY_LOGS(INFO) + << "ReconnectBluetooth failed since remoteBluetoothDevice is null: " + << remote_mac_address.value(); + return false; + } + + bluetooth_socket_ = + bluetooth_medium.Connect(remote_bluetooth_device, reconnect_service_id_, + client_->GetCancellationFlag(endpoint_id_)); + + if (!bluetooth_socket_.IsValid()) { + NEARBY_LOGS(ERROR) << "Failed to reconnect to Bluetooth device " + << remote_bluetooth_device.GetName() + << " for endpoint(id=" << endpoint_id_ << ")."; + return false; + } + + reconnect_channel_ = std::make_unique( + UnWrapInitiatorReconnectServiceId(reconnect_service_id_), + /*channel_name=*/endpoint_id_, bluetooth_socket_); + if (reconnect_channel_ == nullptr) { + NEARBY_LOGS(ERROR) << "ReconnectBluetooth Failed to get the Bluetooth " + "channel, please retry "; + bluetooth_socket_.Close(); + return false; + } + return true; +} + +bool ReconnectManager::BluetoothImpl::SupportEncryptionDisabled() { + return false; +} + +void ReconnectManager::BluetoothImpl::QuietlyCloseChannelAndSocket() { + reconnect_channel_->Close(DisconnectionReason::UNFINISHED); + bluetooth_socket_.Close(); +} + +} // namespace connections +} // namespace nearby diff --git a/connections/implementation/reconnect_manager.h b/connections/implementation/reconnect_manager.h new file mode 100644 index 00000000..ecc29646 --- /dev/null +++ b/connections/implementation/reconnect_manager.h @@ -0,0 +1,237 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef CORE_INTERNAL_RECONNECTION_MANAGER_H_ +#define CORE_INTERNAL_RECONNECTION_MANAGER_H_ + +#include +#include +#include + +#include "securegcm/ukey2_handshake.h" +#include "absl/base/thread_annotations.h" +#include "absl/container/flat_hash_map.h" +#include "absl/container/flat_hash_set.h" +#include "absl/functional/any_invocable.h" +#include "connections/implementation/client_proxy.h" +#include "connections/implementation/encryption_runner.h" +#include "connections/implementation/endpoint_channel.h" +#include "connections/implementation/endpoint_channel_manager.h" +#include "connections/implementation/mediums/bluetooth_classic.h" +#include "connections/implementation/mediums/mediums.h" +#include "connections/implementation/proto/offline_wire_formats.pb.h" +#include "internal/platform/bluetooth_classic.h" +#include "internal/platform/byte_array.h" +#include "internal/platform/cancelable_alarm.h" +#include "internal/platform/count_down_latch.h" +#include "internal/platform/mutex.h" +#include "internal/platform/scheduled_executor.h" +#include "internal/platform/single_thread_executor.h" + +namespace nearby { +namespace connections { +using AutoReconnectFrame = ::location::nearby::connections::AutoReconnectFrame; +using OfflineFrame = ::location::nearby::connections::OfflineFrame; +using Medium = ::location::nearby::proto::connections::Medium; +using DisconnectionReason = + ::location::nearby::proto::connections::DisconnectionReason; + +class ReconnectManager { + public: + ReconnectManager(Mediums& mediums, EndpointChannelManager& channel_manager); + ~ReconnectManager(); + + struct AutoReconnectCallback { + absl::AnyInvocable + on_reconnect_success_cb; + absl::AnyInvocable + on_reconnect_failure_cb; + }; + + struct ReconnectMetadata { + ReconnectMetadata(bool is_incoming, AutoReconnectCallback callback, + bool send_disconnection_notification, + DisconnectionReason disconnection_reason, + const std::string& reconnect_service_id) + : reconnect_service_id(reconnect_service_id), + is_incoming(is_incoming), + send_disconnection_notification(send_disconnection_notification), + disconnection_reason(disconnection_reason) { + reconnect_cb = std::move(callback); + } + ~ReconnectMetadata() noexcept = default; + ReconnectMetadata(ReconnectMetadata&&) = default; + ReconnectMetadata& operator=(ReconnectMetadata&&) = default; + + AutoReconnectCallback reconnect_cb; + std::string reconnect_service_id; + bool is_incoming; + bool send_disconnection_notification; + DisconnectionReason disconnection_reason = + DisconnectionReason::UNKNOWN_DISCONNECTION_REASON; + }; + + // The entry point for AutoReconect, this API will do the auto reconnect for + // specified "endpoint_id" which connection was lost before. + bool AutoReconnect(ClientProxy* client, const std::string& endpoint_id, + AutoReconnectCallback& callback, + bool send_disconnection_notification, + DisconnectionReason disconnection_reason); + + private: + class MediumConnectionProcessor { + public: + virtual ~MediumConnectionProcessor() = default; + + virtual bool IsMediumRadioOn() const = 0; + virtual bool IsListeningForIncomingConnections() const = 0; + virtual bool StartListeningForIncomingConnections() = 0; + virtual void StopListeningForIncomingConnections() = 0; + virtual bool ConnectOverMedium() = 0; + virtual bool SupportEncryptionDisabled() = 0; + virtual void QuietlyCloseChannelAndSocket() = 0; + }; + + class BaseMediumImpl : public MediumConnectionProcessor { + public: + BaseMediumImpl(ClientProxy* client, const std::string& endpoint_id, + const std::string& reconnect_service_id, bool is_incoming, + Medium medium, Mediums* mediums, + EndpointChannelManager* channel_manager, + ReconnectManager& reconnect_manager) + : client_(client), + endpoint_id_(endpoint_id), + reconnect_service_id_(reconnect_service_id), + is_incoming_(is_incoming), + medium_(medium), + mediums_(mediums), + channel_manager_(channel_manager), + reconnect_manager_(reconnect_manager) {} + ~BaseMediumImpl() override = default; + + bool Run(); + + protected: + ClientProxy* client_; + std::string endpoint_id_; + std::string reconnect_service_id_; + bool is_incoming_; + Medium medium_ = Medium::UNKNOWN_MEDIUM; + Mediums* mediums_; + EndpointChannelManager* channel_manager_; + std::unique_ptr reconnect_channel_; + ReconnectManager& reconnect_manager_; + void OnIncomingConnection(const std::string& reconnect_service_id); + + private: + bool RehostForIncomingConnections(); + bool ReconnectToRemoteDevice(); + + std::string ReadClientIntroductionFrame(EndpointChannel* endpoint_channel); + bool ReadClientIntroductionAckFrame(EndpointChannel* endpoint_channel); + bool ReplaceChannelForEndpoint( + ClientProxy* client, const std::string& endpoint_id, + std::unique_ptr new_channel, + bool support_encryption_disabled, + absl::AnyInvocable stop_listening_incoming_connection); + EncryptionRunner::ResultListener GetResultListener(); + void OnEncryptionSuccessRunnable( + const std::string& endpoint_id, + std::unique_ptr ukey2, + const std::string& auth_token, const ByteArray& raw_auth_token); + void OnEncryptionFailureRunnable(const std::string& endpoint_id, + EndpointChannel* endpoint_channel); + void ProcessSuccessfulReconnection( + const std::string& endpoint_id, + absl::AnyInvocable stop_listening_incoming_connection); + void ProcessFailedReconnection( + const std::string& endpoint_id, + absl::AnyInvocable stop_listening_incoming_connection); + void StopListeningIfAllConnected( + const std::string& reconnect_service_id, + absl::AnyInvocable stop_listening_incoming_connection, + bool force_stop); + bool HasPendingIncomingConnections(const std::string& reconnect_service_id); + void CancelClearHostTimeoutAlarm(const std::string& service_id); + void ClearReconnectData(const std::string& service_id, bool is_incoming); + + std::unique_ptr wait_encryption_to_finish_; + bool replace_channel_succeed_; + }; + + class BluetoothImpl : public BaseMediumImpl { + public: + BluetoothImpl(ClientProxy* client_proxy, const std::string& endpoint_id, + const std::string& reconnect_service_id, bool is_incoming, + Medium medium, Mediums* mediums, + EndpointChannelManager* channel_manager, + ReconnectManager& reconnect_manager) + : BaseMediumImpl(client_proxy, endpoint_id, reconnect_service_id, + is_incoming, medium, mediums, channel_manager, + reconnect_manager), + bluetooth_medium_(mediums_->GetBluetoothClassic()) {} + + bool IsMediumRadioOn() const override; + bool IsListeningForIncomingConnections() const override; + bool StartListeningForIncomingConnections() override; + void StopListeningForIncomingConnections() override; + bool ConnectOverMedium() override; + bool SupportEncryptionDisabled() override; + void QuietlyCloseChannelAndSocket() override; + + private: + void OnIncomingBluetoothConnection(ClientProxy* client, + const std::string& upgrade_service_id, + BluetoothSocket socket); + + BluetoothClassic& bluetooth_medium_; + BluetoothSocket bluetooth_socket_; + }; + + bool Start(bool is_incoming, ClientProxy* client_proxy, + const std::string& endpoint_id, + const std::string& reconnect_service_id, Medium medium); + bool RunOnce(bool is_incoming, ClientProxy* client, + const std::string& endpoint_id, + const std::string& reconnect_service_id, Medium medium); + + void ClearReconnectData(ClientProxy* client, + const std::string& reconnect_service_id, + bool is_incoming); + void Shutdown(); + + Mediums* mediums_; + EndpointChannelManager* channel_manager_; + EncryptionRunner encryption_runner_; + + SingleThreadExecutor reconnect_executor_; + ScheduledExecutor alarm_executor_; + SingleThreadExecutor incoming_connection_cb_executor_; + SingleThreadExecutor encryption_cb_executor_; + + mutable RecursiveMutex mutex_; + absl::flat_hash_map> + listen_timeout_alarm_by_service_id_ ABSL_GUARDED_BY(mutex_); + absl::flat_hash_map> + new_endpoint_channels_; + absl::flat_hash_map endpoint_id_metadata_map_; + absl::flat_hash_set resumed_endpoints_; +}; + +} // namespace connections +} // namespace nearby + +#endif // CORE_INTERNAL_RECONNECTION_MANAGER_H_ diff --git a/connections/implementation/reconnect_manager_test.cc b/connections/implementation/reconnect_manager_test.cc new file mode 100644 index 00000000..1313fef3 --- /dev/null +++ b/connections/implementation/reconnect_manager_test.cc @@ -0,0 +1,149 @@ +// Copyright 2023 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 "connections/implementation/reconnect_manager.h" + +#include +#include + +#include "gtest/gtest.h" +#include "absl/strings/string_view.h" +#include "absl/time/time.h" +#include "connections/implementation/client_proxy.h" +#include "connections/implementation/endpoint_channel_manager.h" +#include "connections/implementation/mediums/mediums.h" +#include "connections/implementation/simulation_user.h" +#include "connections/medium_selector.h" +#include "internal/platform/count_down_latch.h" +#include "internal/platform/logging.h" +#include "internal/platform/medium_environment.h" + +namespace nearby { +namespace connections { +namespace { + +constexpr absl::string_view kServiceId = "service-id"; +constexpr absl::string_view kDeviceA = "device-a"; +constexpr absl::string_view kDeviceB = "device-b"; +constexpr absl::Duration kDefaultTimeout = absl::Milliseconds(1000); + +constexpr BooleanMediumSelector kTestCases[] = { + BooleanMediumSelector{ + .bluetooth = true + }, +}; + +class ReconnectSimulatorUser : public SimulationUser { + public: + explicit ReconnectSimulatorUser( + absl::string_view name, + BooleanMediumSelector allowed = BooleanMediumSelector()) + : SimulationUser(std::string(name), allowed, + SetSafeToDisconnect(true, true, false, 3)) {} + ~ReconnectSimulatorUser() override { + NEARBY_LOGS(INFO) << "ReconnectSimulatorUser: [down] name=" << info_.data(); + } + + bool IsConnected() const { + return client_.IsConnectedToEndpoint(discovered_.endpoint_id); + } + + protected: +}; + +class ReconnectManagerTest + : public ::testing::TestWithParam { + protected: + bool SetupConnection(ReconnectSimulatorUser& user_a, + ReconnectSimulatorUser& user_b) { + user_a.StartAdvertising(std::string(kServiceId), &connection_latch_); + user_b.StartDiscovery(std::string(kServiceId), &discovery_latch_); + EXPECT_TRUE(discovery_latch_.Await(kDefaultTimeout).result()); + EXPECT_EQ(user_b.GetDiscovered().service_id, kServiceId); + EXPECT_EQ(user_b.GetDiscovered().endpoint_info, user_a.GetInfo()); + EXPECT_FALSE(user_b.GetDiscovered().endpoint_id.empty()); + NEARBY_LOGS(INFO) << "EP-B: [discovered]" + << user_b.GetDiscovered().endpoint_id; + user_b.RequestConnection(&connection_latch_); + EXPECT_TRUE(connection_latch_.Await(kDefaultTimeout).result()); + EXPECT_FALSE(user_a.GetDiscovered().endpoint_id.empty()); + NEARBY_LOGS(INFO) << "EP-A: [discovered]" + << user_a.GetDiscovered().endpoint_id; + NEARBY_LOGS(INFO) << "Both users discovered their peers."; + user_a.AcceptConnection(&accept_latch_); + user_b.AcceptConnection(&accept_latch_); + EXPECT_TRUE(accept_latch_.Await(kDefaultTimeout).result()); + NEARBY_LOG(INFO, "Both users reached connected state."); + return user_a.IsConnected() && user_b.IsConnected(); + } + + CountDownLatch discovery_latch_{1}; + CountDownLatch connection_latch_{2}; + CountDownLatch accept_latch_{2}; + CountDownLatch reject_latch_{1}; + MediumEnvironment& env_{MediumEnvironment::Instance()}; +}; + +TEST_P(ReconnectManagerTest, AllowReconnect) { + env_.Start(); + ReconnectSimulatorUser user_a(kDeviceA, GetParam()); + ReconnectSimulatorUser user_b(kDeviceB, GetParam()); + ASSERT_TRUE(SetupConnection(user_a, user_b)); + + Mediums mediums; + ReconnectManager::AutoReconnectCallback auto_reconnect_callback = { + .on_reconnect_success_cb = + [&](ClientProxy* client, const std::string& endpoint_id) { + NEARBY_LOGS(INFO) + << " Reconnect successfully for endpoint_id: " << endpoint_id; + }, + .on_reconnect_failure_cb = + [&](ClientProxy* client, const std::string& endpoint_id, + bool send_disconnection_notification, + DisconnectionReason disconnection_reason) { + NEARBY_LOGS(INFO) + << " Reconnect failed for endpoint_id: " << endpoint_id; + }, + }; + + auto& client_a = user_a.GetClient(); + auto& client_b = user_b.GetClient(); + EndpointChannelManager& ecm_a = user_a.GetEndpointChannelManager(); + EndpointChannelManager& ecm_b = user_b.GetEndpointChannelManager(); + + auto reconnect_manager_a = std::make_unique(mediums, ecm_a); + auto reconnect_manager_b = std::make_unique(mediums, ecm_b); + EXPECT_TRUE(reconnect_manager_a->AutoReconnect( + &client_a, user_a.GetDiscovered().endpoint_id, auto_reconnect_callback, + /*send_disconnection_notification=*/false, + DisconnectionReason::UNFINISHED)); + EXPECT_TRUE(reconnect_manager_b->AutoReconnect( + &client_b, user_b.GetDiscovered().endpoint_id, auto_reconnect_callback, + /*send_disconnection_notification=*/false, + DisconnectionReason::UNFINISHED)); + + NEARBY_LOGS(INFO) << "Test completed."; + user_a.Stop(); + user_b.Stop(); + env_.Stop(); +} + +INSTANTIATE_TEST_SUITE_P(ParametrisedReconnectManagerTest, ReconnectManagerTest, + ::testing::ValuesIn(kTestCases)); + +// More test will be added later. + +} // namespace +} // namespace connections +} // namespace nearby diff --git a/connections/implementation/service_id_constants.h b/connections/implementation/service_id_constants.h index 42728228..dace640c 100644 --- a/connections/implementation/service_id_constants.h +++ b/connections/implementation/service_id_constants.h @@ -19,6 +19,7 @@ #include "absl/strings/match.h" #include "absl/strings/string_view.h" +#include "absl/strings/strip.h" namespace nearby { namespace connections { @@ -28,6 +29,7 @@ constexpr absl::string_view kUnknownServiceId = "UNKNOWN_SERVICE"; // A suffix appended to service IDs when initiating a bandwidth upgrade to // distinguish the mediums from those used for advertising/discovery. constexpr absl::string_view kInitiatorUpgradeServiceIdPostfix = "_UPGRADE"; +constexpr absl::string_view kInitiatorReconnectServiceIdPostfix = "_RECONNECT"; // Returns true if |service_id| not empty and has the initiator's upgrade // postfix. @@ -47,6 +49,37 @@ inline std::string WrapInitiatorUpgradeServiceId(absl::string_view service_id) { std::string(kInitiatorUpgradeServiceIdPostfix); } +// Returns true if |service_id| not empty and has the initiator's reconnect +// postfix. +inline bool IsInitiatorReconnectServiceId(absl::string_view service_id) { + return !service_id.empty() && + absl::EndsWith(service_id, kInitiatorReconnectServiceIdPostfix); +} + +// Appends the kInitiatorReconnectServiceIdPostfix to |service_id| if necessary. +inline std::string WrapInitiatorReconnectServiceId( + absl::string_view service_id) { + // If |service_id| is empty or already has the reconnect postfix, do nothing. + if (service_id.empty() || IsInitiatorReconnectServiceId(service_id)) { + return std::string(service_id); + } + + return std::string(service_id) + + std::string(kInitiatorReconnectServiceIdPostfix); +} + +// Appends the kInitiatorReconnectServiceIdPostfix to |service_id| if necessary. +inline std::string UnWrapInitiatorReconnectServiceId( + absl::string_view service_id) { + // If |service_id| is empty or already has the reconnect postfix, do nothing. + if (service_id.empty() || !IsInitiatorReconnectServiceId(service_id)) { + return std::string(service_id); + } + + return std::string( + absl::StripSuffix(service_id, kInitiatorReconnectServiceIdPostfix)); +} + } // namespace connections } // namespace nearby diff --git a/connections/implementation/simulation_user.h b/connections/implementation/simulation_user.h index 78625612..9fba5c1b 100644 --- a/connections/implementation/simulation_user.h +++ b/connections/implementation/simulation_user.h @@ -15,6 +15,7 @@ #ifndef CORE_INTERNAL_SIMULATION_USER_H_ #define CORE_INTERNAL_SIMULATION_USER_H_ +#include #include #include @@ -45,13 +46,16 @@ namespace connections { class SetSafeToDisconnect { public: - explicit SetSafeToDisconnect(bool safe_to_disconnect, + explicit SetSafeToDisconnect(bool safe_to_disconnect, bool auto_reconnect, bool payload_received_ack, std::int32_t safe_to_disconnect_version) { NearbyFlags::GetInstance().OverrideBoolFlagValue( config_package_nearby::nearby_connections_feature:: kEnableSafeToDisconnect, safe_to_disconnect); + NearbyFlags::GetInstance().OverrideBoolFlagValue( + config_package_nearby::nearby_connections_feature::kEnableAutoReconnect, + auto_reconnect); NearbyFlags::GetInstance().OverrideBoolFlagValue( config_package_nearby::nearby_connections_feature:: kEnablePayloadReceivedAck, @@ -74,9 +78,10 @@ class SimulationUser { void Clear() { endpoint_id.clear(); } }; - explicit SimulationUser( - const std::string& device_name, - BooleanMediumSelector allowed = BooleanMediumSelector()) + SimulationUser(const std::string& device_name, + BooleanMediumSelector allowed = BooleanMediumSelector(), + SetSafeToDisconnect set_safe_to_disconnect = + SetSafeToDisconnect(true, false, true, 2)) : info_{ByteArray{device_name}}, advertising_options_{ { @@ -97,7 +102,8 @@ class SimulationUser { Strategy::kP2pCluster, allowed, }, - } {} + }, + set_safe_to_disconnect_(set_safe_to_disconnect) {} virtual ~SimulationUser() { Stop(); } void Stop() { pm_.DisconnectFromEndpointManager(); @@ -168,6 +174,9 @@ class SimulationUser { absl::AnyInvocable pred, absl::Duration timeout); + ClientProxy& GetClient() { return client_; } + EndpointChannelManager& GetEndpointChannelManager() { return ecm_; } + protected: // ConnectionListener callbacks void OnConnectionInitiated(const std::string& endpoint_id, @@ -206,7 +215,7 @@ class SimulationUser { AdvertisingOptions advertising_options_; ConnectionOptions connection_options_; DiscoveryOptions discovery_options_; - SetSafeToDisconnect set_safe_to_disconnect_{true, true, 2}; + SetSafeToDisconnect set_safe_to_disconnect_; ClientProxy client_; EndpointChannelManager ecm_; EndpointManager em_{&ecm_}; diff --git a/internal/platform/feature_flags.h b/internal/platform/feature_flags.h index 736c8015..43d602e1 100644 --- a/internal/platform/feature_flags.h +++ b/internal/platform/feature_flags.h @@ -63,6 +63,12 @@ class FeatureFlags { // on Windows when connecting to FP service id but the rfcomm is successful. bool skip_service_discovery_before_connecting_to_rfcomm = false; std::int32_t min_nc_version_supports_safe_to_disconnect = 1; + std::int32_t min_nc_version_supports_auto_reconnect = 3; + absl::Duration auto_reconnect_retry_delay_millis = absl::Milliseconds(5000); + absl::Duration auto_reconnect_timeout_millis = absl::Milliseconds(30000); + std::int32_t auto_reconnect_retry_attempts = 3; + absl::Duration auto_reconnect_skip_duplicated_endpoint_duration = + absl::Milliseconds(4000); // Android code won't be able to launch "payload_received_ack" feature for // in near future, so change "payload_received_ack" version from "2" to "5" // after auto-reconnect and auto-resume. @@ -73,6 +79,8 @@ class FeatureFlags { absl::Milliseconds(30000); absl::Duration safe_to_disconnect_remote_disc_delay_millis = absl::Milliseconds(10000); + absl::Duration safe_to_disconnect_auto_resume_timeout_millis = + absl::Milliseconds(60000); // If the receiver doesn't ack with payload_received_ack frame in 1s, the // sender will timeout the waiting. absl::Duration wait_payload_received_ack_millis = absl::Milliseconds(1000); diff --git a/internal/platform/implementation/BUILD b/internal/platform/implementation/BUILD index b672f4b0..3b11e279 100644 --- a/internal/platform/implementation/BUILD +++ b/internal/platform/implementation/BUILD @@ -40,6 +40,7 @@ cc_library( "timer.h", ], visibility = [ + "//connections/implementation:__subpackages__", "//connections/implementation/analytics:__subpackages__", "//fastpair:__subpackages__", "//internal/account:__pkg__", From aea7a09a24f6fe6ba5d41984c3bc52535e9b85de Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Thu, 21 Dec 2023 11:33:58 -0800 Subject: [PATCH 087/683] Switch DeviceInfo to use UTF-8 strings. - Move conversion from native to UTF-8 into platform impl. PiperOrigin-RevId: 592912664 --- internal/platform/device_info.h | 22 +++++------ internal/platform/device_info_impl.cc | 12 +++--- internal/platform/device_info_impl.h | 11 ++++-- .../implementation/apple/device_info.h | 8 ++-- .../implementation/apple/device_info.mm | 16 ++++---- .../platform/implementation/device_info.h | 8 ++-- .../platform/implementation/g3/device_info.h | 16 ++++---- .../implementation/windows/device_info.cc | 39 ++++++++----------- .../implementation/windows/device_info.h | 8 ++-- internal/test/fake_device_info.h | 26 ++++++------- internal/test/fake_device_info_test.cc | 16 ++++---- 11 files changed, 89 insertions(+), 93 deletions(-) diff --git a/internal/platform/device_info.h b/internal/platform/device_info.h index c95f592d..8769d560 100644 --- a/internal/platform/device_info.h +++ b/internal/platform/device_info.h @@ -22,7 +22,6 @@ #include "absl/strings/string_view.h" #include "internal/platform/implementation/device_info.h" -#include "internal/platform/implementation/platform.h" namespace nearby { @@ -30,12 +29,13 @@ class DeviceInfo { public: virtual ~DeviceInfo() = default; - virtual std::u16string GetOsDeviceName() const = 0; + // All strings are UTF-8 encoded. + virtual std::string GetOsDeviceName() const = 0; virtual api::DeviceInfo::DeviceType GetDeviceType() const = 0; virtual api::DeviceInfo::OsType GetOsType() const = 0; - virtual std::optional GetFullName() const = 0; - virtual std::optional GetGivenName() const = 0; - virtual std::optional GetLastName() const = 0; + virtual std::optional GetFullName() const = 0; + virtual std::optional GetGivenName() const = 0; + virtual std::optional GetLastName() const = 0; virtual std::optional GetProfileUserName() const = 0; virtual std::filesystem::path GetDownloadPath() const = 0; @@ -55,18 +55,18 @@ class DeviceInfo { virtual bool PreventSleep() = 0; virtual bool AllowSleep() = 0; - // Returns localized device name depends on device type. - std::u16string GetDeviceTypeName() const { + // Returns UTF-8 encoded localized device name depending on device type. + std::string GetDeviceTypeName() const { // TODO(b/230132370): return localized device name. switch (GetDeviceType()) { case api::DeviceInfo::DeviceType::kPhone: - return u"Phone"; + return "Phone"; case api::DeviceInfo::DeviceType::kTablet: - return u"Tablet"; + return "Tablet"; case api::DeviceInfo::DeviceType::kLaptop: - return u"PC"; + return "PC"; default: - return u"Unknown"; + return "Unknown"; } } }; diff --git a/internal/platform/device_info_impl.cc b/internal/platform/device_info_impl.cc index 6ac551d5..4b18f66a 100644 --- a/internal/platform/device_info_impl.cc +++ b/internal/platform/device_info_impl.cc @@ -21,14 +21,14 @@ namespace nearby { -std::u16string DeviceInfoImpl::GetOsDeviceName() const { - std::optional device_name = +std::string DeviceInfoImpl::GetOsDeviceName() const { + std::optional device_name = device_info_impl_->GetOsDeviceName(); if (device_name.has_value()) { return *device_name; } - return u"unknown"; + return "unknown"; } api::DeviceInfo::DeviceType DeviceInfoImpl::GetDeviceType() const { @@ -39,15 +39,15 @@ api::DeviceInfo::OsType DeviceInfoImpl::GetOsType() const { return device_info_impl_->GetOsType(); } -std::optional DeviceInfoImpl::GetFullName() const { +std::optional DeviceInfoImpl::GetFullName() const { return device_info_impl_->GetFullName(); } -std::optional DeviceInfoImpl::GetGivenName() const { +std::optional DeviceInfoImpl::GetGivenName() const { return device_info_impl_->GetGivenName(); } -std::optional DeviceInfoImpl::GetLastName() const { +std::optional DeviceInfoImpl::GetLastName() const { return device_info_impl_->GetLastName(); } diff --git a/internal/platform/device_info_impl.h b/internal/platform/device_info_impl.h index 98e6032f..5c89c588 100644 --- a/internal/platform/device_info_impl.h +++ b/internal/platform/device_info_impl.h @@ -15,13 +15,16 @@ #ifndef PLATFORM_PUBLIC_DEVICE_INFO_IMPL_H_ #define PLATFORM_PUBLIC_DEVICE_INFO_IMPL_H_ +#include #include #include #include #include #include +#include "absl/strings/string_view.h" #include "internal/platform/device_info.h" +#include "internal/platform/implementation/device_info.h" #include "internal/platform/implementation/platform.h" namespace nearby { @@ -31,13 +34,13 @@ class DeviceInfoImpl : public DeviceInfo { DeviceInfoImpl() : device_info_impl_(api::ImplementationPlatform::CreateDeviceInfo()) {} - std::u16string GetOsDeviceName() const override; + std::string GetOsDeviceName() const override; api::DeviceInfo::DeviceType GetDeviceType() const override; api::DeviceInfo::OsType GetOsType() const override; - std::optional GetFullName() const override; - std::optional GetGivenName() const override; - std::optional GetLastName() const override; + std::optional GetFullName() const override; + std::optional GetGivenName() const override; + std::optional GetLastName() const override; std::optional GetProfileUserName() const override; std::filesystem::path GetDownloadPath() const override; diff --git a/internal/platform/implementation/apple/device_info.h b/internal/platform/implementation/apple/device_info.h index 4315040c..753f166a 100644 --- a/internal/platform/implementation/apple/device_info.h +++ b/internal/platform/implementation/apple/device_info.h @@ -28,15 +28,15 @@ namespace apple { class DeviceInfo : public api::DeviceInfo { public: - std::optional GetOsDeviceName() const override; + std::optional GetOsDeviceName() const override; api::DeviceInfo::DeviceType GetDeviceType() const override; api::DeviceInfo::OsType GetOsType() const override; - std::optional GetFullName() const override; - std::optional GetGivenName() const override; - std::optional GetLastName() const override; + std::optional GetFullName() const override; + std::optional GetGivenName() const override; + std::optional GetLastName() const override; std::optional GetProfileUserName() const override; std::optional GetDownloadPath() const override; diff --git a/internal/platform/implementation/apple/device_info.mm b/internal/platform/implementation/apple/device_info.mm index 6a8d09ee..780dbc8f 100644 --- a/internal/platform/implementation/apple/device_info.mm +++ b/internal/platform/implementation/apple/device_info.mm @@ -33,15 +33,15 @@ namespace nearby { namespace apple { -std::optional DeviceInfo::GetOsDeviceName() const { +std::optional DeviceInfo::GetOsDeviceName() const { #if TARGET_OS_IPHONE NSString *name = UIDevice.currentDevice.name; - const char16_t *cName = (const char16_t *)[name cStringUsingEncoding:NSUTF16StringEncoding]; - return std::u16string(cName); + const char *cName = (const char *)[name cStringUsingEncoding:NSUTF8StringEncoding]; + return std::string(cName); #elif TARGET_OS_OSX NSString *name = NSHost.currentHost.localizedName; - const char16_t *cName = (const char16_t *)[name cStringUsingEncoding:NSUTF16StringEncoding]; - return std::u16string(cName); + const char *cName = (const char *)[name cStringUsingEncoding:NSUTF8StringEncoding]; + return std::string(cName); #else return std::nullopt; #endif @@ -78,9 +78,9 @@ api::DeviceInfo::OsType DeviceInfo::GetOsType() const { #endif } -std::optional DeviceInfo::GetFullName() const { return std::nullopt; } -std::optional DeviceInfo::GetGivenName() const { return std::nullopt; } -std::optional DeviceInfo::GetLastName() const { return std::nullopt; } +std::optional DeviceInfo::GetFullName() const { return std::nullopt; } +std::optional DeviceInfo::GetGivenName() const { return std::nullopt; } +std::optional DeviceInfo::GetLastName() const { return std::nullopt; } std::optional DeviceInfo::GetProfileUserName() const { return std::nullopt; } std::optional DeviceInfo::GetDownloadPath() const { diff --git a/internal/platform/implementation/device_info.h b/internal/platform/implementation/device_info.h index 7b48c608..9c529df0 100644 --- a/internal/platform/implementation/device_info.h +++ b/internal/platform/implementation/device_info.h @@ -41,14 +41,14 @@ class DeviceInfo { virtual ~DeviceInfo() = default; // Gets device name. - virtual std::optional GetOsDeviceName() const = 0; + virtual std::optional GetOsDeviceName() const = 0; virtual DeviceType GetDeviceType() const = 0; virtual OsType GetOsType() const = 0; // Gets basic information of current user. - virtual std::optional GetFullName() const = 0; - virtual std::optional GetGivenName() const = 0; - virtual std::optional GetLastName() const = 0; + virtual std::optional GetFullName() const = 0; + virtual std::optional GetGivenName() const = 0; + virtual std::optional GetLastName() const = 0; virtual std::optional GetProfileUserName() const = 0; // Gets known paths of current user. diff --git a/internal/platform/implementation/g3/device_info.h b/internal/platform/implementation/g3/device_info.h index 87d6a958..8b865916 100644 --- a/internal/platform/implementation/g3/device_info.h +++ b/internal/platform/implementation/g3/device_info.h @@ -30,8 +30,8 @@ namespace g3 { class DeviceInfo : public api::DeviceInfo { public: - std::optional GetOsDeviceName() const override { - return u"Windows"; + std::optional GetOsDeviceName() const override { + return "Windows"; } api::DeviceInfo::DeviceType GetDeviceType() const override { @@ -42,14 +42,14 @@ class DeviceInfo : public api::DeviceInfo { return api::DeviceInfo::OsType::kChromeOs; } - std::optional GetFullName() const override { - return u"nearby"; + std::optional GetFullName() const override { + return "nearby"; } - std::optional GetGivenName() const override { - return u"nearby"; + std::optional GetGivenName() const override { + return "nearby"; } - std::optional GetLastName() const override { - return u"nearby"; + std::optional GetLastName() const override { + return "nearby"; } std::optional GetProfileUserName() const override { return "nearby"; diff --git a/internal/platform/implementation/windows/device_info.cc b/internal/platform/implementation/windows/device_info.cc index 5978f27c..eb21b2b9 100644 --- a/internal/platform/implementation/windows/device_info.cc +++ b/internal/platform/implementation/windows/device_info.cc @@ -18,19 +18,15 @@ #include #include -#include #include #include #include #include -#include -#include "absl/container/flat_hash_map.h" #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" -#include "internal/base/bluetooth_address.h" #include "internal/platform/implementation/device_info.h" -#include "internal/platform/implementation/windows/session_manager.h" +#include "internal/platform/implementation/windows/generated/winrt/base.h" #include "internal/platform/logging.h" #include "winrt/Windows.Foundation.Collections.h" #include "winrt/Windows.Foundation.h" @@ -56,7 +52,7 @@ constexpr char logs_relative_path[] = "Google\\Nearby\\Sharing\\Logs"; constexpr char crash_dumps_relative_path[] = "Google\\Nearby\\Sharing\\CrashDumps"; -std::optional DeviceInfo::GetOsDeviceName() const { +std::optional DeviceInfo::GetOsDeviceName() const { DWORD size = 0; // Get length of the computer name. @@ -70,8 +66,8 @@ std::optional DeviceInfo::GetOsDeviceName() const { WCHAR device_name[size]; if (GetComputerNameExW(ComputerNameDnsHostname, device_name, &size)) { - std::wstring wide_name(device_name); - return std::u16string(wide_name.begin(), wide_name.end()); + winrt::hstring device_name_str(device_name); + return winrt::to_string(device_name_str); } NEARBY_LOGS(ERROR) << ": Failed to get device name, error:" << GetLastError(); @@ -87,7 +83,7 @@ api::DeviceInfo::OsType DeviceInfo::GetOsType() const { return api::DeviceInfo::OsType::kWindows; } -std::optional DeviceInfo::GetFullName() const { +std::optional DeviceInfo::GetFullName() const { // FindAllAsync finds all users that are using this app. When we "Switch User" // on Desktop,FindAllAsync() will still return the current user instead of all // of them because the users who are switched out are not using the apps of @@ -119,19 +115,18 @@ std::optional DeviceInfo::GetFullName() const { return std::nullopt; } winrt::hstring full_name = full_name_obj.as(); - std::wstring wstr(full_name); - std::u16string u16str(wstr.begin(), wstr.end()); + std::string full_name_str = winrt::to_string(full_name); - if (u16str.empty()) { + if (full_name_str.empty()) { NEARBY_LOGS(ERROR) << __func__ << ": Error unboxing string value for full name of user."; return std::nullopt; } - return u16str; + return full_name_str; } -std::optional DeviceInfo::GetGivenName() const { +std::optional DeviceInfo::GetGivenName() const { // FindAllAsync finds all users that are using this app. When we "Switch User" // on Desktop,FindAllAsync() will still return the current user instead of all // of them because the users who are switched out are not using the apps of @@ -163,19 +158,18 @@ std::optional DeviceInfo::GetGivenName() const { return std::nullopt; } winrt::hstring given_name = given_name_obj.as(); - std::wstring wstr(given_name); - std::u16string u16str(wstr.begin(), wstr.end()); + std::string given_name_str = winrt::to_string(given_name); - if (u16str.empty()) { + if (given_name_str.empty()) { NEARBY_LOGS(ERROR) << __func__ << ": Error unboxing string value for first name of user."; return std::nullopt; } - return u16str; + return given_name_str; } -std::optional DeviceInfo::GetLastName() const { +std::optional DeviceInfo::GetLastName() const { // FindAllAsync finds all users that are using this app. When we "Switch User" // on Desktop,FindAllAsync() will still return the current user instead of all // of them because the users who are switched out are not using the apps of @@ -207,16 +201,15 @@ std::optional DeviceInfo::GetLastName() const { return std::nullopt; } winrt::hstring last_name = last_name_obj.as(); - std::wstring wstr(last_name); - std::u16string u16str(wstr.begin(), wstr.end()); + std::string last_name_str = winrt::to_string(last_name); - if (u16str.empty()) { + if (last_name_str.empty()) { NEARBY_LOGS(ERROR) << __func__ << ": Error unboxing string value for last name of user."; return std::nullopt; } - return u16str; + return last_name_str; } std::optional DeviceInfo::GetProfileUserName() const { diff --git a/internal/platform/implementation/windows/device_info.h b/internal/platform/implementation/windows/device_info.h index 79c96771..ced7ddbd 100644 --- a/internal/platform/implementation/windows/device_info.h +++ b/internal/platform/implementation/windows/device_info.h @@ -31,12 +31,12 @@ class DeviceInfo : public api::DeviceInfo { public: ~DeviceInfo() override = default; - std::optional GetOsDeviceName() const override; + std::optional GetOsDeviceName() const override; api::DeviceInfo::DeviceType GetDeviceType() const override; api::DeviceInfo::OsType GetOsType() const override; - std::optional GetFullName() const override; - std::optional GetGivenName() const override; - std::optional GetLastName() const override; + std::optional GetFullName() const override; + std::optional GetGivenName() const override; + std::optional GetLastName() const override; std::optional GetProfileUserName() const override; std::optional GetDownloadPath() const override; diff --git a/internal/test/fake_device_info.h b/internal/test/fake_device_info.h index b7fbf160..f33e223f 100644 --- a/internal/test/fake_device_info.h +++ b/internal/test/fake_device_info.h @@ -15,6 +15,7 @@ #ifndef THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_DEVICE_INFO_H_ #define THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_DEVICE_INFO_H_ +#include #include #include #include @@ -24,7 +25,6 @@ #include "absl/container/flat_hash_map.h" #include "absl/strings/string_view.h" -#include "internal/base/bluetooth_address.h" #include "internal/platform/device_info.h" #include "internal/platform/implementation/device_info.h" @@ -32,7 +32,7 @@ namespace nearby { class FakeDeviceInfo : public DeviceInfo { public: - std::u16string GetOsDeviceName() const override { return device_name_; } + std::string GetOsDeviceName() const override { return device_name_; } api::DeviceInfo::DeviceType GetDeviceType() const override { return device_type_; @@ -40,13 +40,13 @@ class FakeDeviceInfo : public DeviceInfo { api::DeviceInfo::OsType GetOsType() const override { return os_type_; } - std::optional GetFullName() const override { + std::optional GetFullName() const override { return full_name_; } - std::optional GetGivenName() const override { + std::optional GetGivenName() const override { return given_name_; } - std::optional GetLastName() const override { + std::optional GetLastName() const override { return last_name_; } std::optional GetProfileUserName() const override { @@ -93,7 +93,7 @@ class FakeDeviceInfo : public DeviceInfo { int GetScreenLockedListenerCount() { return screen_locked_listeners_.size(); } // Mock methods. - void SetOsDeviceName(std::u16string_view device_name) { + void SetOsDeviceName(std::string_view device_name) { device_name_ = device_name; } @@ -103,7 +103,7 @@ class FakeDeviceInfo : public DeviceInfo { void SetOsType(api::DeviceInfo::OsType os_type) { os_type_ = os_type; } - void SetFullName(std::optional full_name) { + void SetFullName(std::optional full_name) { if (full_name.has_value() && !full_name->empty()) { full_name_ = full_name; } else { @@ -111,7 +111,7 @@ class FakeDeviceInfo : public DeviceInfo { } } - void SetGivenName(std::optional given_name) { + void SetGivenName(std::optional given_name) { if (given_name.has_value() && !given_name->empty()) { given_name_ = given_name; } else { @@ -119,7 +119,7 @@ class FakeDeviceInfo : public DeviceInfo { } } - void SetLastName(std::optional last_name) { + void SetLastName(std::optional last_name) { if (last_name.has_value() && !last_name->empty()) { last_name_ = last_name; } else { @@ -160,13 +160,13 @@ class FakeDeviceInfo : public DeviceInfo { } private: - std::u16string device_name_ = u"nearby"; + std::string device_name_ = "nearby"; api::DeviceInfo::DeviceType device_type_ = api::DeviceInfo::DeviceType::kLaptop; api::DeviceInfo::OsType os_type_ = api::DeviceInfo::OsType::kWindows; - std::optional full_name_ = u"Nearby"; - std::optional given_name_ = u"Nearby"; - std::optional last_name_ = u"Nearby"; + std::optional full_name_ = "Nearby"; + std::optional given_name_ = "Nearby"; + std::optional last_name_ = "Nearby"; std::optional profile_user_name_ = "nearby"; std::filesystem::path download_path_ = std::filesystem::temp_directory_path(); std::filesystem::path app_data_path_ = std::filesystem::temp_directory_path(); diff --git a/internal/test/fake_device_info_test.cc b/internal/test/fake_device_info_test.cc index 16935c43..1a5f120f 100644 --- a/internal/test/fake_device_info_test.cc +++ b/internal/test/fake_device_info_test.cc @@ -27,8 +27,8 @@ namespace { TEST(FakeDeviceInfo, DeviceName) { FakeDeviceInfo device_info; - device_info.SetOsDeviceName(u"windows"); - EXPECT_EQ(device_info.GetOsDeviceName(), u"windows"); + device_info.SetOsDeviceName("windows"); + EXPECT_EQ(device_info.GetOsDeviceName(), "windows"); } TEST(FakeDeviceInfo, DeviceType) { @@ -45,24 +45,24 @@ TEST(FakeDeviceInfo, OsType) { TEST(FakeDeviceInfo, FullName) { FakeDeviceInfo device_info; - device_info.SetFullName(u"windows"); - EXPECT_EQ(device_info.GetFullName(), u"windows"); + device_info.SetFullName("windows"); + EXPECT_EQ(device_info.GetFullName(), "windows"); device_info.SetFullName(std::nullopt); EXPECT_FALSE(device_info.GetFullName().has_value()); } TEST(FakeDeviceInfo, GivenName) { FakeDeviceInfo device_info; - device_info.SetGivenName(u"windows"); - EXPECT_EQ(device_info.GetGivenName(), u"windows"); + device_info.SetGivenName("windows"); + EXPECT_EQ(device_info.GetGivenName(), "windows"); device_info.SetGivenName(std::nullopt); EXPECT_FALSE(device_info.GetGivenName().has_value()); } TEST(FakeDeviceInfo, LastName) { FakeDeviceInfo device_info; - device_info.SetLastName(u"windows"); - EXPECT_EQ(device_info.GetLastName(), u"windows"); + device_info.SetLastName("windows"); + EXPECT_EQ(device_info.GetLastName(), "windows"); device_info.SetLastName(std::nullopt); EXPECT_FALSE(device_info.GetLastName().has_value()); } From 78609d17a1af04d14f1d9d411ff9dcf106c4e6c3 Mon Sep 17 00:00:00 2001 From: Hai Shang Date: Thu, 21 Dec 2023 14:50:29 -0800 Subject: [PATCH 088/683] Internal fix PiperOrigin-RevId: 592955244 --- connections/implementation/client_proxy.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/connections/implementation/client_proxy.cc b/connections/implementation/client_proxy.cc index 3cd87094..07cf4bb1 100644 --- a/connections/implementation/client_proxy.cc +++ b/connections/implementation/client_proxy.cc @@ -400,6 +400,7 @@ void ClientProxy::OnEndpointLost(const std::string& service_id, void ClientProxy::OnRequestConnection( const Strategy& strategy, const std::string& endpoint_id, const ConnectionOptions& connection_options) { + NEARBY_LOGS(INFO) << "ClientProxy [RequestConnection]: id=" << endpoint_id; analytics_recorder_->OnRequestConnection(strategy, endpoint_id); } @@ -451,6 +452,7 @@ void ClientProxy::OnConnectionInitiated( } void ClientProxy::OnConnectionAccepted(const std::string& endpoint_id) { + NEARBY_LOGS(INFO) << "ClientProxy [ConnectionAccepted]: id=" << endpoint_id; MutexLock lock(&mutex_); if (!HasPendingConnectionToEndpoint(endpoint_id)) { @@ -470,6 +472,7 @@ void ClientProxy::OnConnectionAccepted(const std::string& endpoint_id) { void ClientProxy::OnConnectionRejected(const std::string& endpoint_id, const Status& status) { + NEARBY_LOGS(INFO) << "ClientProxy [ConnectionRejected]: id=" << endpoint_id; MutexLock lock(&mutex_); if (!HasPendingConnectionToEndpoint(endpoint_id)) { @@ -489,6 +492,7 @@ void ClientProxy::OnConnectionRejected(const std::string& endpoint_id, void ClientProxy::OnBandwidthChanged(const std::string& endpoint_id, Medium new_medium) { + NEARBY_LOGS(INFO) << "ClientProxy [BandwidthChanged]: id=" << endpoint_id; MutexLock lock(&mutex_); const ConnectionPair* item = LookupConnection(endpoint_id); @@ -501,6 +505,7 @@ void ClientProxy::OnBandwidthChanged(const std::string& endpoint_id, } void ClientProxy::OnDisconnected(const std::string& endpoint_id, bool notify) { + NEARBY_LOGS(INFO) << "ClientProxy [OnDisconnected]: id=" << endpoint_id; MutexLock lock(&mutex_); const ConnectionPair* item = LookupConnection(endpoint_id); From 94ae577069aca0866858d93c9a3624ed371f83d9 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Thu, 21 Dec 2023 16:44:23 -0800 Subject: [PATCH 089/683] - Cleanup BUILD deps PiperOrigin-RevId: 592976313 --- internal/test/BUILD | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/test/BUILD b/internal/test/BUILD index 7512570d..5d9b2c8f 100644 --- a/internal/test/BUILD +++ b/internal/test/BUILD @@ -42,7 +42,6 @@ cc_library( visibility = ["//visibility:public"], deps = [ "//internal/base", - "//internal/base:bluetooth_address", "//internal/data:data_manager", "//internal/network:types", "//internal/platform:comm", From 733a483ee232716bd27c726d972b77f074d019dc Mon Sep 17 00:00:00 2001 From: Anay Wadhera Date: Thu, 4 Jan 2024 22:35:59 -0800 Subject: [PATCH 090/683] Update compiled_proto --- .../proto/offline_wire_formats.pb.cc | 464 ++++++++- .../proto/offline_wire_formats.pb.h | 489 ++++++++- .../proto/analytics/connections_log.pb.cc | 224 ++++- .../proto/analytics/connections_log.pb.h | 230 ++++- compiled_proto/proto/connections_enums.pb.cc | 932 +++++++++--------- compiled_proto/proto/connections_enums.pb.h | 35 +- 6 files changed, 1799 insertions(+), 575 deletions(-) diff --git a/compiled_proto/connections/implementation/proto/offline_wire_formats.pb.cc b/compiled_proto/connections/implementation/proto/offline_wire_formats.pb.cc index 7e041c19..fc18ba66 100644 --- a/compiled_proto/connections/implementation/proto/offline_wire_formats.pb.cc +++ b/compiled_proto/connections/implementation/proto/offline_wire_formats.pb.cc @@ -43,6 +43,7 @@ constexpr V1Frame::V1Frame( , authentication_result_(nullptr) , auto_resume_(nullptr) , auto_reconnect_(nullptr) + , bandwidth_upgrade_retry_(nullptr) , type_(0) {} struct V1FrameDefaultTypeInternal { @@ -306,6 +307,19 @@ struct BandwidthUpgradeNegotiationFrameDefaultTypeInternal { }; }; PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT BandwidthUpgradeNegotiationFrameDefaultTypeInternal _BandwidthUpgradeNegotiationFrame_default_instance_; +constexpr BandwidthUpgradeRetryFrame::BandwidthUpgradeRetryFrame( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : supported_medium_() + , is_request_(false){} +struct BandwidthUpgradeRetryFrameDefaultTypeInternal { + constexpr BandwidthUpgradeRetryFrameDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~BandwidthUpgradeRetryFrameDefaultTypeInternal() {} + union { + BandwidthUpgradeRetryFrame _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT BandwidthUpgradeRetryFrameDefaultTypeInternal _BandwidthUpgradeRetryFrame_default_instance_; constexpr KeepAliveFrame::KeepAliveFrame( ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) : ack_(false) @@ -642,13 +656,14 @@ bool V1Frame_FrameType_IsValid(int value) { case 9: case 10: case 11: + case 12: return true; default: return false; } } -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed V1Frame_FrameType_strings[12] = {}; +static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed V1Frame_FrameType_strings[13] = {}; static const char V1Frame_FrameType_names[] = "AUTHENTICATION_MESSAGE" @@ -656,6 +671,7 @@ static const char V1Frame_FrameType_names[] = "AUTO_RECONNECT" "AUTO_RESUME" "BANDWIDTH_UPGRADE_NEGOTIATION" + "BANDWIDTH_UPGRADE_RETRY" "CONNECTION_REQUEST" "CONNECTION_RESPONSE" "DISCONNECTION" @@ -670,28 +686,30 @@ static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry V1Frame_FrameType_entr { {V1Frame_FrameType_names + 43, 14}, 11 }, { {V1Frame_FrameType_names + 57, 11}, 10 }, { {V1Frame_FrameType_names + 68, 29}, 4 }, - { {V1Frame_FrameType_names + 97, 18}, 1 }, - { {V1Frame_FrameType_names + 115, 19}, 2 }, - { {V1Frame_FrameType_names + 134, 13}, 6 }, - { {V1Frame_FrameType_names + 147, 10}, 5 }, - { {V1Frame_FrameType_names + 157, 21}, 7 }, - { {V1Frame_FrameType_names + 178, 16}, 3 }, - { {V1Frame_FrameType_names + 194, 18}, 0 }, + { {V1Frame_FrameType_names + 97, 23}, 12 }, + { {V1Frame_FrameType_names + 120, 18}, 1 }, + { {V1Frame_FrameType_names + 138, 19}, 2 }, + { {V1Frame_FrameType_names + 157, 13}, 6 }, + { {V1Frame_FrameType_names + 170, 10}, 5 }, + { {V1Frame_FrameType_names + 180, 21}, 7 }, + { {V1Frame_FrameType_names + 201, 16}, 3 }, + { {V1Frame_FrameType_names + 217, 18}, 0 }, }; static const int V1Frame_FrameType_entries_by_number[] = { - 11, // 0 -> UNKNOWN_FRAME_TYPE - 5, // 1 -> CONNECTION_REQUEST - 6, // 2 -> CONNECTION_RESPONSE - 10, // 3 -> PAYLOAD_TRANSFER + 12, // 0 -> UNKNOWN_FRAME_TYPE + 6, // 1 -> CONNECTION_REQUEST + 7, // 2 -> CONNECTION_RESPONSE + 11, // 3 -> PAYLOAD_TRANSFER 4, // 4 -> BANDWIDTH_UPGRADE_NEGOTIATION - 8, // 5 -> KEEP_ALIVE - 7, // 6 -> DISCONNECTION - 9, // 7 -> PAIRED_KEY_ENCRYPTION + 9, // 5 -> KEEP_ALIVE + 8, // 6 -> DISCONNECTION + 10, // 7 -> PAIRED_KEY_ENCRYPTION 0, // 8 -> AUTHENTICATION_MESSAGE 1, // 9 -> AUTHENTICATION_RESULT 3, // 10 -> AUTO_RESUME 2, // 11 -> AUTO_RECONNECT + 5, // 12 -> BANDWIDTH_UPGRADE_RETRY }; const std::string& V1Frame_FrameType_Name( @@ -700,12 +718,12 @@ const std::string& V1Frame_FrameType_Name( ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( V1Frame_FrameType_entries, V1Frame_FrameType_entries_by_number, - 12, V1Frame_FrameType_strings); + 13, V1Frame_FrameType_strings); (void) dummy; int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( V1Frame_FrameType_entries, V1Frame_FrameType_entries_by_number, - 12, value); + 13, value); return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : V1Frame_FrameType_strings[idx].get(); } @@ -713,7 +731,7 @@ bool V1Frame_FrameType_Parse( ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, V1Frame_FrameType* value) { int int_value; bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - V1Frame_FrameType_entries, 12, name, &int_value); + V1Frame_FrameType_entries, 13, name, &int_value); if (success) { *value = static_cast(int_value); } @@ -732,6 +750,7 @@ constexpr V1Frame_FrameType V1Frame::AUTHENTICATION_MESSAGE; constexpr V1Frame_FrameType V1Frame::AUTHENTICATION_RESULT; constexpr V1Frame_FrameType V1Frame::AUTO_RESUME; constexpr V1Frame_FrameType V1Frame::AUTO_RECONNECT; +constexpr V1Frame_FrameType V1Frame::BANDWIDTH_UPGRADE_RETRY; constexpr V1Frame_FrameType V1Frame::FrameType_MIN; constexpr V1Frame_FrameType V1Frame::FrameType_MAX; constexpr int V1Frame::FrameType_ARRAYSIZE; @@ -1101,29 +1120,33 @@ bool PayloadTransferFrame_PacketType_IsValid(int value) { case 0: case 1: case 2: + case 3: return true; default: return false; } } -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed PayloadTransferFrame_PacketType_strings[3] = {}; +static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed PayloadTransferFrame_PacketType_strings[4] = {}; static const char PayloadTransferFrame_PacketType_names[] = "CONTROL" "DATA" + "PAYLOAD_ACK" "UNKNOWN_PACKET_TYPE"; static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry PayloadTransferFrame_PacketType_entries[] = { { {PayloadTransferFrame_PacketType_names + 0, 7}, 2 }, { {PayloadTransferFrame_PacketType_names + 7, 4}, 1 }, - { {PayloadTransferFrame_PacketType_names + 11, 19}, 0 }, + { {PayloadTransferFrame_PacketType_names + 11, 11}, 3 }, + { {PayloadTransferFrame_PacketType_names + 22, 19}, 0 }, }; static const int PayloadTransferFrame_PacketType_entries_by_number[] = { - 2, // 0 -> UNKNOWN_PACKET_TYPE + 3, // 0 -> UNKNOWN_PACKET_TYPE 1, // 1 -> DATA 0, // 2 -> CONTROL + 2, // 3 -> PAYLOAD_ACK }; const std::string& PayloadTransferFrame_PacketType_Name( @@ -1132,12 +1155,12 @@ const std::string& PayloadTransferFrame_PacketType_Name( ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( PayloadTransferFrame_PacketType_entries, PayloadTransferFrame_PacketType_entries_by_number, - 3, PayloadTransferFrame_PacketType_strings); + 4, PayloadTransferFrame_PacketType_strings); (void) dummy; int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( PayloadTransferFrame_PacketType_entries, PayloadTransferFrame_PacketType_entries_by_number, - 3, value); + 4, value); return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : PayloadTransferFrame_PacketType_strings[idx].get(); } @@ -1145,7 +1168,7 @@ bool PayloadTransferFrame_PacketType_Parse( ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, PayloadTransferFrame_PacketType* value) { int int_value; bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - PayloadTransferFrame_PacketType_entries, 3, name, &int_value); + PayloadTransferFrame_PacketType_entries, 4, name, &int_value); if (success) { *value = static_cast(int_value); } @@ -1155,6 +1178,7 @@ bool PayloadTransferFrame_PacketType_Parse( constexpr PayloadTransferFrame_PacketType PayloadTransferFrame::UNKNOWN_PACKET_TYPE; constexpr PayloadTransferFrame_PacketType PayloadTransferFrame::DATA; constexpr PayloadTransferFrame_PacketType PayloadTransferFrame::CONTROL; +constexpr PayloadTransferFrame_PacketType PayloadTransferFrame::PAYLOAD_ACK; constexpr PayloadTransferFrame_PacketType PayloadTransferFrame::PacketType_MIN; constexpr PayloadTransferFrame_PacketType PayloadTransferFrame::PacketType_MAX; constexpr int PayloadTransferFrame::PacketType_ARRAYSIZE; @@ -1345,6 +1369,109 @@ constexpr BandwidthUpgradeNegotiationFrame_EventType BandwidthUpgradeNegotiation constexpr BandwidthUpgradeNegotiationFrame_EventType BandwidthUpgradeNegotiationFrame::EventType_MAX; constexpr int BandwidthUpgradeNegotiationFrame::EventType_ARRAYSIZE; #endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)) +bool BandwidthUpgradeRetryFrame_Medium_IsValid(int value) { + switch (value) { + case 0: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + return true; + default: + return false; + } +} + +static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed BandwidthUpgradeRetryFrame_Medium_strings[11] = {}; + +static const char BandwidthUpgradeRetryFrame_Medium_names[] = + "BLE" + "BLE_L2CAP" + "BLUETOOTH" + "NFC" + "UNKNOWN_MEDIUM" + "USB" + "WEB_RTC" + "WIFI_AWARE" + "WIFI_DIRECT" + "WIFI_HOTSPOT" + "WIFI_LAN"; + +static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry BandwidthUpgradeRetryFrame_Medium_entries[] = { + { {BandwidthUpgradeRetryFrame_Medium_names + 0, 3}, 4 }, + { {BandwidthUpgradeRetryFrame_Medium_names + 3, 9}, 10 }, + { {BandwidthUpgradeRetryFrame_Medium_names + 12, 9}, 2 }, + { {BandwidthUpgradeRetryFrame_Medium_names + 21, 3}, 7 }, + { {BandwidthUpgradeRetryFrame_Medium_names + 24, 14}, 0 }, + { {BandwidthUpgradeRetryFrame_Medium_names + 38, 3}, 11 }, + { {BandwidthUpgradeRetryFrame_Medium_names + 41, 7}, 9 }, + { {BandwidthUpgradeRetryFrame_Medium_names + 48, 10}, 6 }, + { {BandwidthUpgradeRetryFrame_Medium_names + 58, 11}, 8 }, + { {BandwidthUpgradeRetryFrame_Medium_names + 69, 12}, 3 }, + { {BandwidthUpgradeRetryFrame_Medium_names + 81, 8}, 5 }, +}; + +static const int BandwidthUpgradeRetryFrame_Medium_entries_by_number[] = { + 4, // 0 -> UNKNOWN_MEDIUM + 2, // 2 -> BLUETOOTH + 9, // 3 -> WIFI_HOTSPOT + 0, // 4 -> BLE + 10, // 5 -> WIFI_LAN + 7, // 6 -> WIFI_AWARE + 3, // 7 -> NFC + 8, // 8 -> WIFI_DIRECT + 6, // 9 -> WEB_RTC + 1, // 10 -> BLE_L2CAP + 5, // 11 -> USB +}; + +const std::string& BandwidthUpgradeRetryFrame_Medium_Name( + BandwidthUpgradeRetryFrame_Medium value) { + static const bool dummy = + ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( + BandwidthUpgradeRetryFrame_Medium_entries, + BandwidthUpgradeRetryFrame_Medium_entries_by_number, + 11, BandwidthUpgradeRetryFrame_Medium_strings); + (void) dummy; + int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( + BandwidthUpgradeRetryFrame_Medium_entries, + BandwidthUpgradeRetryFrame_Medium_entries_by_number, + 11, value); + return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : + BandwidthUpgradeRetryFrame_Medium_strings[idx].get(); +} +bool BandwidthUpgradeRetryFrame_Medium_Parse( + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, BandwidthUpgradeRetryFrame_Medium* value) { + int int_value; + bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( + BandwidthUpgradeRetryFrame_Medium_entries, 11, name, &int_value); + if (success) { + *value = static_cast(int_value); + } + return success; +} +#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)) +constexpr BandwidthUpgradeRetryFrame_Medium BandwidthUpgradeRetryFrame::UNKNOWN_MEDIUM; +constexpr BandwidthUpgradeRetryFrame_Medium BandwidthUpgradeRetryFrame::BLUETOOTH; +constexpr BandwidthUpgradeRetryFrame_Medium BandwidthUpgradeRetryFrame::WIFI_HOTSPOT; +constexpr BandwidthUpgradeRetryFrame_Medium BandwidthUpgradeRetryFrame::BLE; +constexpr BandwidthUpgradeRetryFrame_Medium BandwidthUpgradeRetryFrame::WIFI_LAN; +constexpr BandwidthUpgradeRetryFrame_Medium BandwidthUpgradeRetryFrame::WIFI_AWARE; +constexpr BandwidthUpgradeRetryFrame_Medium BandwidthUpgradeRetryFrame::NFC; +constexpr BandwidthUpgradeRetryFrame_Medium BandwidthUpgradeRetryFrame::WIFI_DIRECT; +constexpr BandwidthUpgradeRetryFrame_Medium BandwidthUpgradeRetryFrame::WEB_RTC; +constexpr BandwidthUpgradeRetryFrame_Medium BandwidthUpgradeRetryFrame::BLE_L2CAP; +constexpr BandwidthUpgradeRetryFrame_Medium BandwidthUpgradeRetryFrame::USB; +constexpr BandwidthUpgradeRetryFrame_Medium BandwidthUpgradeRetryFrame::Medium_MIN; +constexpr BandwidthUpgradeRetryFrame_Medium BandwidthUpgradeRetryFrame::Medium_MAX; +constexpr int BandwidthUpgradeRetryFrame::Medium_ARRAYSIZE; +#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)) bool AutoResumeFrame_EventType_IsValid(int value) { switch (value) { case 0: @@ -2009,7 +2136,7 @@ class V1Frame::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); static void set_has_type(HasBits* has_bits) { - (*has_bits)[0] |= 2048u; + (*has_bits)[0] |= 4096u; } static const ::location::nearby::connections::ConnectionRequestFrame& connection_request(const V1Frame* msg); static void set_has_connection_request(HasBits* has_bits) { @@ -2055,6 +2182,10 @@ class V1Frame::_Internal { static void set_has_auto_reconnect(HasBits* has_bits) { (*has_bits)[0] |= 1024u; } + static const ::location::nearby::connections::BandwidthUpgradeRetryFrame& bandwidth_upgrade_retry(const V1Frame* msg); + static void set_has_bandwidth_upgrade_retry(HasBits* has_bits) { + (*has_bits)[0] |= 2048u; + } }; const ::location::nearby::connections::ConnectionRequestFrame& @@ -2101,6 +2232,10 @@ const ::location::nearby::connections::AutoReconnectFrame& V1Frame::_Internal::auto_reconnect(const V1Frame* msg) { return *msg->auto_reconnect_; } +const ::location::nearby::connections::BandwidthUpgradeRetryFrame& +V1Frame::_Internal::bandwidth_upgrade_retry(const V1Frame* msg) { + return *msg->bandwidth_upgrade_retry_; +} V1Frame::V1Frame(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned) : ::PROTOBUF_NAMESPACE_ID::MessageLite(arena, is_message_owned) { @@ -2169,6 +2304,11 @@ V1Frame::V1Frame(const V1Frame& from) } else { auto_reconnect_ = nullptr; } + if (from._internal_has_bandwidth_upgrade_retry()) { + bandwidth_upgrade_retry_ = new ::location::nearby::connections::BandwidthUpgradeRetryFrame(*from.bandwidth_upgrade_retry_); + } else { + bandwidth_upgrade_retry_ = nullptr; + } type_ = from.type_; // @@protoc_insertion_point(copy_constructor:location.nearby.connections.V1Frame) } @@ -2200,6 +2340,7 @@ inline void V1Frame::SharedDtor() { if (this != internal_default_instance()) delete authentication_result_; if (this != internal_default_instance()) delete auto_resume_; if (this != internal_default_instance()) delete auto_reconnect_; + if (this != internal_default_instance()) delete bandwidth_upgrade_retry_; } void V1Frame::ArenaDtor(void* object) { @@ -2253,7 +2394,7 @@ void V1Frame::Clear() { authentication_message_->Clear(); } } - if (cached_has_bits & 0x00000700u) { + if (cached_has_bits & 0x00000f00u) { if (cached_has_bits & 0x00000100u) { GOOGLE_DCHECK(authentication_result_ != nullptr); authentication_result_->Clear(); @@ -2266,6 +2407,10 @@ void V1Frame::Clear() { GOOGLE_DCHECK(auto_reconnect_ != nullptr); auto_reconnect_->Clear(); } + if (cached_has_bits & 0x00000800u) { + GOOGLE_DCHECK(bandwidth_upgrade_retry_ != nullptr); + bandwidth_upgrade_retry_->Clear(); + } } type_ = 0; _has_bits_.Clear(); @@ -2380,6 +2525,14 @@ const char* V1Frame::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::in } else goto handle_unusual; continue; + // optional .location.nearby.connections.BandwidthUpgradeRetryFrame bandwidth_upgrade_retry = 13; + case 13: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 106)) { + ptr = ctx->ParseMessage(_internal_mutable_bandwidth_upgrade_retry(), ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; default: goto handle_unusual; } // switch @@ -2412,7 +2565,7 @@ uint8_t* V1Frame::_InternalSerialize( cached_has_bits = _has_bits_[0]; // optional .location.nearby.connections.V1Frame.FrameType type = 1; - if (cached_has_bits & 0x00000800u) { + if (cached_has_bits & 0x00001000u) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( 1, this->_internal_type(), target); @@ -2506,6 +2659,14 @@ uint8_t* V1Frame::_InternalSerialize( 12, _Internal::auto_reconnect(this), target, stream); } + // optional .location.nearby.connections.BandwidthUpgradeRetryFrame bandwidth_upgrade_retry = 13; + if (cached_has_bits & 0x00000800u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage( + 13, _Internal::bandwidth_upgrade_retry(this), target, stream); + } + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = stream->WriteRaw(_internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).data(), static_cast(_internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size()), target); @@ -2581,7 +2742,7 @@ size_t V1Frame::ByteSizeLong() const { } } - if (cached_has_bits & 0x00000f00u) { + if (cached_has_bits & 0x00001f00u) { // optional .location.nearby.connections.AuthenticationResultFrame authentication_result = 10; if (cached_has_bits & 0x00000100u) { total_size += 1 + @@ -2603,8 +2764,15 @@ size_t V1Frame::ByteSizeLong() const { *auto_reconnect_); } - // optional .location.nearby.connections.V1Frame.FrameType type = 1; + // optional .location.nearby.connections.BandwidthUpgradeRetryFrame bandwidth_upgrade_retry = 13; if (cached_has_bits & 0x00000800u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *bandwidth_upgrade_retry_); + } + + // optional .location.nearby.connections.V1Frame.FrameType type = 1; + if (cached_has_bits & 0x00001000u) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_type()); } @@ -2657,7 +2825,7 @@ void V1Frame::MergeFrom(const V1Frame& from) { _internal_mutable_authentication_message()->::location::nearby::connections::AuthenticationMessageFrame::MergeFrom(from._internal_authentication_message()); } } - if (cached_has_bits & 0x00000f00u) { + if (cached_has_bits & 0x00001f00u) { if (cached_has_bits & 0x00000100u) { _internal_mutable_authentication_result()->::location::nearby::connections::AuthenticationResultFrame::MergeFrom(from._internal_authentication_result()); } @@ -2668,6 +2836,9 @@ void V1Frame::MergeFrom(const V1Frame& from) { _internal_mutable_auto_reconnect()->::location::nearby::connections::AutoReconnectFrame::MergeFrom(from._internal_auto_reconnect()); } if (cached_has_bits & 0x00000800u) { + _internal_mutable_bandwidth_upgrade_retry()->::location::nearby::connections::BandwidthUpgradeRetryFrame::MergeFrom(from._internal_bandwidth_upgrade_retry()); + } + if (cached_has_bits & 0x00001000u) { type_ = from.type_; } _has_bits_[0] |= cached_has_bits; @@ -8338,6 +8509,236 @@ std::string BandwidthUpgradeNegotiationFrame::GetTypeName() const { } +// =================================================================== + +class BandwidthUpgradeRetryFrame::_Internal { + public: + using HasBits = decltype(std::declval()._has_bits_); + static void set_has_is_request(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } +}; + +BandwidthUpgradeRetryFrame::BandwidthUpgradeRetryFrame(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::MessageLite(arena, is_message_owned), + supported_medium_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:location.nearby.connections.BandwidthUpgradeRetryFrame) +} +BandwidthUpgradeRetryFrame::BandwidthUpgradeRetryFrame(const BandwidthUpgradeRetryFrame& from) + : ::PROTOBUF_NAMESPACE_ID::MessageLite(), + _has_bits_(from._has_bits_), + supported_medium_(from.supported_medium_) { + _internal_metadata_.MergeFrom(from._internal_metadata_); + is_request_ = from.is_request_; + // @@protoc_insertion_point(copy_constructor:location.nearby.connections.BandwidthUpgradeRetryFrame) +} + +inline void BandwidthUpgradeRetryFrame::SharedCtor() { +is_request_ = false; +} + +BandwidthUpgradeRetryFrame::~BandwidthUpgradeRetryFrame() { + // @@protoc_insertion_point(destructor:location.nearby.connections.BandwidthUpgradeRetryFrame) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete(); +} + +inline void BandwidthUpgradeRetryFrame::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void BandwidthUpgradeRetryFrame::ArenaDtor(void* object) { + BandwidthUpgradeRetryFrame* _this = reinterpret_cast< BandwidthUpgradeRetryFrame* >(object); + (void)_this; +} +void BandwidthUpgradeRetryFrame::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void BandwidthUpgradeRetryFrame::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void BandwidthUpgradeRetryFrame::Clear() { +// @@protoc_insertion_point(message_clear_start:location.nearby.connections.BandwidthUpgradeRetryFrame) + uint32_t cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + supported_medium_.Clear(); + is_request_ = false; + _has_bits_.Clear(); + _internal_metadata_.Clear(); +} + +const char* BandwidthUpgradeRetryFrame::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + uint32_t tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // repeated .location.nearby.connections.BandwidthUpgradeRetryFrame.Medium supported_medium = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 8)) { + ptr -= 1; + do { + ptr += 1; + uint64_t val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + if (PROTOBUF_PREDICT_TRUE(::location::nearby::connections::BandwidthUpgradeRetryFrame_Medium_IsValid(val))) { + _internal_add_supported_medium(static_cast<::location::nearby::connections::BandwidthUpgradeRetryFrame_Medium>(val)); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(1, val, mutable_unknown_fields()); + } + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<8>(ptr)); + } else if (static_cast(tag) == 10) { + ptr = ::PROTOBUF_NAMESPACE_ID::internal::PackedEnumParser(_internal_mutable_supported_medium(), ptr, ctx, ::location::nearby::connections::BandwidthUpgradeRetryFrame_Medium_IsValid, &_internal_metadata_, 1); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional bool is_request = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 16)) { + _Internal::set_has_is_request(&has_bits); + is_request_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* BandwidthUpgradeRetryFrame::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:location.nearby.connections.BandwidthUpgradeRetryFrame) + uint32_t cached_has_bits = 0; + (void) cached_has_bits; + + // repeated .location.nearby.connections.BandwidthUpgradeRetryFrame.Medium supported_medium = 1; + for (int i = 0, n = this->_internal_supported_medium_size(); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( + 1, this->_internal_supported_medium(i), target); + } + + cached_has_bits = _has_bits_[0]; + // optional bool is_request = 2; + if (cached_has_bits & 0x00000001u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(2, this->_internal_is_request(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = stream->WriteRaw(_internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).data(), + static_cast(_internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size()), target); + } + // @@protoc_insertion_point(serialize_to_array_end:location.nearby.connections.BandwidthUpgradeRetryFrame) + return target; +} + +size_t BandwidthUpgradeRetryFrame::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:location.nearby.connections.BandwidthUpgradeRetryFrame) + size_t total_size = 0; + + uint32_t cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .location.nearby.connections.BandwidthUpgradeRetryFrame.Medium supported_medium = 1; + { + size_t data_size = 0; + unsigned int count = static_cast(this->_internal_supported_medium_size());for (unsigned int i = 0; i < count; i++) { + data_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize( + this->_internal_supported_medium(static_cast(i))); + } + total_size += (1UL * count) + data_size; + } + + // optional bool is_request = 2; + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000001u) { + total_size += 1 + 1; + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + total_size += _internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size(); + } + int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); + SetCachedSize(cached_size); + return total_size; +} + +void BandwidthUpgradeRetryFrame::CheckTypeAndMergeFrom( + const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { + MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( + &from)); +} + +void BandwidthUpgradeRetryFrame::MergeFrom(const BandwidthUpgradeRetryFrame& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:location.nearby.connections.BandwidthUpgradeRetryFrame) + GOOGLE_DCHECK_NE(&from, this); + uint32_t cached_has_bits = 0; + (void) cached_has_bits; + + supported_medium_.MergeFrom(from.supported_medium_); + if (from._internal_has_is_request()) { + _internal_set_is_request(from._internal_is_request()); + } + _internal_metadata_.MergeFrom(from._internal_metadata_); +} + +void BandwidthUpgradeRetryFrame::CopyFrom(const BandwidthUpgradeRetryFrame& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:location.nearby.connections.BandwidthUpgradeRetryFrame) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool BandwidthUpgradeRetryFrame::IsInitialized() const { + return true; +} + +void BandwidthUpgradeRetryFrame::InternalSwap(BandwidthUpgradeRetryFrame* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_has_bits_[0], other->_has_bits_[0]); + supported_medium_.InternalSwap(&other->supported_medium_); + swap(is_request_, other->is_request_); +} + +std::string BandwidthUpgradeRetryFrame::GetTypeName() const { + return "location.nearby.connections.BandwidthUpgradeRetryFrame"; +} + + // =================================================================== class KeepAliveFrame::_Internal { @@ -13083,6 +13484,9 @@ template<> PROTOBUF_NOINLINE ::location::nearby::connections::BandwidthUpgradeNe template<> PROTOBUF_NOINLINE ::location::nearby::connections::BandwidthUpgradeNegotiationFrame* Arena::CreateMaybeMessage< ::location::nearby::connections::BandwidthUpgradeNegotiationFrame >(Arena* arena) { return Arena::CreateMessageInternal< ::location::nearby::connections::BandwidthUpgradeNegotiationFrame >(arena); } +template<> PROTOBUF_NOINLINE ::location::nearby::connections::BandwidthUpgradeRetryFrame* Arena::CreateMaybeMessage< ::location::nearby::connections::BandwidthUpgradeRetryFrame >(Arena* arena) { + return Arena::CreateMessageInternal< ::location::nearby::connections::BandwidthUpgradeRetryFrame >(arena); +} template<> PROTOBUF_NOINLINE ::location::nearby::connections::KeepAliveFrame* Arena::CreateMaybeMessage< ::location::nearby::connections::KeepAliveFrame >(Arena* arena) { return Arena::CreateMessageInternal< ::location::nearby::connections::KeepAliveFrame >(arena); } diff --git a/compiled_proto/connections/implementation/proto/offline_wire_formats.pb.h b/compiled_proto/connections/implementation/proto/offline_wire_formats.pb.h index 22ca5e23..ca2d04a6 100644 --- a/compiled_proto/connections/implementation/proto/offline_wire_formats.pb.h +++ b/compiled_proto/connections/implementation/proto/offline_wire_formats.pb.h @@ -45,7 +45,7 @@ struct TableStruct_connections_2fimplementation_2fproto_2foffline_5fwire_5fforma PROTOBUF_SECTION_VARIABLE(protodesc_cold); static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[36] + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[37] PROTOBUF_SECTION_VARIABLE(protodesc_cold); static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; @@ -99,6 +99,9 @@ extern BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiHotspotCredentialsDe class BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiLanSocket; struct BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiLanSocketDefaultTypeInternal; extern BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiLanSocketDefaultTypeInternal _BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiLanSocket_default_instance_; +class BandwidthUpgradeRetryFrame; +struct BandwidthUpgradeRetryFrameDefaultTypeInternal; +extern BandwidthUpgradeRetryFrameDefaultTypeInternal _BandwidthUpgradeRetryFrame_default_instance_; class ConnectionRequestFrame; struct ConnectionRequestFrameDefaultTypeInternal; extern ConnectionRequestFrameDefaultTypeInternal _ConnectionRequestFrame_default_instance_; @@ -181,6 +184,7 @@ template<> ::location::nearby::connections::BandwidthUpgradeNegotiationFrame_Upg template<> ::location::nearby::connections::BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials* Arena::CreateMaybeMessage<::location::nearby::connections::BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials>(Arena*); template<> ::location::nearby::connections::BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiHotspotCredentials* Arena::CreateMaybeMessage<::location::nearby::connections::BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiHotspotCredentials>(Arena*); template<> ::location::nearby::connections::BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiLanSocket* Arena::CreateMaybeMessage<::location::nearby::connections::BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiLanSocket>(Arena*); +template<> ::location::nearby::connections::BandwidthUpgradeRetryFrame* Arena::CreateMaybeMessage<::location::nearby::connections::BandwidthUpgradeRetryFrame>(Arena*); template<> ::location::nearby::connections::ConnectionRequestFrame* Arena::CreateMaybeMessage<::location::nearby::connections::ConnectionRequestFrame>(Arena*); template<> ::location::nearby::connections::ConnectionResponseFrame* Arena::CreateMaybeMessage<::location::nearby::connections::ConnectionResponseFrame>(Arena*); template<> ::location::nearby::connections::ConnectionsDevice* Arena::CreateMaybeMessage<::location::nearby::connections::ConnectionsDevice>(Arena*); @@ -238,11 +242,12 @@ enum V1Frame_FrameType : int { V1Frame_FrameType_AUTHENTICATION_MESSAGE = 8, V1Frame_FrameType_AUTHENTICATION_RESULT = 9, V1Frame_FrameType_AUTO_RESUME = 10, - V1Frame_FrameType_AUTO_RECONNECT = 11 + V1Frame_FrameType_AUTO_RECONNECT = 11, + V1Frame_FrameType_BANDWIDTH_UPGRADE_RETRY = 12 }; bool V1Frame_FrameType_IsValid(int value); constexpr V1Frame_FrameType V1Frame_FrameType_FrameType_MIN = V1Frame_FrameType_UNKNOWN_FRAME_TYPE; -constexpr V1Frame_FrameType V1Frame_FrameType_FrameType_MAX = V1Frame_FrameType_AUTO_RECONNECT; +constexpr V1Frame_FrameType V1Frame_FrameType_FrameType_MAX = V1Frame_FrameType_BANDWIDTH_UPGRADE_RETRY; constexpr int V1Frame_FrameType_FrameType_ARRAYSIZE = V1Frame_FrameType_FrameType_MAX + 1; const std::string& V1Frame_FrameType_Name(V1Frame_FrameType value); @@ -347,7 +352,7 @@ enum PayloadTransferFrame_ControlMessage_EventType : int { PayloadTransferFrame_ControlMessage_EventType_UNKNOWN_EVENT_TYPE = 0, PayloadTransferFrame_ControlMessage_EventType_PAYLOAD_ERROR = 1, PayloadTransferFrame_ControlMessage_EventType_PAYLOAD_CANCELED = 2, - PayloadTransferFrame_ControlMessage_EventType_PAYLOAD_RECEIVED_ACK = 3 + PayloadTransferFrame_ControlMessage_EventType_PAYLOAD_RECEIVED_ACK PROTOBUF_DEPRECATED_ENUM = 3 }; bool PayloadTransferFrame_ControlMessage_EventType_IsValid(int value); constexpr PayloadTransferFrame_ControlMessage_EventType PayloadTransferFrame_ControlMessage_EventType_EventType_MIN = PayloadTransferFrame_ControlMessage_EventType_UNKNOWN_EVENT_TYPE; @@ -367,11 +372,12 @@ bool PayloadTransferFrame_ControlMessage_EventType_Parse( enum PayloadTransferFrame_PacketType : int { PayloadTransferFrame_PacketType_UNKNOWN_PACKET_TYPE = 0, PayloadTransferFrame_PacketType_DATA = 1, - PayloadTransferFrame_PacketType_CONTROL = 2 + PayloadTransferFrame_PacketType_CONTROL = 2, + PayloadTransferFrame_PacketType_PAYLOAD_ACK = 3 }; bool PayloadTransferFrame_PacketType_IsValid(int value); constexpr PayloadTransferFrame_PacketType PayloadTransferFrame_PacketType_PacketType_MIN = PayloadTransferFrame_PacketType_UNKNOWN_PACKET_TYPE; -constexpr PayloadTransferFrame_PacketType PayloadTransferFrame_PacketType_PacketType_MAX = PayloadTransferFrame_PacketType_CONTROL; +constexpr PayloadTransferFrame_PacketType PayloadTransferFrame_PacketType_PacketType_MAX = PayloadTransferFrame_PacketType_PAYLOAD_ACK; constexpr int PayloadTransferFrame_PacketType_PacketType_ARRAYSIZE = PayloadTransferFrame_PacketType_PacketType_MAX + 1; const std::string& PayloadTransferFrame_PacketType_Name(PayloadTransferFrame_PacketType value); @@ -436,6 +442,34 @@ inline const std::string& BandwidthUpgradeNegotiationFrame_EventType_Name(T enum } bool BandwidthUpgradeNegotiationFrame_EventType_Parse( ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, BandwidthUpgradeNegotiationFrame_EventType* value); +enum BandwidthUpgradeRetryFrame_Medium : int { + BandwidthUpgradeRetryFrame_Medium_UNKNOWN_MEDIUM = 0, + BandwidthUpgradeRetryFrame_Medium_BLUETOOTH = 2, + BandwidthUpgradeRetryFrame_Medium_WIFI_HOTSPOT = 3, + BandwidthUpgradeRetryFrame_Medium_BLE = 4, + BandwidthUpgradeRetryFrame_Medium_WIFI_LAN = 5, + BandwidthUpgradeRetryFrame_Medium_WIFI_AWARE = 6, + BandwidthUpgradeRetryFrame_Medium_NFC = 7, + BandwidthUpgradeRetryFrame_Medium_WIFI_DIRECT = 8, + BandwidthUpgradeRetryFrame_Medium_WEB_RTC = 9, + BandwidthUpgradeRetryFrame_Medium_BLE_L2CAP = 10, + BandwidthUpgradeRetryFrame_Medium_USB = 11 +}; +bool BandwidthUpgradeRetryFrame_Medium_IsValid(int value); +constexpr BandwidthUpgradeRetryFrame_Medium BandwidthUpgradeRetryFrame_Medium_Medium_MIN = BandwidthUpgradeRetryFrame_Medium_UNKNOWN_MEDIUM; +constexpr BandwidthUpgradeRetryFrame_Medium BandwidthUpgradeRetryFrame_Medium_Medium_MAX = BandwidthUpgradeRetryFrame_Medium_USB; +constexpr int BandwidthUpgradeRetryFrame_Medium_Medium_ARRAYSIZE = BandwidthUpgradeRetryFrame_Medium_Medium_MAX + 1; + +const std::string& BandwidthUpgradeRetryFrame_Medium_Name(BandwidthUpgradeRetryFrame_Medium value); +template +inline const std::string& BandwidthUpgradeRetryFrame_Medium_Name(T enum_t_value) { + static_assert(::std::is_same::value || + ::std::is_integral::value, + "Incorrect type passed to function BandwidthUpgradeRetryFrame_Medium_Name."); + return BandwidthUpgradeRetryFrame_Medium_Name(static_cast(enum_t_value)); +} +bool BandwidthUpgradeRetryFrame_Medium_Parse( + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, BandwidthUpgradeRetryFrame_Medium* value); enum AutoResumeFrame_EventType : int { AutoResumeFrame_EventType_UNKNOWN_AUTO_RESUME_EVENT_TYPE = 0, AutoResumeFrame_EventType_PAYLOAD_RESUME_TRANSFER_START = 1, @@ -888,6 +922,8 @@ class V1Frame final : V1Frame_FrameType_AUTO_RESUME; static constexpr FrameType AUTO_RECONNECT = V1Frame_FrameType_AUTO_RECONNECT; + static constexpr FrameType BANDWIDTH_UPGRADE_RETRY = + V1Frame_FrameType_BANDWIDTH_UPGRADE_RETRY; static inline bool FrameType_IsValid(int value) { return V1Frame_FrameType_IsValid(value); } @@ -923,6 +959,7 @@ class V1Frame final : kAuthenticationResultFieldNumber = 10, kAutoResumeFieldNumber = 11, kAutoReconnectFieldNumber = 12, + kBandwidthUpgradeRetryFieldNumber = 13, kTypeFieldNumber = 1, }; // optional .location.nearby.connections.ConnectionRequestFrame connection_request = 2; @@ -1123,6 +1160,24 @@ class V1Frame final : ::location::nearby::connections::AutoReconnectFrame* auto_reconnect); ::location::nearby::connections::AutoReconnectFrame* unsafe_arena_release_auto_reconnect(); + // optional .location.nearby.connections.BandwidthUpgradeRetryFrame bandwidth_upgrade_retry = 13; + bool has_bandwidth_upgrade_retry() const; + private: + bool _internal_has_bandwidth_upgrade_retry() const; + public: + void clear_bandwidth_upgrade_retry(); + const ::location::nearby::connections::BandwidthUpgradeRetryFrame& bandwidth_upgrade_retry() const; + PROTOBUF_NODISCARD ::location::nearby::connections::BandwidthUpgradeRetryFrame* release_bandwidth_upgrade_retry(); + ::location::nearby::connections::BandwidthUpgradeRetryFrame* mutable_bandwidth_upgrade_retry(); + void set_allocated_bandwidth_upgrade_retry(::location::nearby::connections::BandwidthUpgradeRetryFrame* bandwidth_upgrade_retry); + private: + const ::location::nearby::connections::BandwidthUpgradeRetryFrame& _internal_bandwidth_upgrade_retry() const; + ::location::nearby::connections::BandwidthUpgradeRetryFrame* _internal_mutable_bandwidth_upgrade_retry(); + public: + void unsafe_arena_set_allocated_bandwidth_upgrade_retry( + ::location::nearby::connections::BandwidthUpgradeRetryFrame* bandwidth_upgrade_retry); + ::location::nearby::connections::BandwidthUpgradeRetryFrame* unsafe_arena_release_bandwidth_upgrade_retry(); + // optional .location.nearby.connections.V1Frame.FrameType type = 1; bool has_type() const; private: @@ -1156,6 +1211,7 @@ class V1Frame final : ::location::nearby::connections::AuthenticationResultFrame* authentication_result_; ::location::nearby::connections::AutoResumeFrame* auto_resume_; ::location::nearby::connections::AutoReconnectFrame* auto_reconnect_; + ::location::nearby::connections::BandwidthUpgradeRetryFrame* bandwidth_upgrade_retry_; int type_; friend struct ::TableStruct_connections_2fimplementation_2fproto_2foffline_5fwire_5fformats_2eproto; }; @@ -2452,7 +2508,7 @@ class PayloadTransferFrame_ControlMessage final : PayloadTransferFrame_ControlMessage_EventType_PAYLOAD_ERROR; static constexpr EventType PAYLOAD_CANCELED = PayloadTransferFrame_ControlMessage_EventType_PAYLOAD_CANCELED; - static constexpr EventType PAYLOAD_RECEIVED_ACK = + PROTOBUF_DEPRECATED_ENUM static constexpr EventType PAYLOAD_RECEIVED_ACK = PayloadTransferFrame_ControlMessage_EventType_PAYLOAD_RECEIVED_ACK; static inline bool EventType_IsValid(int value) { return PayloadTransferFrame_ControlMessage_EventType_IsValid(value); @@ -2643,6 +2699,8 @@ class PayloadTransferFrame final : PayloadTransferFrame_PacketType_DATA; static constexpr PacketType CONTROL = PayloadTransferFrame_PacketType_CONTROL; + static constexpr PacketType PAYLOAD_ACK = + PayloadTransferFrame_PacketType_PAYLOAD_ACK; static inline bool PacketType_IsValid(int value) { return PayloadTransferFrame_PacketType_IsValid(value); } @@ -4766,6 +4824,211 @@ class BandwidthUpgradeNegotiationFrame final : }; // ------------------------------------------------------------------- +class BandwidthUpgradeRetryFrame final : + public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:location.nearby.connections.BandwidthUpgradeRetryFrame) */ { + public: + inline BandwidthUpgradeRetryFrame() : BandwidthUpgradeRetryFrame(nullptr) {} + ~BandwidthUpgradeRetryFrame() override; + explicit constexpr BandwidthUpgradeRetryFrame(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + BandwidthUpgradeRetryFrame(const BandwidthUpgradeRetryFrame& from); + BandwidthUpgradeRetryFrame(BandwidthUpgradeRetryFrame&& from) noexcept + : BandwidthUpgradeRetryFrame() { + *this = ::std::move(from); + } + + inline BandwidthUpgradeRetryFrame& operator=(const BandwidthUpgradeRetryFrame& from) { + CopyFrom(from); + return *this; + } + inline BandwidthUpgradeRetryFrame& operator=(BandwidthUpgradeRetryFrame&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const std::string& unknown_fields() const { + return _internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString); + } + inline std::string* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const BandwidthUpgradeRetryFrame& default_instance() { + return *internal_default_instance(); + } + static inline const BandwidthUpgradeRetryFrame* internal_default_instance() { + return reinterpret_cast( + &_BandwidthUpgradeRetryFrame_default_instance_); + } + static constexpr int kIndexInFileMessages = + 18; + + friend void swap(BandwidthUpgradeRetryFrame& a, BandwidthUpgradeRetryFrame& b) { + a.Swap(&b); + } + inline void Swap(BandwidthUpgradeRetryFrame* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(BandwidthUpgradeRetryFrame* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + BandwidthUpgradeRetryFrame* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage(arena); + } + void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) final; + void CopyFrom(const BandwidthUpgradeRetryFrame& from); + void MergeFrom(const BandwidthUpgradeRetryFrame& from); + PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + bool IsInitialized() const final; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(BandwidthUpgradeRetryFrame* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "location.nearby.connections.BandwidthUpgradeRetryFrame"; + } + protected: + explicit BandwidthUpgradeRetryFrame(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned = false); + private: + static void ArenaDtor(void* object); + inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); + public: + + std::string GetTypeName() const final; + + // nested types ---------------------------------------------------- + + typedef BandwidthUpgradeRetryFrame_Medium Medium; + static constexpr Medium UNKNOWN_MEDIUM = + BandwidthUpgradeRetryFrame_Medium_UNKNOWN_MEDIUM; + static constexpr Medium BLUETOOTH = + BandwidthUpgradeRetryFrame_Medium_BLUETOOTH; + static constexpr Medium WIFI_HOTSPOT = + BandwidthUpgradeRetryFrame_Medium_WIFI_HOTSPOT; + static constexpr Medium BLE = + BandwidthUpgradeRetryFrame_Medium_BLE; + static constexpr Medium WIFI_LAN = + BandwidthUpgradeRetryFrame_Medium_WIFI_LAN; + static constexpr Medium WIFI_AWARE = + BandwidthUpgradeRetryFrame_Medium_WIFI_AWARE; + static constexpr Medium NFC = + BandwidthUpgradeRetryFrame_Medium_NFC; + static constexpr Medium WIFI_DIRECT = + BandwidthUpgradeRetryFrame_Medium_WIFI_DIRECT; + static constexpr Medium WEB_RTC = + BandwidthUpgradeRetryFrame_Medium_WEB_RTC; + static constexpr Medium BLE_L2CAP = + BandwidthUpgradeRetryFrame_Medium_BLE_L2CAP; + static constexpr Medium USB = + BandwidthUpgradeRetryFrame_Medium_USB; + static inline bool Medium_IsValid(int value) { + return BandwidthUpgradeRetryFrame_Medium_IsValid(value); + } + static constexpr Medium Medium_MIN = + BandwidthUpgradeRetryFrame_Medium_Medium_MIN; + static constexpr Medium Medium_MAX = + BandwidthUpgradeRetryFrame_Medium_Medium_MAX; + static constexpr int Medium_ARRAYSIZE = + BandwidthUpgradeRetryFrame_Medium_Medium_ARRAYSIZE; + template + static inline const std::string& Medium_Name(T enum_t_value) { + static_assert(::std::is_same::value || + ::std::is_integral::value, + "Incorrect type passed to function Medium_Name."); + return BandwidthUpgradeRetryFrame_Medium_Name(enum_t_value); + } + static inline bool Medium_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name, + Medium* value) { + return BandwidthUpgradeRetryFrame_Medium_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + enum : int { + kSupportedMediumFieldNumber = 1, + kIsRequestFieldNumber = 2, + }; + // repeated .location.nearby.connections.BandwidthUpgradeRetryFrame.Medium supported_medium = 1; + int supported_medium_size() const; + private: + int _internal_supported_medium_size() const; + public: + void clear_supported_medium(); + private: + ::location::nearby::connections::BandwidthUpgradeRetryFrame_Medium _internal_supported_medium(int index) const; + void _internal_add_supported_medium(::location::nearby::connections::BandwidthUpgradeRetryFrame_Medium value); + ::PROTOBUF_NAMESPACE_ID::RepeatedField* _internal_mutable_supported_medium(); + public: + ::location::nearby::connections::BandwidthUpgradeRetryFrame_Medium supported_medium(int index) const; + void set_supported_medium(int index, ::location::nearby::connections::BandwidthUpgradeRetryFrame_Medium value); + void add_supported_medium(::location::nearby::connections::BandwidthUpgradeRetryFrame_Medium value); + const ::PROTOBUF_NAMESPACE_ID::RepeatedField& supported_medium() const; + ::PROTOBUF_NAMESPACE_ID::RepeatedField* mutable_supported_medium(); + + // optional bool is_request = 2; + bool has_is_request() const; + private: + bool _internal_has_is_request() const; + public: + void clear_is_request(); + bool is_request() const; + void set_is_request(bool value); + private: + bool _internal_is_request() const; + void _internal_set_is_request(bool value); + public: + + // @@protoc_insertion_point(class_scope:location.nearby.connections.BandwidthUpgradeRetryFrame) + private: + class _Internal; + + template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::RepeatedField supported_medium_; + bool is_request_; + friend struct ::TableStruct_connections_2fimplementation_2fproto_2foffline_5fwire_5fformats_2eproto; +}; +// ------------------------------------------------------------------- + class KeepAliveFrame final : public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:location.nearby.connections.KeepAliveFrame) */ { public: @@ -4812,7 +5075,7 @@ class KeepAliveFrame final : &_KeepAliveFrame_default_instance_); } static constexpr int kIndexInFileMessages = - 18; + 19; friend void swap(KeepAliveFrame& a, KeepAliveFrame& b) { a.Swap(&b); @@ -4969,7 +5232,7 @@ class DisconnectionFrame final : &_DisconnectionFrame_default_instance_); } static constexpr int kIndexInFileMessages = - 19; + 20; friend void swap(DisconnectionFrame& a, DisconnectionFrame& b) { a.Swap(&b); @@ -5126,7 +5389,7 @@ class PairedKeyEncryptionFrame final : &_PairedKeyEncryptionFrame_default_instance_); } static constexpr int kIndexInFileMessages = - 20; + 21; friend void swap(PairedKeyEncryptionFrame& a, PairedKeyEncryptionFrame& b) { a.Swap(&b); @@ -5273,7 +5536,7 @@ class AuthenticationMessageFrame final : &_AuthenticationMessageFrame_default_instance_); } static constexpr int kIndexInFileMessages = - 21; + 22; friend void swap(AuthenticationMessageFrame& a, AuthenticationMessageFrame& b) { a.Swap(&b); @@ -5420,7 +5683,7 @@ class AuthenticationResultFrame final : &_AuthenticationResultFrame_default_instance_); } static constexpr int kIndexInFileMessages = - 22; + 23; friend void swap(AuthenticationResultFrame& a, AuthenticationResultFrame& b) { a.Swap(&b); @@ -5562,7 +5825,7 @@ class AutoResumeFrame final : &_AutoResumeFrame_default_instance_); } static constexpr int kIndexInFileMessages = - 23; + 24; friend void swap(AutoResumeFrame& a, AutoResumeFrame& b) { a.Swap(&b); @@ -5762,7 +6025,7 @@ class AutoReconnectFrame final : &_AutoReconnectFrame_default_instance_); } static constexpr int kIndexInFileMessages = - 24; + 25; friend void swap(AutoReconnectFrame& a, AutoReconnectFrame& b) { a.Swap(&b); @@ -5952,7 +6215,7 @@ class MediumMetadata final : &_MediumMetadata_default_instance_); } static constexpr int kIndexInFileMessages = - 25; + 26; friend void swap(MediumMetadata& a, MediumMetadata& b) { a.Swap(&b); @@ -6279,7 +6542,7 @@ class AvailableChannels final : &_AvailableChannels_default_instance_); } static constexpr int kIndexInFileMessages = - 26; + 27; friend void swap(AvailableChannels& a, AvailableChannels& b) { a.Swap(&b); @@ -6430,7 +6693,7 @@ class WifiDirectCliUsableChannels final : &_WifiDirectCliUsableChannels_default_instance_); } static constexpr int kIndexInFileMessages = - 27; + 28; friend void swap(WifiDirectCliUsableChannels& a, WifiDirectCliUsableChannels& b) { a.Swap(&b); @@ -6581,7 +6844,7 @@ class WifiLanUsableChannels final : &_WifiLanUsableChannels_default_instance_); } static constexpr int kIndexInFileMessages = - 28; + 29; friend void swap(WifiLanUsableChannels& a, WifiLanUsableChannels& b) { a.Swap(&b); @@ -6732,7 +6995,7 @@ class WifiAwareUsableChannels final : &_WifiAwareUsableChannels_default_instance_); } static constexpr int kIndexInFileMessages = - 29; + 30; friend void swap(WifiAwareUsableChannels& a, WifiAwareUsableChannels& b) { a.Swap(&b); @@ -6883,7 +7146,7 @@ class WifiHotspotStaUsableChannels final : &_WifiHotspotStaUsableChannels_default_instance_); } static constexpr int kIndexInFileMessages = - 30; + 31; friend void swap(WifiHotspotStaUsableChannels& a, WifiHotspotStaUsableChannels& b) { a.Swap(&b); @@ -7034,7 +7297,7 @@ class LocationHint final : &_LocationHint_default_instance_); } static constexpr int kIndexInFileMessages = - 31; + 32; friend void swap(LocationHint& a, LocationHint& b) { a.Swap(&b); @@ -7196,7 +7459,7 @@ class LocationStandard final : &_LocationStandard_default_instance_); } static constexpr int kIndexInFileMessages = - 32; + 33; friend void swap(LocationStandard& a, LocationStandard& b) { a.Swap(&b); @@ -7348,7 +7611,7 @@ class OsInfo final : &_OsInfo_default_instance_); } static constexpr int kIndexInFileMessages = - 33; + 34; friend void swap(OsInfo& a, OsInfo& b) { a.Swap(&b); @@ -7524,7 +7787,7 @@ class ConnectionsDevice final : &_ConnectionsDevice_default_instance_); } static constexpr int kIndexInFileMessages = - 34; + 35; friend void swap(ConnectionsDevice& a, ConnectionsDevice& b) { a.Swap(&b); @@ -7726,7 +7989,7 @@ class PresenceDevice final : &_PresenceDevice_default_instance_); } static constexpr int kIndexInFileMessages = - 35; + 36; friend void swap(PresenceDevice& a, PresenceDevice& b) { a.Swap(&b); @@ -8172,7 +8435,7 @@ inline void OfflineFrame::set_allocated_v1(::location::nearby::connections::V1Fr // optional .location.nearby.connections.V1Frame.FrameType type = 1; inline bool V1Frame::_internal_has_type() const { - bool value = (_has_bits_[0] & 0x00000800u) != 0; + bool value = (_has_bits_[0] & 0x00001000u) != 0; return value; } inline bool V1Frame::has_type() const { @@ -8180,7 +8443,7 @@ inline bool V1Frame::has_type() const { } inline void V1Frame::clear_type() { type_ = 0; - _has_bits_[0] &= ~0x00000800u; + _has_bits_[0] &= ~0x00001000u; } inline ::location::nearby::connections::V1Frame_FrameType V1Frame::_internal_type() const { return static_cast< ::location::nearby::connections::V1Frame_FrameType >(type_); @@ -8191,7 +8454,7 @@ inline ::location::nearby::connections::V1Frame_FrameType V1Frame::type() const } inline void V1Frame::_internal_set_type(::location::nearby::connections::V1Frame_FrameType value) { assert(::location::nearby::connections::V1Frame_FrameType_IsValid(value)); - _has_bits_[0] |= 0x00000800u; + _has_bits_[0] |= 0x00001000u; type_ = value; } inline void V1Frame::set_type(::location::nearby::connections::V1Frame_FrameType value) { @@ -9189,6 +9452,96 @@ inline void V1Frame::set_allocated_auto_reconnect(::location::nearby::connection // @@protoc_insertion_point(field_set_allocated:location.nearby.connections.V1Frame.auto_reconnect) } +// optional .location.nearby.connections.BandwidthUpgradeRetryFrame bandwidth_upgrade_retry = 13; +inline bool V1Frame::_internal_has_bandwidth_upgrade_retry() const { + bool value = (_has_bits_[0] & 0x00000800u) != 0; + PROTOBUF_ASSUME(!value || bandwidth_upgrade_retry_ != nullptr); + return value; +} +inline bool V1Frame::has_bandwidth_upgrade_retry() const { + return _internal_has_bandwidth_upgrade_retry(); +} +inline void V1Frame::clear_bandwidth_upgrade_retry() { + if (bandwidth_upgrade_retry_ != nullptr) bandwidth_upgrade_retry_->Clear(); + _has_bits_[0] &= ~0x00000800u; +} +inline const ::location::nearby::connections::BandwidthUpgradeRetryFrame& V1Frame::_internal_bandwidth_upgrade_retry() const { + const ::location::nearby::connections::BandwidthUpgradeRetryFrame* p = bandwidth_upgrade_retry_; + return p != nullptr ? *p : reinterpret_cast( + ::location::nearby::connections::_BandwidthUpgradeRetryFrame_default_instance_); +} +inline const ::location::nearby::connections::BandwidthUpgradeRetryFrame& V1Frame::bandwidth_upgrade_retry() const { + // @@protoc_insertion_point(field_get:location.nearby.connections.V1Frame.bandwidth_upgrade_retry) + return _internal_bandwidth_upgrade_retry(); +} +inline void V1Frame::unsafe_arena_set_allocated_bandwidth_upgrade_retry( + ::location::nearby::connections::BandwidthUpgradeRetryFrame* bandwidth_upgrade_retry) { + if (GetArenaForAllocation() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(bandwidth_upgrade_retry_); + } + bandwidth_upgrade_retry_ = bandwidth_upgrade_retry; + if (bandwidth_upgrade_retry) { + _has_bits_[0] |= 0x00000800u; + } else { + _has_bits_[0] &= ~0x00000800u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:location.nearby.connections.V1Frame.bandwidth_upgrade_retry) +} +inline ::location::nearby::connections::BandwidthUpgradeRetryFrame* V1Frame::release_bandwidth_upgrade_retry() { + _has_bits_[0] &= ~0x00000800u; + ::location::nearby::connections::BandwidthUpgradeRetryFrame* temp = bandwidth_upgrade_retry_; + bandwidth_upgrade_retry_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + if (GetArenaForAllocation() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + return temp; +} +inline ::location::nearby::connections::BandwidthUpgradeRetryFrame* V1Frame::unsafe_arena_release_bandwidth_upgrade_retry() { + // @@protoc_insertion_point(field_release:location.nearby.connections.V1Frame.bandwidth_upgrade_retry) + _has_bits_[0] &= ~0x00000800u; + ::location::nearby::connections::BandwidthUpgradeRetryFrame* temp = bandwidth_upgrade_retry_; + bandwidth_upgrade_retry_ = nullptr; + return temp; +} +inline ::location::nearby::connections::BandwidthUpgradeRetryFrame* V1Frame::_internal_mutable_bandwidth_upgrade_retry() { + _has_bits_[0] |= 0x00000800u; + if (bandwidth_upgrade_retry_ == nullptr) { + auto* p = CreateMaybeMessage<::location::nearby::connections::BandwidthUpgradeRetryFrame>(GetArenaForAllocation()); + bandwidth_upgrade_retry_ = p; + } + return bandwidth_upgrade_retry_; +} +inline ::location::nearby::connections::BandwidthUpgradeRetryFrame* V1Frame::mutable_bandwidth_upgrade_retry() { + ::location::nearby::connections::BandwidthUpgradeRetryFrame* _msg = _internal_mutable_bandwidth_upgrade_retry(); + // @@protoc_insertion_point(field_mutable:location.nearby.connections.V1Frame.bandwidth_upgrade_retry) + return _msg; +} +inline void V1Frame::set_allocated_bandwidth_upgrade_retry(::location::nearby::connections::BandwidthUpgradeRetryFrame* bandwidth_upgrade_retry) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); + if (message_arena == nullptr) { + delete bandwidth_upgrade_retry_; + } + if (bandwidth_upgrade_retry) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::location::nearby::connections::BandwidthUpgradeRetryFrame>::GetOwningArena(bandwidth_upgrade_retry); + if (message_arena != submessage_arena) { + bandwidth_upgrade_retry = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, bandwidth_upgrade_retry, submessage_arena); + } + _has_bits_[0] |= 0x00000800u; + } else { + _has_bits_[0] &= ~0x00000800u; + } + bandwidth_upgrade_retry_ = bandwidth_upgrade_retry; + // @@protoc_insertion_point(field_set_allocated:location.nearby.connections.V1Frame.bandwidth_upgrade_retry) +} + // ------------------------------------------------------------------- // ConnectionRequestFrame @@ -13263,6 +13616,83 @@ inline void BandwidthUpgradeNegotiationFrame::set_allocated_client_introduction_ // ------------------------------------------------------------------- +// BandwidthUpgradeRetryFrame + +// repeated .location.nearby.connections.BandwidthUpgradeRetryFrame.Medium supported_medium = 1; +inline int BandwidthUpgradeRetryFrame::_internal_supported_medium_size() const { + return supported_medium_.size(); +} +inline int BandwidthUpgradeRetryFrame::supported_medium_size() const { + return _internal_supported_medium_size(); +} +inline void BandwidthUpgradeRetryFrame::clear_supported_medium() { + supported_medium_.Clear(); +} +inline ::location::nearby::connections::BandwidthUpgradeRetryFrame_Medium BandwidthUpgradeRetryFrame::_internal_supported_medium(int index) const { + return static_cast< ::location::nearby::connections::BandwidthUpgradeRetryFrame_Medium >(supported_medium_.Get(index)); +} +inline ::location::nearby::connections::BandwidthUpgradeRetryFrame_Medium BandwidthUpgradeRetryFrame::supported_medium(int index) const { + // @@protoc_insertion_point(field_get:location.nearby.connections.BandwidthUpgradeRetryFrame.supported_medium) + return _internal_supported_medium(index); +} +inline void BandwidthUpgradeRetryFrame::set_supported_medium(int index, ::location::nearby::connections::BandwidthUpgradeRetryFrame_Medium value) { + assert(::location::nearby::connections::BandwidthUpgradeRetryFrame_Medium_IsValid(value)); + supported_medium_.Set(index, value); + // @@protoc_insertion_point(field_set:location.nearby.connections.BandwidthUpgradeRetryFrame.supported_medium) +} +inline void BandwidthUpgradeRetryFrame::_internal_add_supported_medium(::location::nearby::connections::BandwidthUpgradeRetryFrame_Medium value) { + assert(::location::nearby::connections::BandwidthUpgradeRetryFrame_Medium_IsValid(value)); + supported_medium_.Add(value); +} +inline void BandwidthUpgradeRetryFrame::add_supported_medium(::location::nearby::connections::BandwidthUpgradeRetryFrame_Medium value) { + _internal_add_supported_medium(value); + // @@protoc_insertion_point(field_add:location.nearby.connections.BandwidthUpgradeRetryFrame.supported_medium) +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField& +BandwidthUpgradeRetryFrame::supported_medium() const { + // @@protoc_insertion_point(field_list:location.nearby.connections.BandwidthUpgradeRetryFrame.supported_medium) + return supported_medium_; +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedField* +BandwidthUpgradeRetryFrame::_internal_mutable_supported_medium() { + return &supported_medium_; +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedField* +BandwidthUpgradeRetryFrame::mutable_supported_medium() { + // @@protoc_insertion_point(field_mutable_list:location.nearby.connections.BandwidthUpgradeRetryFrame.supported_medium) + return _internal_mutable_supported_medium(); +} + +// optional bool is_request = 2; +inline bool BandwidthUpgradeRetryFrame::_internal_has_is_request() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool BandwidthUpgradeRetryFrame::has_is_request() const { + return _internal_has_is_request(); +} +inline void BandwidthUpgradeRetryFrame::clear_is_request() { + is_request_ = false; + _has_bits_[0] &= ~0x00000001u; +} +inline bool BandwidthUpgradeRetryFrame::_internal_is_request() const { + return is_request_; +} +inline bool BandwidthUpgradeRetryFrame::is_request() const { + // @@protoc_insertion_point(field_get:location.nearby.connections.BandwidthUpgradeRetryFrame.is_request) + return _internal_is_request(); +} +inline void BandwidthUpgradeRetryFrame::_internal_set_is_request(bool value) { + _has_bits_[0] |= 0x00000001u; + is_request_ = value; +} +inline void BandwidthUpgradeRetryFrame::set_is_request(bool value) { + _internal_set_is_request(value); + // @@protoc_insertion_point(field_set:location.nearby.connections.BandwidthUpgradeRetryFrame.is_request) +} + +// ------------------------------------------------------------------- + // KeepAliveFrame // optional bool ack = 1; @@ -15666,6 +16096,8 @@ PresenceDevice::mutable_identity_type() { // ------------------------------------------------------------------- +// ------------------------------------------------------------------- + // @@protoc_insertion_point(namespace_scope) @@ -15685,6 +16117,7 @@ template <> struct is_proto_enum< ::location::nearby::connections::PayloadTransf template <> struct is_proto_enum< ::location::nearby::connections::PayloadTransferFrame_PacketType> : ::std::true_type {}; template <> struct is_proto_enum< ::location::nearby::connections::BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium> : ::std::true_type {}; template <> struct is_proto_enum< ::location::nearby::connections::BandwidthUpgradeNegotiationFrame_EventType> : ::std::true_type {}; +template <> struct is_proto_enum< ::location::nearby::connections::BandwidthUpgradeRetryFrame_Medium> : ::std::true_type {}; template <> struct is_proto_enum< ::location::nearby::connections::AutoResumeFrame_EventType> : ::std::true_type {}; template <> struct is_proto_enum< ::location::nearby::connections::AutoReconnectFrame_EventType> : ::std::true_type {}; template <> struct is_proto_enum< ::location::nearby::connections::LocationStandard_Format> : ::std::true_type {}; diff --git a/compiled_proto/internal/proto/analytics/connections_log.pb.cc b/compiled_proto/internal/proto/analytics/connections_log.pb.cc index 82410f52..2167e5a6 100644 --- a/compiled_proto/internal/proto/analytics/connections_log.pb.cc +++ b/compiled_proto/internal/proto/analytics/connections_log.pb.cc @@ -20,7 +20,9 @@ namespace proto { constexpr ConnectionsLog_ClientSession::ConnectionsLog_ClientSession( ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) : strategy_session_() - , duration_millis_(int64_t{0}){} + , connection_token_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , duration_millis_(int64_t{0}) + , client_flow_id_(int64_t{0}){} struct ConnectionsLog_ClientSessionDefaultTypeInternal { constexpr ConnectionsLog_ClientSessionDefaultTypeInternal() : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} @@ -209,7 +211,8 @@ constexpr ConnectionsLog_Payload::ConnectionsLog_Payload( , num_chunks_(0) , num_bytes_transferred_(int64_t{0}) , status_(0) -{} + + , num_successful_auto_resume_(0){} struct ConnectionsLog_PayloadDefaultTypeInternal { constexpr ConnectionsLog_PayloadDefaultTypeInternal() : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} @@ -272,6 +275,7 @@ constexpr ConnectionsLog_AdvertisingMetadata::ConnectionsLog_AdvertisingMetadata , supports_extended_ble_advertisements_(false) , supports_nfc_technology_(false) , multiple_advertisement_supported_(false) + , supports_dual_band_(false) , power_level_(-1) {} struct ConnectionsLog_AdvertisingMetadataDefaultTypeInternal { @@ -424,6 +428,12 @@ class ConnectionsLog_ClientSession::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); static void set_has_duration_millis(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } + static void set_has_client_flow_id(HasBits* has_bits) { + (*has_bits)[0] |= 4u; + } + static void set_has_connection_token(HasBits* has_bits) { (*has_bits)[0] |= 1u; } }; @@ -443,12 +453,29 @@ ConnectionsLog_ClientSession::ConnectionsLog_ClientSession(const ConnectionsLog_ _has_bits_(from._has_bits_), strategy_session_(from.strategy_session_) { _internal_metadata_.MergeFrom(from._internal_metadata_); - duration_millis_ = from.duration_millis_; + connection_token_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + connection_token_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_connection_token()) { + connection_token_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_connection_token(), + GetArenaForAllocation()); + } + ::memcpy(&duration_millis_, &from.duration_millis_, + static_cast(reinterpret_cast(&client_flow_id_) - + reinterpret_cast(&duration_millis_)) + sizeof(client_flow_id_)); // @@protoc_insertion_point(copy_constructor:location.nearby.analytics.proto.ConnectionsLog.ClientSession) } inline void ConnectionsLog_ClientSession::SharedCtor() { -duration_millis_ = int64_t{0}; +connection_token_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + connection_token_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&duration_millis_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&client_flow_id_) - + reinterpret_cast(&duration_millis_)) + sizeof(client_flow_id_)); } ConnectionsLog_ClientSession::~ConnectionsLog_ClientSession() { @@ -460,6 +487,7 @@ ConnectionsLog_ClientSession::~ConnectionsLog_ClientSession() { inline void ConnectionsLog_ClientSession::SharedDtor() { GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + connection_token_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); } void ConnectionsLog_ClientSession::ArenaDtor(void* object) { @@ -479,7 +507,15 @@ void ConnectionsLog_ClientSession::Clear() { (void) cached_has_bits; strategy_session_.Clear(); - duration_millis_ = int64_t{0}; + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000001u) { + connection_token_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000006u) { + ::memset(&duration_millis_, 0, static_cast( + reinterpret_cast(&client_flow_id_) - + reinterpret_cast(&duration_millis_)) + sizeof(client_flow_id_)); + } _has_bits_.Clear(); _internal_metadata_.Clear(); } @@ -513,6 +549,24 @@ const char* ConnectionsLog_ClientSession::_InternalParse(const char* ptr, ::PROT } else goto handle_unusual; continue; + // optional int64 client_flow_id = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 24)) { + _Internal::set_has_client_flow_id(&has_bits); + client_flow_id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional string connection_token = 4; + case 4: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 34)) { + auto str = _internal_mutable_connection_token(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); + } else + goto handle_unusual; + continue; default: goto handle_unusual; } // switch @@ -545,7 +599,7 @@ uint8_t* ConnectionsLog_ClientSession::_InternalSerialize( cached_has_bits = _has_bits_[0]; // optional int64 duration_millis = 1; - if (cached_has_bits & 0x00000001u) { + if (cached_has_bits & 0x00000002u) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64ToArray(1, this->_internal_duration_millis(), target); } @@ -558,6 +612,18 @@ uint8_t* ConnectionsLog_ClientSession::_InternalSerialize( InternalWriteMessage(2, this->_internal_strategy_session(i), target, stream); } + // optional int64 client_flow_id = 3; + if (cached_has_bits & 0x00000004u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64ToArray(3, this->_internal_client_flow_id(), target); + } + + // optional string connection_token = 4; + if (cached_has_bits & 0x00000001u) { + target = stream->WriteStringMaybeAliased( + 4, this->_internal_connection_token(), target); + } + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = stream->WriteRaw(_internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).data(), static_cast(_internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size()), target); @@ -581,12 +647,26 @@ size_t ConnectionsLog_ClientSession::ByteSizeLong() const { ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); } - // optional int64 duration_millis = 1; cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000001u) { - total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64SizePlusOne(this->_internal_duration_millis()); - } + if (cached_has_bits & 0x00000007u) { + // optional string connection_token = 4; + if (cached_has_bits & 0x00000001u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_connection_token()); + } + // optional int64 duration_millis = 1; + if (cached_has_bits & 0x00000002u) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64SizePlusOne(this->_internal_duration_millis()); + } + + // optional int64 client_flow_id = 3; + if (cached_has_bits & 0x00000004u) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64SizePlusOne(this->_internal_client_flow_id()); + } + + } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { total_size += _internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size(); } @@ -608,8 +688,18 @@ void ConnectionsLog_ClientSession::MergeFrom(const ConnectionsLog_ClientSession& (void) cached_has_bits; strategy_session_.MergeFrom(from.strategy_session_); - if (from._internal_has_duration_millis()) { - _internal_set_duration_millis(from._internal_duration_millis()); + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 0x00000007u) { + if (cached_has_bits & 0x00000001u) { + _internal_set_connection_token(from._internal_connection_token()); + } + if (cached_has_bits & 0x00000002u) { + duration_millis_ = from.duration_millis_; + } + if (cached_has_bits & 0x00000004u) { + client_flow_id_ = from.client_flow_id_; + } + _has_bits_[0] |= cached_has_bits; } _internal_metadata_.MergeFrom(from._internal_metadata_); } @@ -627,10 +717,22 @@ bool ConnectionsLog_ClientSession::IsInitialized() const { void ConnectionsLog_ClientSession::InternalSwap(ConnectionsLog_ClientSession* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); strategy_session_.InternalSwap(&other->strategy_session_); - swap(duration_millis_, other->duration_millis_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &connection_token_, lhs_arena, + &other->connection_token_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(ConnectionsLog_ClientSession, client_flow_id_) + + sizeof(ConnectionsLog_ClientSession::client_flow_id_) + - PROTOBUF_FIELD_OFFSET(ConnectionsLog_ClientSession, duration_millis_)>( + reinterpret_cast(&duration_millis_), + reinterpret_cast(&other->duration_millis_)); } std::string ConnectionsLog_ClientSession::GetTypeName() const { @@ -4181,6 +4283,9 @@ class ConnectionsLog_Payload::_Internal { static void set_has_status(HasBits* has_bits) { (*has_bits)[0] |= 32u; } + static void set_has_num_successful_auto_resume(HasBits* has_bits) { + (*has_bits)[0] |= 64u; + } }; ConnectionsLog_Payload::ConnectionsLog_Payload(::PROTOBUF_NAMESPACE_ID::Arena* arena, @@ -4197,16 +4302,16 @@ ConnectionsLog_Payload::ConnectionsLog_Payload(const ConnectionsLog_Payload& fro _has_bits_(from._has_bits_) { _internal_metadata_.MergeFrom(from._internal_metadata_); ::memcpy(&duration_millis_, &from.duration_millis_, - static_cast(reinterpret_cast(&status_) - - reinterpret_cast(&duration_millis_)) + sizeof(status_)); + static_cast(reinterpret_cast(&num_successful_auto_resume_) - + reinterpret_cast(&duration_millis_)) + sizeof(num_successful_auto_resume_)); // @@protoc_insertion_point(copy_constructor:location.nearby.analytics.proto.ConnectionsLog.Payload) } inline void ConnectionsLog_Payload::SharedCtor() { ::memset(reinterpret_cast(this) + static_cast( reinterpret_cast(&duration_millis_) - reinterpret_cast(this)), - 0, static_cast(reinterpret_cast(&status_) - - reinterpret_cast(&duration_millis_)) + sizeof(status_)); + 0, static_cast(reinterpret_cast(&num_successful_auto_resume_) - + reinterpret_cast(&duration_millis_)) + sizeof(num_successful_auto_resume_)); } ConnectionsLog_Payload::~ConnectionsLog_Payload() { @@ -4237,10 +4342,10 @@ void ConnectionsLog_Payload::Clear() { (void) cached_has_bits; cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000003fu) { + if (cached_has_bits & 0x0000007fu) { ::memset(&duration_millis_, 0, static_cast( - reinterpret_cast(&status_) - - reinterpret_cast(&duration_millis_)) + sizeof(status_)); + reinterpret_cast(&num_successful_auto_resume_) - + reinterpret_cast(&duration_millis_)) + sizeof(num_successful_auto_resume_)); } _has_bits_.Clear(); _internal_metadata_.Clear(); @@ -4315,6 +4420,15 @@ const char* ConnectionsLog_Payload::_InternalParse(const char* ptr, ::PROTOBUF_N } else goto handle_unusual; continue; + // optional int32 num_successful_auto_resume = 7; + case 7: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 56)) { + _Internal::set_has_num_successful_auto_resume(&has_bits); + num_successful_auto_resume_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; default: goto handle_unusual; } // switch @@ -4384,6 +4498,12 @@ uint8_t* ConnectionsLog_Payload::_InternalSerialize( 6, this->_internal_status(), target); } + // optional int32 num_successful_auto_resume = 7; + if (cached_has_bits & 0x00000040u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(7, this->_internal_num_successful_auto_resume(), target); + } + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = stream->WriteRaw(_internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).data(), static_cast(_internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size()), target); @@ -4401,7 +4521,7 @@ size_t ConnectionsLog_Payload::ByteSizeLong() const { (void) cached_has_bits; cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000003fu) { + if (cached_has_bits & 0x0000007fu) { // optional int64 duration_millis = 1; if (cached_has_bits & 0x00000001u) { total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64SizePlusOne(this->_internal_duration_millis()); @@ -4434,6 +4554,11 @@ size_t ConnectionsLog_Payload::ByteSizeLong() const { ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_status()); } + // optional int32 num_successful_auto_resume = 7; + if (cached_has_bits & 0x00000040u) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_num_successful_auto_resume()); + } + } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { total_size += _internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size(); @@ -4456,7 +4581,7 @@ void ConnectionsLog_Payload::MergeFrom(const ConnectionsLog_Payload& from) { (void) cached_has_bits; cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x0000003fu) { + if (cached_has_bits & 0x0000007fu) { if (cached_has_bits & 0x00000001u) { duration_millis_ = from.duration_millis_; } @@ -4475,6 +4600,9 @@ void ConnectionsLog_Payload::MergeFrom(const ConnectionsLog_Payload& from) { if (cached_has_bits & 0x00000020u) { status_ = from.status_; } + if (cached_has_bits & 0x00000040u) { + num_successful_auto_resume_ = from.num_successful_auto_resume_; + } _has_bits_[0] |= cached_has_bits; } _internal_metadata_.MergeFrom(from._internal_metadata_); @@ -4496,8 +4624,8 @@ void ConnectionsLog_Payload::InternalSwap(ConnectionsLog_Payload* other) { _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); ::PROTOBUF_NAMESPACE_ID::internal::memswap< - PROTOBUF_FIELD_OFFSET(ConnectionsLog_Payload, status_) - + sizeof(ConnectionsLog_Payload::status_) + PROTOBUF_FIELD_OFFSET(ConnectionsLog_Payload, num_successful_auto_resume_) + + sizeof(ConnectionsLog_Payload::num_successful_auto_resume_) - PROTOBUF_FIELD_OFFSET(ConnectionsLog_Payload, duration_millis_)>( reinterpret_cast(&duration_millis_), reinterpret_cast(&other->duration_millis_)); @@ -5967,6 +6095,9 @@ class ConnectionsLog_AdvertisingMetadata::_Internal { (*has_bits)[0] |= 8u; } static void set_has_power_level(HasBits* has_bits) { + (*has_bits)[0] |= 32u; + } + static void set_has_supports_dual_band(HasBits* has_bits) { (*has_bits)[0] |= 16u; } }; @@ -5993,8 +6124,8 @@ ConnectionsLog_AdvertisingMetadata::ConnectionsLog_AdvertisingMetadata(const Con inline void ConnectionsLog_AdvertisingMetadata::SharedCtor() { ::memset(reinterpret_cast(this) + static_cast( reinterpret_cast(&connected_ap_frequency_) - reinterpret_cast(this)), - 0, static_cast(reinterpret_cast(&multiple_advertisement_supported_) - - reinterpret_cast(&connected_ap_frequency_)) + sizeof(multiple_advertisement_supported_)); + 0, static_cast(reinterpret_cast(&supports_dual_band_) - + reinterpret_cast(&connected_ap_frequency_)) + sizeof(supports_dual_band_)); power_level_ = -1; } @@ -6026,10 +6157,10 @@ void ConnectionsLog_AdvertisingMetadata::Clear() { (void) cached_has_bits; cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { + if (cached_has_bits & 0x0000003fu) { ::memset(&connected_ap_frequency_, 0, static_cast( - reinterpret_cast(&multiple_advertisement_supported_) - - reinterpret_cast(&connected_ap_frequency_)) + sizeof(multiple_advertisement_supported_)); + reinterpret_cast(&supports_dual_band_) - + reinterpret_cast(&connected_ap_frequency_)) + sizeof(supports_dual_band_)); power_level_ = -1; } _has_bits_.Clear(); @@ -6092,6 +6223,15 @@ const char* ConnectionsLog_AdvertisingMetadata::_InternalParse(const char* ptr, } else goto handle_unusual; continue; + // optional bool supports_dual_band = 6; + case 6: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 48)) { + _Internal::set_has_supports_dual_band(&has_bits); + supports_dual_band_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; default: goto handle_unusual; } // switch @@ -6148,12 +6288,18 @@ uint8_t* ConnectionsLog_AdvertisingMetadata::_InternalSerialize( } // optional .location.nearby.proto.connections.PowerLevel power_level = 5; - if (cached_has_bits & 0x00000010u) { + if (cached_has_bits & 0x00000020u) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( 5, this->_internal_power_level(), target); } + // optional bool supports_dual_band = 6; + if (cached_has_bits & 0x00000010u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(6, this->_internal_supports_dual_band(), target); + } + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = stream->WriteRaw(_internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).data(), static_cast(_internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size()), target); @@ -6171,7 +6317,7 @@ size_t ConnectionsLog_AdvertisingMetadata::ByteSizeLong() const { (void) cached_has_bits; cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { + if (cached_has_bits & 0x0000003fu) { // optional int32 connected_ap_frequency = 2; if (cached_has_bits & 0x00000001u) { total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_connected_ap_frequency()); @@ -6192,8 +6338,13 @@ size_t ConnectionsLog_AdvertisingMetadata::ByteSizeLong() const { total_size += 1 + 1; } - // optional .location.nearby.proto.connections.PowerLevel power_level = 5; + // optional bool supports_dual_band = 6; if (cached_has_bits & 0x00000010u) { + total_size += 1 + 1; + } + + // optional .location.nearby.proto.connections.PowerLevel power_level = 5; + if (cached_has_bits & 0x00000020u) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_power_level()); } @@ -6220,7 +6371,7 @@ void ConnectionsLog_AdvertisingMetadata::MergeFrom(const ConnectionsLog_Advertis (void) cached_has_bits; cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { + if (cached_has_bits & 0x0000003fu) { if (cached_has_bits & 0x00000001u) { connected_ap_frequency_ = from.connected_ap_frequency_; } @@ -6234,6 +6385,9 @@ void ConnectionsLog_AdvertisingMetadata::MergeFrom(const ConnectionsLog_Advertis multiple_advertisement_supported_ = from.multiple_advertisement_supported_; } if (cached_has_bits & 0x00000010u) { + supports_dual_band_ = from.supports_dual_band_; + } + if (cached_has_bits & 0x00000020u) { power_level_ = from.power_level_; } _has_bits_[0] |= cached_has_bits; @@ -6257,8 +6411,8 @@ void ConnectionsLog_AdvertisingMetadata::InternalSwap(ConnectionsLog_Advertising _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); ::PROTOBUF_NAMESPACE_ID::internal::memswap< - PROTOBUF_FIELD_OFFSET(ConnectionsLog_AdvertisingMetadata, multiple_advertisement_supported_) - + sizeof(ConnectionsLog_AdvertisingMetadata::multiple_advertisement_supported_) + PROTOBUF_FIELD_OFFSET(ConnectionsLog_AdvertisingMetadata, supports_dual_band_) + + sizeof(ConnectionsLog_AdvertisingMetadata::supports_dual_band_) - PROTOBUF_FIELD_OFFSET(ConnectionsLog_AdvertisingMetadata, connected_ap_frequency_)>( reinterpret_cast(&connected_ap_frequency_), reinterpret_cast(&other->connected_ap_frequency_)); diff --git a/compiled_proto/internal/proto/analytics/connections_log.pb.h b/compiled_proto/internal/proto/analytics/connections_log.pb.h index c90e49b3..071f3dc3 100644 --- a/compiled_proto/internal/proto/analytics/connections_log.pb.h +++ b/compiled_proto/internal/proto/analytics/connections_log.pb.h @@ -272,7 +272,9 @@ class ConnectionsLog_ClientSession final : enum : int { kStrategySessionFieldNumber = 2, + kConnectionTokenFieldNumber = 4, kDurationMillisFieldNumber = 1, + kClientFlowIdFieldNumber = 3, }; // repeated .location.nearby.analytics.proto.ConnectionsLog.StrategySession strategy_session = 2; int strategy_session_size() const; @@ -292,6 +294,24 @@ class ConnectionsLog_ClientSession final : const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::location::nearby::analytics::proto::ConnectionsLog_StrategySession >& strategy_session() const; + // optional string connection_token = 4; + bool has_connection_token() const; + private: + bool _internal_has_connection_token() const; + public: + void clear_connection_token(); + const std::string& connection_token() const; + template + void set_connection_token(ArgT0&& arg0, ArgT... args); + std::string* mutable_connection_token(); + PROTOBUF_NODISCARD std::string* release_connection_token(); + void set_allocated_connection_token(std::string* connection_token); + private: + const std::string& _internal_connection_token() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_connection_token(const std::string& value); + std::string* _internal_mutable_connection_token(); + public: + // optional int64 duration_millis = 1; bool has_duration_millis() const; private: @@ -305,6 +325,19 @@ class ConnectionsLog_ClientSession final : void _internal_set_duration_millis(int64_t value); public: + // optional int64 client_flow_id = 3; + bool has_client_flow_id() const; + private: + bool _internal_has_client_flow_id() const; + public: + void clear_client_flow_id(); + int64_t client_flow_id() const; + void set_client_flow_id(int64_t value); + private: + int64_t _internal_client_flow_id() const; + void _internal_set_client_flow_id(int64_t value); + public: + // @@protoc_insertion_point(class_scope:location.nearby.analytics.proto.ConnectionsLog.ClientSession) private: class _Internal; @@ -315,7 +348,9 @@ class ConnectionsLog_ClientSession final : ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::location::nearby::analytics::proto::ConnectionsLog_StrategySession > strategy_session_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr connection_token_; int64_t duration_millis_; + int64_t client_flow_id_; friend struct ::TableStruct_internal_2fproto_2fanalytics_2fconnections_5flog_2eproto; }; // ------------------------------------------------------------------- @@ -2597,6 +2632,7 @@ class ConnectionsLog_Payload final : kNumChunksFieldNumber = 5, kNumBytesTransferredFieldNumber = 4, kStatusFieldNumber = 6, + kNumSuccessfulAutoResumeFieldNumber = 7, }; // optional int64 duration_millis = 1; bool has_duration_millis() const; @@ -2676,6 +2712,19 @@ class ConnectionsLog_Payload final : void _internal_set_status(::location::nearby::proto::connections::PayloadStatus value); public: + // optional int32 num_successful_auto_resume = 7; + bool has_num_successful_auto_resume() const; + private: + bool _internal_has_num_successful_auto_resume() const; + public: + void clear_num_successful_auto_resume(); + int32_t num_successful_auto_resume() const; + void set_num_successful_auto_resume(int32_t value); + private: + int32_t _internal_num_successful_auto_resume() const; + void _internal_set_num_successful_auto_resume(int32_t value); + public: + // @@protoc_insertion_point(class_scope:location.nearby.analytics.proto.ConnectionsLog.Payload) private: class _Internal; @@ -2691,6 +2740,7 @@ class ConnectionsLog_Payload final : int32_t num_chunks_; int64_t num_bytes_transferred_; int status_; + int32_t num_successful_auto_resume_; friend struct ::TableStruct_internal_2fproto_2fanalytics_2fconnections_5flog_2eproto; }; // ------------------------------------------------------------------- @@ -3559,6 +3609,7 @@ class ConnectionsLog_AdvertisingMetadata final : kSupportsExtendedBleAdvertisementsFieldNumber = 1, kSupportsNfcTechnologyFieldNumber = 3, kMultipleAdvertisementSupportedFieldNumber = 4, + kSupportsDualBandFieldNumber = 6, kPowerLevelFieldNumber = 5, }; // optional int32 connected_ap_frequency = 2; @@ -3613,6 +3664,19 @@ class ConnectionsLog_AdvertisingMetadata final : void _internal_set_multiple_advertisement_supported(bool value); public: + // optional bool supports_dual_band = 6; + bool has_supports_dual_band() const; + private: + bool _internal_has_supports_dual_band() const; + public: + void clear_supports_dual_band(); + bool supports_dual_band() const; + void set_supports_dual_band(bool value); + private: + bool _internal_supports_dual_band() const; + void _internal_set_supports_dual_band(bool value); + public: + // optional .location.nearby.proto.connections.PowerLevel power_level = 5; bool has_power_level() const; private: @@ -3639,6 +3703,7 @@ class ConnectionsLog_AdvertisingMetadata final : bool supports_extended_ble_advertisements_; bool supports_nfc_technology_; bool multiple_advertisement_supported_; + bool supports_dual_band_; int power_level_; friend struct ::TableStruct_internal_2fproto_2fanalytics_2fconnections_5flog_2eproto; }; @@ -4458,7 +4523,7 @@ class ConnectionsLog final : // optional int64 duration_millis = 1; inline bool ConnectionsLog_ClientSession::_internal_has_duration_millis() const { - bool value = (_has_bits_[0] & 0x00000001u) != 0; + bool value = (_has_bits_[0] & 0x00000002u) != 0; return value; } inline bool ConnectionsLog_ClientSession::has_duration_millis() const { @@ -4466,7 +4531,7 @@ inline bool ConnectionsLog_ClientSession::has_duration_millis() const { } inline void ConnectionsLog_ClientSession::clear_duration_millis() { duration_millis_ = int64_t{0}; - _has_bits_[0] &= ~0x00000001u; + _has_bits_[0] &= ~0x00000002u; } inline int64_t ConnectionsLog_ClientSession::_internal_duration_millis() const { return duration_millis_; @@ -4476,7 +4541,7 @@ inline int64_t ConnectionsLog_ClientSession::duration_millis() const { return _internal_duration_millis(); } inline void ConnectionsLog_ClientSession::_internal_set_duration_millis(int64_t value) { - _has_bits_[0] |= 0x00000001u; + _has_bits_[0] |= 0x00000002u; duration_millis_ = value; } inline void ConnectionsLog_ClientSession::set_duration_millis(int64_t value) { @@ -4524,6 +4589,103 @@ ConnectionsLog_ClientSession::strategy_session() const { return strategy_session_; } +// optional int64 client_flow_id = 3; +inline bool ConnectionsLog_ClientSession::_internal_has_client_flow_id() const { + bool value = (_has_bits_[0] & 0x00000004u) != 0; + return value; +} +inline bool ConnectionsLog_ClientSession::has_client_flow_id() const { + return _internal_has_client_flow_id(); +} +inline void ConnectionsLog_ClientSession::clear_client_flow_id() { + client_flow_id_ = int64_t{0}; + _has_bits_[0] &= ~0x00000004u; +} +inline int64_t ConnectionsLog_ClientSession::_internal_client_flow_id() const { + return client_flow_id_; +} +inline int64_t ConnectionsLog_ClientSession::client_flow_id() const { + // @@protoc_insertion_point(field_get:location.nearby.analytics.proto.ConnectionsLog.ClientSession.client_flow_id) + return _internal_client_flow_id(); +} +inline void ConnectionsLog_ClientSession::_internal_set_client_flow_id(int64_t value) { + _has_bits_[0] |= 0x00000004u; + client_flow_id_ = value; +} +inline void ConnectionsLog_ClientSession::set_client_flow_id(int64_t value) { + _internal_set_client_flow_id(value); + // @@protoc_insertion_point(field_set:location.nearby.analytics.proto.ConnectionsLog.ClientSession.client_flow_id) +} + +// optional string connection_token = 4; +inline bool ConnectionsLog_ClientSession::_internal_has_connection_token() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool ConnectionsLog_ClientSession::has_connection_token() const { + return _internal_has_connection_token(); +} +inline void ConnectionsLog_ClientSession::clear_connection_token() { + connection_token_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000001u; +} +inline const std::string& ConnectionsLog_ClientSession::connection_token() const { + // @@protoc_insertion_point(field_get:location.nearby.analytics.proto.ConnectionsLog.ClientSession.connection_token) + return _internal_connection_token(); +} +template +inline PROTOBUF_ALWAYS_INLINE +void ConnectionsLog_ClientSession::set_connection_token(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000001u; + connection_token_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:location.nearby.analytics.proto.ConnectionsLog.ClientSession.connection_token) +} +inline std::string* ConnectionsLog_ClientSession::mutable_connection_token() { + std::string* _s = _internal_mutable_connection_token(); + // @@protoc_insertion_point(field_mutable:location.nearby.analytics.proto.ConnectionsLog.ClientSession.connection_token) + return _s; +} +inline const std::string& ConnectionsLog_ClientSession::_internal_connection_token() const { + return connection_token_.Get(); +} +inline void ConnectionsLog_ClientSession::_internal_set_connection_token(const std::string& value) { + _has_bits_[0] |= 0x00000001u; + connection_token_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline std::string* ConnectionsLog_ClientSession::_internal_mutable_connection_token() { + _has_bits_[0] |= 0x00000001u; + return connection_token_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline std::string* ConnectionsLog_ClientSession::release_connection_token() { + // @@protoc_insertion_point(field_release:location.nearby.analytics.proto.ConnectionsLog.ClientSession.connection_token) + if (!_internal_has_connection_token()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000001u; + auto* p = connection_token_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (connection_token_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + connection_token_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void ConnectionsLog_ClientSession::set_allocated_connection_token(std::string* connection_token) { + if (connection_token != nullptr) { + _has_bits_[0] |= 0x00000001u; + } else { + _has_bits_[0] &= ~0x00000001u; + } + connection_token_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), connection_token, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (connection_token_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + connection_token_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:location.nearby.analytics.proto.ConnectionsLog.ClientSession.connection_token) +} + // ------------------------------------------------------------------- // ConnectionsLog_StrategySession @@ -6902,6 +7064,34 @@ inline void ConnectionsLog_Payload::set_status(::location::nearby::proto::connec // @@protoc_insertion_point(field_set:location.nearby.analytics.proto.ConnectionsLog.Payload.status) } +// optional int32 num_successful_auto_resume = 7; +inline bool ConnectionsLog_Payload::_internal_has_num_successful_auto_resume() const { + bool value = (_has_bits_[0] & 0x00000040u) != 0; + return value; +} +inline bool ConnectionsLog_Payload::has_num_successful_auto_resume() const { + return _internal_has_num_successful_auto_resume(); +} +inline void ConnectionsLog_Payload::clear_num_successful_auto_resume() { + num_successful_auto_resume_ = 0; + _has_bits_[0] &= ~0x00000040u; +} +inline int32_t ConnectionsLog_Payload::_internal_num_successful_auto_resume() const { + return num_successful_auto_resume_; +} +inline int32_t ConnectionsLog_Payload::num_successful_auto_resume() const { + // @@protoc_insertion_point(field_get:location.nearby.analytics.proto.ConnectionsLog.Payload.num_successful_auto_resume) + return _internal_num_successful_auto_resume(); +} +inline void ConnectionsLog_Payload::_internal_set_num_successful_auto_resume(int32_t value) { + _has_bits_[0] |= 0x00000040u; + num_successful_auto_resume_ = value; +} +inline void ConnectionsLog_Payload::set_num_successful_auto_resume(int32_t value) { + _internal_set_num_successful_auto_resume(value); + // @@protoc_insertion_point(field_set:location.nearby.analytics.proto.ConnectionsLog.Payload.num_successful_auto_resume) +} + // ------------------------------------------------------------------- // ConnectionsLog_BandwidthUpgradeAttempt @@ -8135,7 +8325,7 @@ inline void ConnectionsLog_AdvertisingMetadata::set_multiple_advertisement_suppo // optional .location.nearby.proto.connections.PowerLevel power_level = 5; inline bool ConnectionsLog_AdvertisingMetadata::_internal_has_power_level() const { - bool value = (_has_bits_[0] & 0x00000010u) != 0; + bool value = (_has_bits_[0] & 0x00000020u) != 0; return value; } inline bool ConnectionsLog_AdvertisingMetadata::has_power_level() const { @@ -8143,7 +8333,7 @@ inline bool ConnectionsLog_AdvertisingMetadata::has_power_level() const { } inline void ConnectionsLog_AdvertisingMetadata::clear_power_level() { power_level_ = -1; - _has_bits_[0] &= ~0x00000010u; + _has_bits_[0] &= ~0x00000020u; } inline ::location::nearby::proto::connections::PowerLevel ConnectionsLog_AdvertisingMetadata::_internal_power_level() const { return static_cast< ::location::nearby::proto::connections::PowerLevel >(power_level_); @@ -8154,7 +8344,7 @@ inline ::location::nearby::proto::connections::PowerLevel ConnectionsLog_Adverti } inline void ConnectionsLog_AdvertisingMetadata::_internal_set_power_level(::location::nearby::proto::connections::PowerLevel value) { assert(::location::nearby::proto::connections::PowerLevel_IsValid(value)); - _has_bits_[0] |= 0x00000010u; + _has_bits_[0] |= 0x00000020u; power_level_ = value; } inline void ConnectionsLog_AdvertisingMetadata::set_power_level(::location::nearby::proto::connections::PowerLevel value) { @@ -8162,6 +8352,34 @@ inline void ConnectionsLog_AdvertisingMetadata::set_power_level(::location::near // @@protoc_insertion_point(field_set:location.nearby.analytics.proto.ConnectionsLog.AdvertisingMetadata.power_level) } +// optional bool supports_dual_band = 6; +inline bool ConnectionsLog_AdvertisingMetadata::_internal_has_supports_dual_band() const { + bool value = (_has_bits_[0] & 0x00000010u) != 0; + return value; +} +inline bool ConnectionsLog_AdvertisingMetadata::has_supports_dual_band() const { + return _internal_has_supports_dual_band(); +} +inline void ConnectionsLog_AdvertisingMetadata::clear_supports_dual_band() { + supports_dual_band_ = false; + _has_bits_[0] &= ~0x00000010u; +} +inline bool ConnectionsLog_AdvertisingMetadata::_internal_supports_dual_band() const { + return supports_dual_band_; +} +inline bool ConnectionsLog_AdvertisingMetadata::supports_dual_band() const { + // @@protoc_insertion_point(field_get:location.nearby.analytics.proto.ConnectionsLog.AdvertisingMetadata.supports_dual_band) + return _internal_supports_dual_band(); +} +inline void ConnectionsLog_AdvertisingMetadata::_internal_set_supports_dual_band(bool value) { + _has_bits_[0] |= 0x00000010u; + supports_dual_band_ = value; +} +inline void ConnectionsLog_AdvertisingMetadata::set_supports_dual_band(bool value) { + _internal_set_supports_dual_band(value); + // @@protoc_insertion_point(field_set:location.nearby.analytics.proto.ConnectionsLog.AdvertisingMetadata.supports_dual_band) +} + // ------------------------------------------------------------------- // ConnectionsLog_DiscoveryMetadata diff --git a/compiled_proto/proto/connections_enums.pb.cc b/compiled_proto/proto/connections_enums.pb.cc index 76d86f05..5796844a 100644 --- a/compiled_proto/proto/connections_enums.pb.cc +++ b/compiled_proto/proto/connections_enums.pb.cc @@ -720,15 +720,17 @@ bool DisconnectionReason_IsValid(int value) { case 5: case 6: case 7: + case 8: return true; default: return false; } } -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed DisconnectionReason_strings[8] = {}; +static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed DisconnectionReason_strings[9] = {}; static const char DisconnectionReason_names[] = + "AUTHENTICATION_FAILURE" "IO_ERROR" "LOCAL_DISCONNECTION" "PREV_CHANNEL_DISCONNECTION_IN_RECONNECT" @@ -739,25 +741,27 @@ static const char DisconnectionReason_names[] = "UPGRADED"; static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry DisconnectionReason_entries[] = { - { {DisconnectionReason_names + 0, 8}, 3 }, - { {DisconnectionReason_names + 8, 19}, 1 }, - { {DisconnectionReason_names + 27, 39}, 7 }, - { {DisconnectionReason_names + 66, 20}, 2 }, - { {DisconnectionReason_names + 86, 8}, 5 }, - { {DisconnectionReason_names + 94, 10}, 6 }, - { {DisconnectionReason_names + 104, 28}, 0 }, - { {DisconnectionReason_names + 132, 8}, 4 }, + { {DisconnectionReason_names + 0, 22}, 8 }, + { {DisconnectionReason_names + 22, 8}, 3 }, + { {DisconnectionReason_names + 30, 19}, 1 }, + { {DisconnectionReason_names + 49, 39}, 7 }, + { {DisconnectionReason_names + 88, 20}, 2 }, + { {DisconnectionReason_names + 108, 8}, 5 }, + { {DisconnectionReason_names + 116, 10}, 6 }, + { {DisconnectionReason_names + 126, 28}, 0 }, + { {DisconnectionReason_names + 154, 8}, 4 }, }; static const int DisconnectionReason_entries_by_number[] = { - 6, // 0 -> UNKNOWN_DISCONNECTION_REASON - 1, // 1 -> LOCAL_DISCONNECTION - 3, // 2 -> REMOTE_DISCONNECTION - 0, // 3 -> IO_ERROR - 7, // 4 -> UPGRADED - 4, // 5 -> SHUTDOWN - 5, // 6 -> UNFINISHED - 2, // 7 -> PREV_CHANNEL_DISCONNECTION_IN_RECONNECT + 7, // 0 -> UNKNOWN_DISCONNECTION_REASON + 2, // 1 -> LOCAL_DISCONNECTION + 4, // 2 -> REMOTE_DISCONNECTION + 1, // 3 -> IO_ERROR + 8, // 4 -> UPGRADED + 5, // 5 -> SHUTDOWN + 6, // 6 -> UNFINISHED + 3, // 7 -> PREV_CHANNEL_DISCONNECTION_IN_RECONNECT + 0, // 8 -> AUTHENTICATION_FAILURE }; const std::string& DisconnectionReason_Name( @@ -766,12 +770,12 @@ const std::string& DisconnectionReason_Name( ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( DisconnectionReason_entries, DisconnectionReason_entries_by_number, - 8, DisconnectionReason_strings); + 9, DisconnectionReason_strings); (void) dummy; int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( DisconnectionReason_entries, DisconnectionReason_entries_by_number, - 8, value); + 9, value); return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : DisconnectionReason_strings[idx].get(); } @@ -779,7 +783,7 @@ bool DisconnectionReason_Parse( ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, DisconnectionReason* value) { int int_value; bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - DisconnectionReason_entries, 8, name, &int_value); + DisconnectionReason_entries, 9, name, &int_value); if (success) { *value = static_cast(int_value); } @@ -1505,7 +1509,7 @@ bool OperationResultCategory_Parse( } return success; } -bool OperationResultDetail_IsValid(int value) { +bool OperationResultCode_IsValid(int value) { switch (value) { case 0: case 1: @@ -1678,6 +1682,8 @@ bool OperationResultDetail_IsValid(int value) { case 3553: case 3554: case 3555: + case 3556: + case 3557: case 4500: case 4501: case 4502: @@ -1751,9 +1757,9 @@ bool OperationResultDetail_IsValid(int value) { } } -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed OperationResultDetail_strings[238] = {}; +static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed OperationResultCode_strings[240] = {}; -static const char OperationResultDetail_names[] = +static const char OperationResultCode_names[] = "CLIENT_CANCELLATION_BT_SERVER_SOCKET_CREATION" "CLIENT_CANCELLATION_CANCEL_BLE_OUTGOING_CONNECTION" "CLIENT_CANCELLATION_CANCEL_BT_OUTGOING_CONNECTION" @@ -1809,6 +1815,7 @@ static const char OperationResultDetail_names[] = "CONNECTIVITY_GENERIC_WRITING_CHANNEL_IO_ERROR" "CONNECTIVITY_L2CAP_CLIENT_OBTAIN_FAIURE" "CONNECTIVITY_L2CAP_CLIENT_SOCKET_CREATION_FAILURE" + "CONNECTIVITY_L2CAP_CLIENT_SOCKET_CREATION_TIMEOUT_FAILURE" "CONNECTIVITY_L2CAP_DATA_CONNECTION_FAILURE" "CONNECTIVITY_L2CAP_SERVER_SOCKET_CREATION_FAILURE" "CONNECTIVITY_L2CAP_SERVER_SOCKET_CREATION_SECURITY_EXCEPTION_FAILURE" @@ -1823,6 +1830,7 @@ static const char OperationResultDetail_names[] = "CONNECTIVITY_WEB_RTC_CONNECT_TO_TACHYON_FAILURE" "CONNECTIVITY_WEB_RTC_INVALID_CREDENTIAL" "CONNECTIVITY_WEB_RTC_SERVER_SOCKET_CREATION_FAILURE" + "CONNECTIVITY_WEB_RTC_UNSATISFIED_LINK_ERROR" "CONNECTIVITY_WIFI_AWARE_ATTACH_FAILURE" "CONNECTIVITY_WIFI_AWARE_CLIENT_SOCKET_CREATION_FAILURE" "CONNECTIVITY_WIFI_AWARE_DISCOVERED_PEER_NULL" @@ -1859,8 +1867,8 @@ static const char OperationResultDetail_names[] = "DEVICE_STATE_RADIO_DISABLING_FAILURE" "DEVICE_STATE_RADIO_ENABLING_FAILURE" "IO_ENDPOINT_IO_ERROR_ON_BLE" + "IO_ENDPOINT_IO_ERROR_ON_BLE_L2CAP" "IO_ENDPOINT_IO_ERROR_ON_BT" - "IO_ENDPOINT_IO_ERROR_ON_L2CAP" "IO_ENDPOINT_IO_ERROR_ON_LAN" "IO_ENDPOINT_IO_ERROR_ON_NFC" "IO_ENDPOINT_IO_ERROR_ON_USB" @@ -1993,250 +2001,252 @@ static const char OperationResultDetail_names[] = "NEARBY_WIFI_HOTSPOT_SOFT_AP_OPERATION_REGISTERED_FAILED" "NEARBY_WIFI_LAN_IP_ADDRESS_ERROR"; -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry OperationResultDetail_entries[] = { - { {OperationResultDetail_names + 0, 45}, 519 }, - { {OperationResultDetail_names + 45, 50}, 504 }, - { {OperationResultDetail_names + 95, 49}, 505 }, - { {OperationResultDetail_names + 144, 46}, 515 }, - { {OperationResultDetail_names + 190, 52}, 506 }, - { {OperationResultDetail_names + 242, 50}, 507 }, - { {OperationResultDetail_names + 292, 50}, 508 }, - { {OperationResultDetail_names + 342, 46}, 514 }, - { {OperationResultDetail_names + 388, 50}, 509 }, - { {OperationResultDetail_names + 438, 54}, 513 }, - { {OperationResultDetail_names + 492, 57}, 510 }, - { {OperationResultDetail_names + 549, 58}, 511 }, - { {OperationResultDetail_names + 607, 59}, 512 }, - { {OperationResultDetail_names + 666, 40}, 501 }, - { {OperationResultDetail_names + 706, 36}, 522 }, - { {OperationResultDetail_names + 742, 41}, 502 }, - { {OperationResultDetail_names + 783, 37}, 523 }, - { {OperationResultDetail_names + 820, 44}, 500 }, - { {OperationResultDetail_names + 864, 46}, 503 }, - { {OperationResultDetail_names + 910, 50}, 520 }, - { {OperationResultDetail_names + 960, 53}, 516 }, - { {OperationResultDetail_names + 1013, 54}, 517 }, - { {OperationResultDetail_names + 1067, 55}, 518 }, - { {OperationResultDetail_names + 1122, 51}, 521 }, - { {OperationResultDetail_names + 1173, 49}, 2002 }, - { {OperationResultDetail_names + 1222, 48}, 2004 }, - { {OperationResultDetail_names + 1270, 51}, 2003 }, - { {OperationResultDetail_names + 1321, 49}, 2005 }, - { {OperationResultDetail_names + 1370, 49}, 2006 }, - { {OperationResultDetail_names + 1419, 49}, 2011 }, - { {OperationResultDetail_names + 1468, 53}, 2007 }, - { {OperationResultDetail_names + 1521, 56}, 2008 }, - { {OperationResultDetail_names + 1577, 57}, 2010 }, - { {OperationResultDetail_names + 1634, 58}, 2009 }, - { {OperationResultDetail_names + 1692, 46}, 2012 }, - { {OperationResultDetail_names + 1738, 47}, 2015 }, - { {OperationResultDetail_names + 1785, 47}, 2013 }, - { {OperationResultDetail_names + 1832, 48}, 2014 }, - { {OperationResultDetail_names + 1880, 43}, 2016 }, - { {OperationResultDetail_names + 1923, 63}, 2000 }, - { {OperationResultDetail_names + 1986, 59}, 2001 }, - { {OperationResultDetail_names + 2045, 47}, 3502 }, - { {OperationResultDetail_names + 2092, 47}, 3513 }, - { {OperationResultDetail_names + 2139, 47}, 3539 }, - { {OperationResultDetail_names + 2186, 44}, 3501 }, - { {OperationResultDetail_names + 2230, 41}, 3518 }, - { {OperationResultDetail_names + 2271, 46}, 3504 }, - { {OperationResultDetail_names + 2317, 46}, 3541 }, - { {OperationResultDetail_names + 2363, 65}, 3555 }, - { {OperationResultDetail_names + 2428, 37}, 3538 }, - { {OperationResultDetail_names + 2465, 39}, 3553 }, - { {OperationResultDetail_names + 2504, 59}, 3551 }, - { {OperationResultDetail_names + 2563, 45}, 3550 }, - { {OperationResultDetail_names + 2608, 39}, 3525 }, - { {OperationResultDetail_names + 2647, 49}, 3503 }, - { {OperationResultDetail_names + 2696, 42}, 3526 }, - { {OperationResultDetail_names + 2738, 49}, 3540 }, - { {OperationResultDetail_names + 2787, 68}, 3554 }, - { {OperationResultDetail_names + 2855, 47}, 3505 }, - { {OperationResultDetail_names + 2902, 47}, 3531 }, - { {OperationResultDetail_names + 2949, 47}, 3542 }, - { {OperationResultDetail_names + 2996, 28}, 3529 }, - { {OperationResultDetail_names + 3024, 47}, 3506 }, - { {OperationResultDetail_names + 3071, 47}, 3547 }, - { {OperationResultDetail_names + 3118, 47}, 3511 }, - { {OperationResultDetail_names + 3165, 51}, 3507 }, - { {OperationResultDetail_names + 3216, 47}, 3512 }, - { {OperationResultDetail_names + 3263, 39}, 3523 }, - { {OperationResultDetail_names + 3302, 51}, 3543 }, - { {OperationResultDetail_names + 3353, 38}, 3500 }, - { {OperationResultDetail_names + 3391, 54}, 3508 }, - { {OperationResultDetail_names + 3445, 44}, 3552 }, - { {OperationResultDetail_names + 3489, 53}, 3515 }, - { {OperationResultDetail_names + 3542, 51}, 3514 }, - { {OperationResultDetail_names + 3593, 42}, 3522 }, - { {OperationResultDetail_names + 3635, 62}, 3527 }, - { {OperationResultDetail_names + 3697, 65}, 3528 }, - { {OperationResultDetail_names + 3762, 54}, 3544 }, - { {OperationResultDetail_names + 3816, 46}, 3549 }, - { {OperationResultDetail_names + 3862, 55}, 3510 }, - { {OperationResultDetail_names + 3917, 55}, 3532 }, - { {OperationResultDetail_names + 3972, 54}, 3516 }, - { {OperationResultDetail_names + 4026, 43}, 3520 }, - { {OperationResultDetail_names + 4069, 55}, 3535 }, - { {OperationResultDetail_names + 4124, 51}, 3537 }, - { {OperationResultDetail_names + 4175, 55}, 3546 }, - { {OperationResultDetail_names + 4230, 56}, 3509 }, - { {OperationResultDetail_names + 4286, 56}, 3533 }, - { {OperationResultDetail_names + 4342, 55}, 3517 }, - { {OperationResultDetail_names + 4397, 44}, 3521 }, - { {OperationResultDetail_names + 4441, 47}, 3530 }, - { {OperationResultDetail_names + 4488, 56}, 3534 }, - { {OperationResultDetail_names + 4544, 52}, 3536 }, - { {OperationResultDetail_names + 4596, 56}, 3545 }, - { {OperationResultDetail_names + 4652, 50}, 3548 }, - { {OperationResultDetail_names + 4702, 40}, 3519 }, - { {OperationResultDetail_names + 4742, 38}, 3524 }, - { {OperationResultDetail_names + 4780, 14}, 1 }, - { {OperationResultDetail_names + 4794, 14}, 0 }, - { {OperationResultDetail_names + 4808, 46}, 1000 }, - { {OperationResultDetail_names + 4854, 39}, 1001 }, - { {OperationResultDetail_names + 4893, 30}, 1002 }, - { {OperationResultDetail_names + 4923, 36}, 1003 }, - { {OperationResultDetail_names + 4959, 35}, 1004 }, - { {OperationResultDetail_names + 4994, 27}, 3005 }, - { {OperationResultDetail_names + 5021, 26}, 3007 }, - { {OperationResultDetail_names + 5047, 29}, 3006 }, - { {OperationResultDetail_names + 5076, 27}, 3009 }, - { {OperationResultDetail_names + 5103, 27}, 3013 }, - { {OperationResultDetail_names + 5130, 27}, 3014 }, - { {OperationResultDetail_names + 5157, 31}, 3008 }, - { {OperationResultDetail_names + 5188, 34}, 3012 }, - { {OperationResultDetail_names + 5222, 35}, 3010 }, - { {OperationResultDetail_names + 5257, 36}, 3011 }, - { {OperationResultDetail_names + 5293, 21}, 3000 }, - { {OperationResultDetail_names + 5314, 21}, 3001 }, - { {OperationResultDetail_names + 5335, 21}, 3002 }, - { {OperationResultDetail_names + 5356, 24}, 3003 }, - { {OperationResultDetail_names + 5380, 29}, 3004 }, - { {OperationResultDetail_names + 5409, 51}, 1534 }, - { {OperationResultDetail_names + 5460, 60}, 1535 }, - { {OperationResultDetail_names + 5520, 47}, 1515 }, - { {OperationResultDetail_names + 5567, 36}, 1505 }, - { {OperationResultDetail_names + 5603, 42}, 1507 }, - { {OperationResultDetail_names + 5645, 46}, 1516 }, - { {OperationResultDetail_names + 5691, 45}, 1501 }, - { {OperationResultDetail_names + 5736, 38}, 1506 }, - { {OperationResultDetail_names + 5774, 47}, 1517 }, - { {OperationResultDetail_names + 5821, 36}, 1513 }, - { {OperationResultDetail_names + 5857, 54}, 1532 }, - { {OperationResultDetail_names + 5911, 49}, 1503 }, - { {OperationResultDetail_names + 5960, 52}, 1504 }, - { {OperationResultDetail_names + 6012, 47}, 1518 }, - { {OperationResultDetail_names + 6059, 36}, 1512 }, - { {OperationResultDetail_names + 6095, 60}, 1536 }, - { {OperationResultDetail_names + 6155, 43}, 1533 }, - { {OperationResultDetail_names + 6198, 38}, 1502 }, - { {OperationResultDetail_names + 6236, 41}, 1537 }, - { {OperationResultDetail_names + 6277, 55}, 1526 }, - { {OperationResultDetail_names + 6332, 54}, 1530 }, - { {OperationResultDetail_names + 6386, 57}, 1527 }, - { {OperationResultDetail_names + 6443, 55}, 1529 }, - { {OperationResultDetail_names + 6498, 55}, 1531 }, - { {OperationResultDetail_names + 6553, 59}, 1528 }, - { {OperationResultDetail_names + 6612, 47}, 1519 }, - { {OperationResultDetail_names + 6659, 36}, 1514 }, - { {OperationResultDetail_names + 6695, 51}, 1520 }, - { {OperationResultDetail_names + 6746, 40}, 1508 }, - { {OperationResultDetail_names + 6786, 38}, 1538 }, - { {OperationResultDetail_names + 6824, 54}, 1521 }, - { {OperationResultDetail_names + 6878, 43}, 1509 }, - { {OperationResultDetail_names + 6921, 52}, 1500 }, - { {OperationResultDetail_names + 6973, 55}, 1523 }, - { {OperationResultDetail_names + 7028, 44}, 1511 }, - { {OperationResultDetail_names + 7072, 57}, 1525 }, - { {OperationResultDetail_names + 7129, 56}, 1522 }, - { {OperationResultDetail_names + 7185, 45}, 1510 }, - { {OperationResultDetail_names + 7230, 58}, 1524 }, - { {OperationResultDetail_names + 7288, 38}, 2503 }, - { {OperationResultDetail_names + 7326, 41}, 2500 }, - { {OperationResultDetail_names + 7367, 59}, 2510 }, - { {OperationResultDetail_names + 7426, 37}, 2505 }, - { {OperationResultDetail_names + 7463, 40}, 2504 }, - { {OperationResultDetail_names + 7503, 33}, 2501 }, - { {OperationResultDetail_names + 7536, 52}, 2511 }, - { {OperationResultDetail_names + 7588, 55}, 2512 }, - { {OperationResultDetail_names + 7643, 45}, 2506 }, - { {OperationResultDetail_names + 7688, 46}, 2507 }, - { {OperationResultDetail_names + 7734, 56}, 2502 }, - { {OperationResultDetail_names + 7790, 47}, 2509 }, - { {OperationResultDetail_names + 7837, 43}, 2508 }, - { {OperationResultDetail_names + 7880, 45}, 4500 }, - { {OperationResultDetail_names + 7925, 44}, 4504 }, - { {OperationResultDetail_names + 7969, 49}, 4515 }, - { {OperationResultDetail_names + 8018, 29}, 4518 }, - { {OperationResultDetail_names + 8047, 38}, 4536 }, - { {OperationResultDetail_names + 8085, 48}, 4501 }, - { {OperationResultDetail_names + 8133, 43}, 4506 }, - { {OperationResultDetail_names + 8176, 35}, 4530 }, - { {OperationResultDetail_names + 8211, 23}, 4520 }, - { {OperationResultDetail_names + 8234, 37}, 4538 }, - { {OperationResultDetail_names + 8271, 41}, 4563 }, - { {OperationResultDetail_names + 8312, 32}, 4503 }, - { {OperationResultDetail_names + 8344, 35}, 4514 }, - { {OperationResultDetail_names + 8379, 45}, 4552 }, - { {OperationResultDetail_names + 8424, 40}, 4532 }, - { {OperationResultDetail_names + 8464, 40}, 4535 }, - { {OperationResultDetail_names + 8504, 48}, 4547 }, - { {OperationResultDetail_names + 8552, 60}, 4556 }, - { {OperationResultDetail_names + 8612, 56}, 4558 }, - { {OperationResultDetail_names + 8668, 60}, 4557 }, - { {OperationResultDetail_names + 8728, 56}, 4553 }, - { {OperationResultDetail_names + 8784, 52}, 4555 }, - { {OperationResultDetail_names + 8836, 56}, 4554 }, - { {OperationResultDetail_names + 8892, 43}, 4559 }, - { {OperationResultDetail_names + 8935, 43}, 4560 }, - { {OperationResultDetail_names + 8978, 37}, 4561 }, - { {OperationResultDetail_names + 9015, 41}, 4562 }, - { {OperationResultDetail_names + 9056, 46}, 4505 }, - { {OperationResultDetail_names + 9102, 26}, 4519 }, - { {OperationResultDetail_names + 9128, 40}, 4537 }, - { {OperationResultDetail_names + 9168, 29}, 4566 }, - { {OperationResultDetail_names + 9197, 44}, 4507 }, - { {OperationResultDetail_names + 9241, 36}, 4531 }, - { {OperationResultDetail_names + 9277, 24}, 4525 }, - { {OperationResultDetail_names + 9301, 38}, 4539 }, - { {OperationResultDetail_names + 9339, 42}, 4564 }, - { {OperationResultDetail_names + 9381, 44}, 4508 }, - { {OperationResultDetail_names + 9425, 24}, 4522 }, - { {OperationResultDetail_names + 9449, 44}, 4513 }, - { {OperationResultDetail_names + 9493, 24}, 4521 }, - { {OperationResultDetail_names + 9517, 35}, 4502 }, - { {OperationResultDetail_names + 9552, 48}, 4512 }, - { {OperationResultDetail_names + 9600, 28}, 4524 }, - { {OperationResultDetail_names + 9628, 42}, 4540 }, - { {OperationResultDetail_names + 9670, 51}, 4509 }, - { {OperationResultDetail_names + 9721, 31}, 4523 }, - { {OperationResultDetail_names + 9752, 45}, 4541 }, - { {OperationResultDetail_names + 9797, 52}, 4511 }, - { {OperationResultDetail_names + 9849, 39}, 4516 }, - { {OperationResultDetail_names + 9888, 41}, 4533 }, - { {OperationResultDetail_names + 9929, 32}, 4527 }, - { {OperationResultDetail_names + 9961, 32}, 4529 }, - { {OperationResultDetail_names + 9993, 28}, 4528 }, - { {OperationResultDetail_names + 10021, 46}, 4546 }, - { {OperationResultDetail_names + 10067, 48}, 4549 }, - { {OperationResultDetail_names + 10115, 48}, 4551 }, - { {OperationResultDetail_names + 10163, 54}, 4545 }, - { {OperationResultDetail_names + 10217, 54}, 4542 }, - { {OperationResultDetail_names + 10271, 53}, 4510 }, - { {OperationResultDetail_names + 10324, 40}, 4517 }, - { {OperationResultDetail_names + 10364, 52}, 4544 }, - { {OperationResultDetail_names + 10416, 44}, 4534 }, - { {OperationResultDetail_names + 10460, 33}, 4526 }, - { {OperationResultDetail_names + 10493, 49}, 4548 }, - { {OperationResultDetail_names + 10542, 49}, 4550 }, - { {OperationResultDetail_names + 10591, 55}, 4543 }, - { {OperationResultDetail_names + 10646, 32}, 4565 }, +static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry OperationResultCode_entries[] = { + { {OperationResultCode_names + 0, 45}, 519 }, + { {OperationResultCode_names + 45, 50}, 504 }, + { {OperationResultCode_names + 95, 49}, 505 }, + { {OperationResultCode_names + 144, 46}, 515 }, + { {OperationResultCode_names + 190, 52}, 506 }, + { {OperationResultCode_names + 242, 50}, 507 }, + { {OperationResultCode_names + 292, 50}, 508 }, + { {OperationResultCode_names + 342, 46}, 514 }, + { {OperationResultCode_names + 388, 50}, 509 }, + { {OperationResultCode_names + 438, 54}, 513 }, + { {OperationResultCode_names + 492, 57}, 510 }, + { {OperationResultCode_names + 549, 58}, 511 }, + { {OperationResultCode_names + 607, 59}, 512 }, + { {OperationResultCode_names + 666, 40}, 501 }, + { {OperationResultCode_names + 706, 36}, 522 }, + { {OperationResultCode_names + 742, 41}, 502 }, + { {OperationResultCode_names + 783, 37}, 523 }, + { {OperationResultCode_names + 820, 44}, 500 }, + { {OperationResultCode_names + 864, 46}, 503 }, + { {OperationResultCode_names + 910, 50}, 520 }, + { {OperationResultCode_names + 960, 53}, 516 }, + { {OperationResultCode_names + 1013, 54}, 517 }, + { {OperationResultCode_names + 1067, 55}, 518 }, + { {OperationResultCode_names + 1122, 51}, 521 }, + { {OperationResultCode_names + 1173, 49}, 2002 }, + { {OperationResultCode_names + 1222, 48}, 2004 }, + { {OperationResultCode_names + 1270, 51}, 2003 }, + { {OperationResultCode_names + 1321, 49}, 2005 }, + { {OperationResultCode_names + 1370, 49}, 2006 }, + { {OperationResultCode_names + 1419, 49}, 2011 }, + { {OperationResultCode_names + 1468, 53}, 2007 }, + { {OperationResultCode_names + 1521, 56}, 2008 }, + { {OperationResultCode_names + 1577, 57}, 2010 }, + { {OperationResultCode_names + 1634, 58}, 2009 }, + { {OperationResultCode_names + 1692, 46}, 2012 }, + { {OperationResultCode_names + 1738, 47}, 2015 }, + { {OperationResultCode_names + 1785, 47}, 2013 }, + { {OperationResultCode_names + 1832, 48}, 2014 }, + { {OperationResultCode_names + 1880, 43}, 2016 }, + { {OperationResultCode_names + 1923, 63}, 2000 }, + { {OperationResultCode_names + 1986, 59}, 2001 }, + { {OperationResultCode_names + 2045, 47}, 3502 }, + { {OperationResultCode_names + 2092, 47}, 3513 }, + { {OperationResultCode_names + 2139, 47}, 3539 }, + { {OperationResultCode_names + 2186, 44}, 3501 }, + { {OperationResultCode_names + 2230, 41}, 3518 }, + { {OperationResultCode_names + 2271, 46}, 3504 }, + { {OperationResultCode_names + 2317, 46}, 3541 }, + { {OperationResultCode_names + 2363, 65}, 3555 }, + { {OperationResultCode_names + 2428, 37}, 3538 }, + { {OperationResultCode_names + 2465, 39}, 3553 }, + { {OperationResultCode_names + 2504, 59}, 3551 }, + { {OperationResultCode_names + 2563, 45}, 3550 }, + { {OperationResultCode_names + 2608, 39}, 3525 }, + { {OperationResultCode_names + 2647, 49}, 3503 }, + { {OperationResultCode_names + 2696, 57}, 3556 }, + { {OperationResultCode_names + 2753, 42}, 3526 }, + { {OperationResultCode_names + 2795, 49}, 3540 }, + { {OperationResultCode_names + 2844, 68}, 3554 }, + { {OperationResultCode_names + 2912, 47}, 3505 }, + { {OperationResultCode_names + 2959, 47}, 3531 }, + { {OperationResultCode_names + 3006, 47}, 3542 }, + { {OperationResultCode_names + 3053, 28}, 3529 }, + { {OperationResultCode_names + 3081, 47}, 3506 }, + { {OperationResultCode_names + 3128, 47}, 3547 }, + { {OperationResultCode_names + 3175, 47}, 3511 }, + { {OperationResultCode_names + 3222, 51}, 3507 }, + { {OperationResultCode_names + 3273, 47}, 3512 }, + { {OperationResultCode_names + 3320, 39}, 3523 }, + { {OperationResultCode_names + 3359, 51}, 3543 }, + { {OperationResultCode_names + 3410, 43}, 3557 }, + { {OperationResultCode_names + 3453, 38}, 3500 }, + { {OperationResultCode_names + 3491, 54}, 3508 }, + { {OperationResultCode_names + 3545, 44}, 3552 }, + { {OperationResultCode_names + 3589, 53}, 3515 }, + { {OperationResultCode_names + 3642, 51}, 3514 }, + { {OperationResultCode_names + 3693, 42}, 3522 }, + { {OperationResultCode_names + 3735, 62}, 3527 }, + { {OperationResultCode_names + 3797, 65}, 3528 }, + { {OperationResultCode_names + 3862, 54}, 3544 }, + { {OperationResultCode_names + 3916, 46}, 3549 }, + { {OperationResultCode_names + 3962, 55}, 3510 }, + { {OperationResultCode_names + 4017, 55}, 3532 }, + { {OperationResultCode_names + 4072, 54}, 3516 }, + { {OperationResultCode_names + 4126, 43}, 3520 }, + { {OperationResultCode_names + 4169, 55}, 3535 }, + { {OperationResultCode_names + 4224, 51}, 3537 }, + { {OperationResultCode_names + 4275, 55}, 3546 }, + { {OperationResultCode_names + 4330, 56}, 3509 }, + { {OperationResultCode_names + 4386, 56}, 3533 }, + { {OperationResultCode_names + 4442, 55}, 3517 }, + { {OperationResultCode_names + 4497, 44}, 3521 }, + { {OperationResultCode_names + 4541, 47}, 3530 }, + { {OperationResultCode_names + 4588, 56}, 3534 }, + { {OperationResultCode_names + 4644, 52}, 3536 }, + { {OperationResultCode_names + 4696, 56}, 3545 }, + { {OperationResultCode_names + 4752, 50}, 3548 }, + { {OperationResultCode_names + 4802, 40}, 3519 }, + { {OperationResultCode_names + 4842, 38}, 3524 }, + { {OperationResultCode_names + 4880, 14}, 1 }, + { {OperationResultCode_names + 4894, 14}, 0 }, + { {OperationResultCode_names + 4908, 46}, 1000 }, + { {OperationResultCode_names + 4954, 39}, 1001 }, + { {OperationResultCode_names + 4993, 30}, 1002 }, + { {OperationResultCode_names + 5023, 36}, 1003 }, + { {OperationResultCode_names + 5059, 35}, 1004 }, + { {OperationResultCode_names + 5094, 27}, 3005 }, + { {OperationResultCode_names + 5121, 33}, 3006 }, + { {OperationResultCode_names + 5154, 26}, 3007 }, + { {OperationResultCode_names + 5180, 27}, 3009 }, + { {OperationResultCode_names + 5207, 27}, 3013 }, + { {OperationResultCode_names + 5234, 27}, 3014 }, + { {OperationResultCode_names + 5261, 31}, 3008 }, + { {OperationResultCode_names + 5292, 34}, 3012 }, + { {OperationResultCode_names + 5326, 35}, 3010 }, + { {OperationResultCode_names + 5361, 36}, 3011 }, + { {OperationResultCode_names + 5397, 21}, 3000 }, + { {OperationResultCode_names + 5418, 21}, 3001 }, + { {OperationResultCode_names + 5439, 21}, 3002 }, + { {OperationResultCode_names + 5460, 24}, 3003 }, + { {OperationResultCode_names + 5484, 29}, 3004 }, + { {OperationResultCode_names + 5513, 51}, 1534 }, + { {OperationResultCode_names + 5564, 60}, 1535 }, + { {OperationResultCode_names + 5624, 47}, 1515 }, + { {OperationResultCode_names + 5671, 36}, 1505 }, + { {OperationResultCode_names + 5707, 42}, 1507 }, + { {OperationResultCode_names + 5749, 46}, 1516 }, + { {OperationResultCode_names + 5795, 45}, 1501 }, + { {OperationResultCode_names + 5840, 38}, 1506 }, + { {OperationResultCode_names + 5878, 47}, 1517 }, + { {OperationResultCode_names + 5925, 36}, 1513 }, + { {OperationResultCode_names + 5961, 54}, 1532 }, + { {OperationResultCode_names + 6015, 49}, 1503 }, + { {OperationResultCode_names + 6064, 52}, 1504 }, + { {OperationResultCode_names + 6116, 47}, 1518 }, + { {OperationResultCode_names + 6163, 36}, 1512 }, + { {OperationResultCode_names + 6199, 60}, 1536 }, + { {OperationResultCode_names + 6259, 43}, 1533 }, + { {OperationResultCode_names + 6302, 38}, 1502 }, + { {OperationResultCode_names + 6340, 41}, 1537 }, + { {OperationResultCode_names + 6381, 55}, 1526 }, + { {OperationResultCode_names + 6436, 54}, 1530 }, + { {OperationResultCode_names + 6490, 57}, 1527 }, + { {OperationResultCode_names + 6547, 55}, 1529 }, + { {OperationResultCode_names + 6602, 55}, 1531 }, + { {OperationResultCode_names + 6657, 59}, 1528 }, + { {OperationResultCode_names + 6716, 47}, 1519 }, + { {OperationResultCode_names + 6763, 36}, 1514 }, + { {OperationResultCode_names + 6799, 51}, 1520 }, + { {OperationResultCode_names + 6850, 40}, 1508 }, + { {OperationResultCode_names + 6890, 38}, 1538 }, + { {OperationResultCode_names + 6928, 54}, 1521 }, + { {OperationResultCode_names + 6982, 43}, 1509 }, + { {OperationResultCode_names + 7025, 52}, 1500 }, + { {OperationResultCode_names + 7077, 55}, 1523 }, + { {OperationResultCode_names + 7132, 44}, 1511 }, + { {OperationResultCode_names + 7176, 57}, 1525 }, + { {OperationResultCode_names + 7233, 56}, 1522 }, + { {OperationResultCode_names + 7289, 45}, 1510 }, + { {OperationResultCode_names + 7334, 58}, 1524 }, + { {OperationResultCode_names + 7392, 38}, 2503 }, + { {OperationResultCode_names + 7430, 41}, 2500 }, + { {OperationResultCode_names + 7471, 59}, 2510 }, + { {OperationResultCode_names + 7530, 37}, 2505 }, + { {OperationResultCode_names + 7567, 40}, 2504 }, + { {OperationResultCode_names + 7607, 33}, 2501 }, + { {OperationResultCode_names + 7640, 52}, 2511 }, + { {OperationResultCode_names + 7692, 55}, 2512 }, + { {OperationResultCode_names + 7747, 45}, 2506 }, + { {OperationResultCode_names + 7792, 46}, 2507 }, + { {OperationResultCode_names + 7838, 56}, 2502 }, + { {OperationResultCode_names + 7894, 47}, 2509 }, + { {OperationResultCode_names + 7941, 43}, 2508 }, + { {OperationResultCode_names + 7984, 45}, 4500 }, + { {OperationResultCode_names + 8029, 44}, 4504 }, + { {OperationResultCode_names + 8073, 49}, 4515 }, + { {OperationResultCode_names + 8122, 29}, 4518 }, + { {OperationResultCode_names + 8151, 38}, 4536 }, + { {OperationResultCode_names + 8189, 48}, 4501 }, + { {OperationResultCode_names + 8237, 43}, 4506 }, + { {OperationResultCode_names + 8280, 35}, 4530 }, + { {OperationResultCode_names + 8315, 23}, 4520 }, + { {OperationResultCode_names + 8338, 37}, 4538 }, + { {OperationResultCode_names + 8375, 41}, 4563 }, + { {OperationResultCode_names + 8416, 32}, 4503 }, + { {OperationResultCode_names + 8448, 35}, 4514 }, + { {OperationResultCode_names + 8483, 45}, 4552 }, + { {OperationResultCode_names + 8528, 40}, 4532 }, + { {OperationResultCode_names + 8568, 40}, 4535 }, + { {OperationResultCode_names + 8608, 48}, 4547 }, + { {OperationResultCode_names + 8656, 60}, 4556 }, + { {OperationResultCode_names + 8716, 56}, 4558 }, + { {OperationResultCode_names + 8772, 60}, 4557 }, + { {OperationResultCode_names + 8832, 56}, 4553 }, + { {OperationResultCode_names + 8888, 52}, 4555 }, + { {OperationResultCode_names + 8940, 56}, 4554 }, + { {OperationResultCode_names + 8996, 43}, 4559 }, + { {OperationResultCode_names + 9039, 43}, 4560 }, + { {OperationResultCode_names + 9082, 37}, 4561 }, + { {OperationResultCode_names + 9119, 41}, 4562 }, + { {OperationResultCode_names + 9160, 46}, 4505 }, + { {OperationResultCode_names + 9206, 26}, 4519 }, + { {OperationResultCode_names + 9232, 40}, 4537 }, + { {OperationResultCode_names + 9272, 29}, 4566 }, + { {OperationResultCode_names + 9301, 44}, 4507 }, + { {OperationResultCode_names + 9345, 36}, 4531 }, + { {OperationResultCode_names + 9381, 24}, 4525 }, + { {OperationResultCode_names + 9405, 38}, 4539 }, + { {OperationResultCode_names + 9443, 42}, 4564 }, + { {OperationResultCode_names + 9485, 44}, 4508 }, + { {OperationResultCode_names + 9529, 24}, 4522 }, + { {OperationResultCode_names + 9553, 44}, 4513 }, + { {OperationResultCode_names + 9597, 24}, 4521 }, + { {OperationResultCode_names + 9621, 35}, 4502 }, + { {OperationResultCode_names + 9656, 48}, 4512 }, + { {OperationResultCode_names + 9704, 28}, 4524 }, + { {OperationResultCode_names + 9732, 42}, 4540 }, + { {OperationResultCode_names + 9774, 51}, 4509 }, + { {OperationResultCode_names + 9825, 31}, 4523 }, + { {OperationResultCode_names + 9856, 45}, 4541 }, + { {OperationResultCode_names + 9901, 52}, 4511 }, + { {OperationResultCode_names + 9953, 39}, 4516 }, + { {OperationResultCode_names + 9992, 41}, 4533 }, + { {OperationResultCode_names + 10033, 32}, 4527 }, + { {OperationResultCode_names + 10065, 32}, 4529 }, + { {OperationResultCode_names + 10097, 28}, 4528 }, + { {OperationResultCode_names + 10125, 46}, 4546 }, + { {OperationResultCode_names + 10171, 48}, 4549 }, + { {OperationResultCode_names + 10219, 48}, 4551 }, + { {OperationResultCode_names + 10267, 54}, 4545 }, + { {OperationResultCode_names + 10321, 54}, 4542 }, + { {OperationResultCode_names + 10375, 53}, 4510 }, + { {OperationResultCode_names + 10428, 40}, 4517 }, + { {OperationResultCode_names + 10468, 52}, 4544 }, + { {OperationResultCode_names + 10520, 44}, 4534 }, + { {OperationResultCode_names + 10564, 33}, 4526 }, + { {OperationResultCode_names + 10597, 49}, 4548 }, + { {OperationResultCode_names + 10646, 49}, 4550 }, + { {OperationResultCode_names + 10695, 55}, 4543 }, + { {OperationResultCode_names + 10750, 32}, 4565 }, }; -static const int OperationResultDetail_entries_by_number[] = { - 98, // 0 -> DETAIL_UNKNOWN - 97, // 1 -> DETAIL_SUCCESS +static const int OperationResultCode_entries_by_number[] = { + 100, // 0 -> DETAIL_UNKNOWN + 99, // 1 -> DETAIL_SUCCESS 17, // 500 -> CLIENT_CANCELLATION_REMOTE_IN_CANCELED_STATE 13, // 501 -> CLIENT_CANCELLATION_LOCAL_CANCEL_PAYLOAD 15, // 502 -> CLIENT_CANCELLATION_REMOTE_CANCEL_PAYLOAD @@ -2261,50 +2271,50 @@ static const int OperationResultDetail_entries_by_number[] = { 23, // 521 -> CLIENT_CANCELLATION_WIFI_LAN_SERVER_SOCKET_CREATION 14, // 522 -> CLIENT_CANCELLATION_LOCAL_DISCONNECT 16, // 523 -> CLIENT_CANCELLATION_REMOTE_DISCONNECT - 99, // 1000 -> DEVICE_STATE_ERROR_UNFINISHED_UPGRADE_ATTEMPTS - 100, // 1001 -> DEVICE_STATE_ERROR_USER_HOTSPOT_ENABLED - 101, // 1002 -> DEVICE_STATE_LOCATION_DISABLED - 102, // 1003 -> DEVICE_STATE_RADIO_DISABLING_FAILURE - 103, // 1004 -> DEVICE_STATE_RADIO_ENABLING_FAILURE - 151, // 1500 -> MEDIUM_UNAVAILABLE_WIFI_AWARE_RESOURCE_NOT_AVAILABLE - 125, // 1501 -> MEDIUM_UNAVAILABLE_DIRECT_HOTSPOT_NOT_SUPPORT - 136, // 1502 -> MEDIUM_UNAVAILABLE_SOFT_AP_NOT_SUPPORT - 130, // 1503 -> MEDIUM_UNAVAILABLE_LOCAL_ONLY_HOTSPOT_NOT_SUPPORT - 131, // 1504 -> MEDIUM_UNAVAILABLE_LOCAL_ONLY_HOTSPOT_NOT_SUPPORT_5G - 122, // 1505 -> MEDIUM_UNAVAILABLE_BLE_NOT_AVAILABLE - 126, // 1506 -> MEDIUM_UNAVAILABLE_L2CAP_NOT_AVAILABLE - 123, // 1507 -> MEDIUM_UNAVAILABLE_BLUETOOTH_NOT_AVAILABLE - 147, // 1508 -> MEDIUM_UNAVAILABLE_WEB_RTC_NOT_AVAILABLE - 150, // 1509 -> MEDIUM_UNAVAILABLE_WIFI_AWARE_NOT_AVAILABLE - 156, // 1510 -> MEDIUM_UNAVAILABLE_WIFI_HOTSPOT_NOT_AVAILABLE - 153, // 1511 -> MEDIUM_UNAVAILABLE_WIFI_DIRECT_NOT_AVAILABLE - 133, // 1512 -> MEDIUM_UNAVAILABLE_NFC_NOT_AVAILABLE - 128, // 1513 -> MEDIUM_UNAVAILABLE_LAN_NOT_AVAILABLE - 145, // 1514 -> MEDIUM_UNAVAILABLE_USB_NOT_AVAILABLE - 121, // 1515 -> MEDIUM_UNAVAILABLE_BLE_NC_LOGICAL_NOT_AVAILABLE - 124, // 1516 -> MEDIUM_UNAVAILABLE_BT_NC_LOGICAL_NOT_AVAILABLE - 127, // 1517 -> MEDIUM_UNAVAILABLE_LAN_NC_LOGICAL_NOT_AVAILABLE - 132, // 1518 -> MEDIUM_UNAVAILABLE_NFC_NC_LOGICAL_NOT_AVAILABLE - 144, // 1519 -> MEDIUM_UNAVAILABLE_USB_NC_LOGICAL_NOT_AVAILABLE - 146, // 1520 -> MEDIUM_UNAVAILABLE_WEB_RTC_NC_LOGICAL_NOT_AVAILABLE - 149, // 1521 -> MEDIUM_UNAVAILABLE_WIFI_AWARE_NC_LOGICAL_NOT_AVAILABLE - 155, // 1522 -> MEDIUM_UNAVAILABLE_WIFI_HOTSPOT_NC_LOGICAL_NOT_AVAILABLE - 152, // 1523 -> MEDIUM_UNAVAILABLE_WIFI_DIRECT_NC_LOGICAL_NOT_AVAILABLE - 157, // 1524 -> MEDIUM_UNAVAILABLE_WIFI_HOTSPOT_P2P_RESOURCE_NOT_AVAILABLE - 154, // 1525 -> MEDIUM_UNAVAILABLE_WIFI_DIRECT_P2P_RESOURCE_NOT_AVAILABLE - 138, // 1526 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_BLE_LOW_QUALITY_MEDIUMS - 140, // 1527 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_L2CAP_LOW_QUALITY_MEDIUMS - 143, // 1528 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_WEB_RTC_LOW_QUALITY_MEDIUMS - 141, // 1529 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_LAN_LOW_QUALITY_MEDIUMS - 139, // 1530 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_BT_LOW_QUALITY_MEDIUMS - 142, // 1531 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_USB_LOW_QUALITY_MEDIUMS - 129, // 1532 -> MEDIUM_UNAVAILABLE_LOCAL_ONLY_HOTSPOT_DISRUPTIVE_FALSE - 135, // 1533 -> MEDIUM_UNAVAILABLE_SOFT_AP_DISRUPTIVE_FALSE - 119, // 1534 -> MEDIUM_UNAVAILABLE_ALREADY_HAVE_A_WIFI_DIRECT_GROUP - 120, // 1535 -> MEDIUM_UNAVAILABLE_ALREADY_HOSTING_HOTSPOT_FOR_OTHER_CLIENTS - 134, // 1536 -> MEDIUM_UNAVAILABLE_REJECT_L2CAP_ON_GATT_MULTIPLEX_CONNECTION - 137, // 1537 -> MEDIUM_UNAVAILABLE_UPGRADE_ON_SAME_MEDIUM - 148, // 1538 -> MEDIUM_UNAVAILABLE_WEB_RTC_NO_INTERNET + 101, // 1000 -> DEVICE_STATE_ERROR_UNFINISHED_UPGRADE_ATTEMPTS + 102, // 1001 -> DEVICE_STATE_ERROR_USER_HOTSPOT_ENABLED + 103, // 1002 -> DEVICE_STATE_LOCATION_DISABLED + 104, // 1003 -> DEVICE_STATE_RADIO_DISABLING_FAILURE + 105, // 1004 -> DEVICE_STATE_RADIO_ENABLING_FAILURE + 153, // 1500 -> MEDIUM_UNAVAILABLE_WIFI_AWARE_RESOURCE_NOT_AVAILABLE + 127, // 1501 -> MEDIUM_UNAVAILABLE_DIRECT_HOTSPOT_NOT_SUPPORT + 138, // 1502 -> MEDIUM_UNAVAILABLE_SOFT_AP_NOT_SUPPORT + 132, // 1503 -> MEDIUM_UNAVAILABLE_LOCAL_ONLY_HOTSPOT_NOT_SUPPORT + 133, // 1504 -> MEDIUM_UNAVAILABLE_LOCAL_ONLY_HOTSPOT_NOT_SUPPORT_5G + 124, // 1505 -> MEDIUM_UNAVAILABLE_BLE_NOT_AVAILABLE + 128, // 1506 -> MEDIUM_UNAVAILABLE_L2CAP_NOT_AVAILABLE + 125, // 1507 -> MEDIUM_UNAVAILABLE_BLUETOOTH_NOT_AVAILABLE + 149, // 1508 -> MEDIUM_UNAVAILABLE_WEB_RTC_NOT_AVAILABLE + 152, // 1509 -> MEDIUM_UNAVAILABLE_WIFI_AWARE_NOT_AVAILABLE + 158, // 1510 -> MEDIUM_UNAVAILABLE_WIFI_HOTSPOT_NOT_AVAILABLE + 155, // 1511 -> MEDIUM_UNAVAILABLE_WIFI_DIRECT_NOT_AVAILABLE + 135, // 1512 -> MEDIUM_UNAVAILABLE_NFC_NOT_AVAILABLE + 130, // 1513 -> MEDIUM_UNAVAILABLE_LAN_NOT_AVAILABLE + 147, // 1514 -> MEDIUM_UNAVAILABLE_USB_NOT_AVAILABLE + 123, // 1515 -> MEDIUM_UNAVAILABLE_BLE_NC_LOGICAL_NOT_AVAILABLE + 126, // 1516 -> MEDIUM_UNAVAILABLE_BT_NC_LOGICAL_NOT_AVAILABLE + 129, // 1517 -> MEDIUM_UNAVAILABLE_LAN_NC_LOGICAL_NOT_AVAILABLE + 134, // 1518 -> MEDIUM_UNAVAILABLE_NFC_NC_LOGICAL_NOT_AVAILABLE + 146, // 1519 -> MEDIUM_UNAVAILABLE_USB_NC_LOGICAL_NOT_AVAILABLE + 148, // 1520 -> MEDIUM_UNAVAILABLE_WEB_RTC_NC_LOGICAL_NOT_AVAILABLE + 151, // 1521 -> MEDIUM_UNAVAILABLE_WIFI_AWARE_NC_LOGICAL_NOT_AVAILABLE + 157, // 1522 -> MEDIUM_UNAVAILABLE_WIFI_HOTSPOT_NC_LOGICAL_NOT_AVAILABLE + 154, // 1523 -> MEDIUM_UNAVAILABLE_WIFI_DIRECT_NC_LOGICAL_NOT_AVAILABLE + 159, // 1524 -> MEDIUM_UNAVAILABLE_WIFI_HOTSPOT_P2P_RESOURCE_NOT_AVAILABLE + 156, // 1525 -> MEDIUM_UNAVAILABLE_WIFI_DIRECT_P2P_RESOURCE_NOT_AVAILABLE + 140, // 1526 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_BLE_LOW_QUALITY_MEDIUMS + 142, // 1527 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_L2CAP_LOW_QUALITY_MEDIUMS + 145, // 1528 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_WEB_RTC_LOW_QUALITY_MEDIUMS + 143, // 1529 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_LAN_LOW_QUALITY_MEDIUMS + 141, // 1530 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_BT_LOW_QUALITY_MEDIUMS + 144, // 1531 -> MEDIUM_UNAVAILABLE_UPGRADE_SKIP_USB_LOW_QUALITY_MEDIUMS + 131, // 1532 -> MEDIUM_UNAVAILABLE_LOCAL_ONLY_HOTSPOT_DISRUPTIVE_FALSE + 137, // 1533 -> MEDIUM_UNAVAILABLE_SOFT_AP_DISRUPTIVE_FALSE + 121, // 1534 -> MEDIUM_UNAVAILABLE_ALREADY_HAVE_A_WIFI_DIRECT_GROUP + 122, // 1535 -> MEDIUM_UNAVAILABLE_ALREADY_HOSTING_HOTSPOT_FOR_OTHER_CLIENTS + 136, // 1536 -> MEDIUM_UNAVAILABLE_REJECT_L2CAP_ON_GATT_MULTIPLEX_CONNECTION + 139, // 1537 -> MEDIUM_UNAVAILABLE_UPGRADE_ON_SAME_MEDIUM + 150, // 1538 -> MEDIUM_UNAVAILABLE_WEB_RTC_NO_INTERNET 39, // 2000 -> CLIENT_WIFI_DIRECT_ALREADY_HOSTING_DIRECT_GROUP_FOR_THIS_CLIENT 40, // 2001 -> CLIENT_WIFI_HOTSPOT_ALREADY_HOSTING_HOTSPOT_FOR_THIS_CLIENT 24, // 2002 -> CLIENT_DUPLICATE_ACCEPTING_BLE_CONNECTION_REQUEST @@ -2322,181 +2332,183 @@ static const int OperationResultDetail_entries_by_number[] = { 37, // 2014 -> CLIENT_DUPLICATE_WIFI_HOTSPOT_CONNECTION_REQUEST 35, // 2015 -> CLIENT_DUPLICATE_WIFI_AWARE_SUBSCRIBING_REQUEST 38, // 2016 -> CLIENT_UNSUPPORTED_USB_TO_BE_UPGRADE_MEDIUM - 159, // 2500 -> MISCELLEANEOUS_BLUETOOTH_MAC_ADDRESS_NULL - 163, // 2501 -> MISCELLEANEOUS_MOVE_TO_NEW_MEDIUM - 168, // 2502 -> MISCELLEANEOUS_WIFI_HOTSPOT_SOFT_AP_BLOCKED_BY_PROVISION - 158, // 2503 -> MISCELLEANEOUS_BLE_SYSTEM_SERVICE_NULL - 162, // 2504 -> MISCELLEANEOUS_L2CAP_SYSTEM_SERVICE_NULL - 161, // 2505 -> MISCELLEANEOUS_BT_SYSTEM_SERVICE_NULL - 166, // 2506 -> MISCELLEANEOUS_WIFI_AWARE_SYSTEM_SERVICE_NULL - 167, // 2507 -> MISCELLEANEOUS_WIFI_DIRECT_SYSTEM_SERVICE_NULL - 170, // 2508 -> MISCELLEANEOUS_WIFI_LAN_SYSTEM_SERVICE_NULL - 169, // 2509 -> MISCELLEANEOUS_WIFI_HOTSPOT_SYSTEM_SERVICE_NULL - 160, // 2510 -> MISCELLEANEOUS_BT_NOT_ACCEPTING_CONNECTION_FOR_WORK_PROFILE - 164, // 2511 -> MISCELLEANEOUS_WEB_RTC_GET_DROIDGUARD_RESULT_FAILURE - 165, // 2512 -> MISCELLEANEOUS_WEB_RTC_TACHYON_SIGNALING_MESSENGER_NULL - 114, // 3000 -> IO_FILE_OPENING_ERROR - 115, // 3001 -> IO_FILE_READING_ERROR - 116, // 3002 -> IO_FILE_WRITING_ERROR - 117, // 3003 -> IO_FOLDER_CREATION_ERROR - 118, // 3004 -> IO_STREAM_CREATE_PIPE_FAILURE - 104, // 3005 -> IO_ENDPOINT_IO_ERROR_ON_BLE - 106, // 3006 -> IO_ENDPOINT_IO_ERROR_ON_L2CAP - 105, // 3007 -> IO_ENDPOINT_IO_ERROR_ON_BT - 110, // 3008 -> IO_ENDPOINT_IO_ERROR_ON_WEB_RTC - 107, // 3009 -> IO_ENDPOINT_IO_ERROR_ON_LAN - 112, // 3010 -> IO_ENDPOINT_IO_ERROR_ON_WIFI_DIRECT - 113, // 3011 -> IO_ENDPOINT_IO_ERROR_ON_WIFI_HOTSPOT - 111, // 3012 -> IO_ENDPOINT_IO_ERROR_ON_WIFI_AWARE - 108, // 3013 -> IO_ENDPOINT_IO_ERROR_ON_NFC - 109, // 3014 -> IO_ENDPOINT_IO_ERROR_ON_USB - 69, // 3500 -> CONNECTIVITY_WIFI_AWARE_ATTACH_FAILURE + 161, // 2500 -> MISCELLEANEOUS_BLUETOOTH_MAC_ADDRESS_NULL + 165, // 2501 -> MISCELLEANEOUS_MOVE_TO_NEW_MEDIUM + 170, // 2502 -> MISCELLEANEOUS_WIFI_HOTSPOT_SOFT_AP_BLOCKED_BY_PROVISION + 160, // 2503 -> MISCELLEANEOUS_BLE_SYSTEM_SERVICE_NULL + 164, // 2504 -> MISCELLEANEOUS_L2CAP_SYSTEM_SERVICE_NULL + 163, // 2505 -> MISCELLEANEOUS_BT_SYSTEM_SERVICE_NULL + 168, // 2506 -> MISCELLEANEOUS_WIFI_AWARE_SYSTEM_SERVICE_NULL + 169, // 2507 -> MISCELLEANEOUS_WIFI_DIRECT_SYSTEM_SERVICE_NULL + 172, // 2508 -> MISCELLEANEOUS_WIFI_LAN_SYSTEM_SERVICE_NULL + 171, // 2509 -> MISCELLEANEOUS_WIFI_HOTSPOT_SYSTEM_SERVICE_NULL + 162, // 2510 -> MISCELLEANEOUS_BT_NOT_ACCEPTING_CONNECTION_FOR_WORK_PROFILE + 166, // 2511 -> MISCELLEANEOUS_WEB_RTC_GET_DROIDGUARD_RESULT_FAILURE + 167, // 2512 -> MISCELLEANEOUS_WEB_RTC_TACHYON_SIGNALING_MESSENGER_NULL + 116, // 3000 -> IO_FILE_OPENING_ERROR + 117, // 3001 -> IO_FILE_READING_ERROR + 118, // 3002 -> IO_FILE_WRITING_ERROR + 119, // 3003 -> IO_FOLDER_CREATION_ERROR + 120, // 3004 -> IO_STREAM_CREATE_PIPE_FAILURE + 106, // 3005 -> IO_ENDPOINT_IO_ERROR_ON_BLE + 107, // 3006 -> IO_ENDPOINT_IO_ERROR_ON_BLE_L2CAP + 108, // 3007 -> IO_ENDPOINT_IO_ERROR_ON_BT + 112, // 3008 -> IO_ENDPOINT_IO_ERROR_ON_WEB_RTC + 109, // 3009 -> IO_ENDPOINT_IO_ERROR_ON_LAN + 114, // 3010 -> IO_ENDPOINT_IO_ERROR_ON_WIFI_DIRECT + 115, // 3011 -> IO_ENDPOINT_IO_ERROR_ON_WIFI_HOTSPOT + 113, // 3012 -> IO_ENDPOINT_IO_ERROR_ON_WIFI_AWARE + 110, // 3013 -> IO_ENDPOINT_IO_ERROR_ON_NFC + 111, // 3014 -> IO_ENDPOINT_IO_ERROR_ON_USB + 71, // 3500 -> CONNECTIVITY_WIFI_AWARE_ATTACH_FAILURE 44, // 3501 -> CONNECTIVITY_BLUETOOTH_DEVICE_OBTAIN_FAILURE 41, // 3502 -> CONNECTIVITY_BLE_CLIENT_SOCKET_CREATION_FAILURE 54, // 3503 -> CONNECTIVITY_L2CAP_CLIENT_SOCKET_CREATION_FAILURE 46, // 3504 -> CONNECTIVITY_BT_CLIENT_SOCKET_CREATION_FAILURE - 58, // 3505 -> CONNECTIVITY_LAN_CLIENT_SOCKET_CREATION_FAILURE - 62, // 3506 -> CONNECTIVITY_NFC_CLIENT_SOCKET_CREATION_FAILURE - 65, // 3507 -> CONNECTIVITY_WEB_RTC_CLIENT_SOCKET_CREATION_FAILURE - 70, // 3508 -> CONNECTIVITY_WIFI_AWARE_CLIENT_SOCKET_CREATION_FAILURE - 86, // 3509 -> CONNECTIVITY_WIFI_HOTSPOT_CLIENT_SOCKET_CREATION_FAILURE - 79, // 3510 -> CONNECTIVITY_WIFI_DIRECT_CLIENT_SOCKET_CREATION_FAILURE - 64, // 3511 -> CONNECTIVITY_USB_CLIENT_SOCKET_CREATION_FAILURE - 66, // 3512 -> CONNECTIVITY_WEB_RTC_CONNECT_TO_TACHYON_FAILURE + 59, // 3505 -> CONNECTIVITY_LAN_CLIENT_SOCKET_CREATION_FAILURE + 63, // 3506 -> CONNECTIVITY_NFC_CLIENT_SOCKET_CREATION_FAILURE + 66, // 3507 -> CONNECTIVITY_WEB_RTC_CLIENT_SOCKET_CREATION_FAILURE + 72, // 3508 -> CONNECTIVITY_WIFI_AWARE_CLIENT_SOCKET_CREATION_FAILURE + 88, // 3509 -> CONNECTIVITY_WIFI_HOTSPOT_CLIENT_SOCKET_CREATION_FAILURE + 81, // 3510 -> CONNECTIVITY_WIFI_DIRECT_CLIENT_SOCKET_CREATION_FAILURE + 65, // 3511 -> CONNECTIVITY_USB_CLIENT_SOCKET_CREATION_FAILURE + 67, // 3512 -> CONNECTIVITY_WEB_RTC_CONNECT_TO_TACHYON_FAILURE 42, // 3513 -> CONNECTIVITY_BLE_CREATE_GATT_CONNECTION_FAILURE - 73, // 3514 -> CONNECTIVITY_WIFI_AWARE_GET_REMOTE_IP_FRAME_FAILURE - 72, // 3515 -> CONNECTIVITY_WIFI_AWARE_GET_REMOTE_IP_ADDRESS_FAILURE - 81, // 3516 -> CONNECTIVITY_WIFI_DIRECT_INCONSISTENT_HOSTED_WIFI_BAND - 88, // 3517 -> CONNECTIVITY_WIFI_HOTSPOT_INCONSISTENT_HOSTED_WIFI_BAND + 75, // 3514 -> CONNECTIVITY_WIFI_AWARE_GET_REMOTE_IP_FRAME_FAILURE + 74, // 3515 -> CONNECTIVITY_WIFI_AWARE_GET_REMOTE_IP_ADDRESS_FAILURE + 83, // 3516 -> CONNECTIVITY_WIFI_DIRECT_INCONSISTENT_HOSTED_WIFI_BAND + 90, // 3517 -> CONNECTIVITY_WIFI_HOTSPOT_INCONSISTENT_HOSTED_WIFI_BAND 45, // 3518 -> CONNECTIVITY_BLUETOOTH_INVALID_CREDENTIAL - 95, // 3519 -> CONNECTIVITY_WIFI_LAN_INVALID_CREDENTIAL - 82, // 3520 -> CONNECTIVITY_WIFI_DIRECT_INVALID_CREDENTIAL - 89, // 3521 -> CONNECTIVITY_WIFI_HOTSPOT_INVALID_CREDENTIAL - 74, // 3522 -> CONNECTIVITY_WIFI_AWARE_INVALID_CREDENTIAL - 67, // 3523 -> CONNECTIVITY_WEB_RTC_INVALID_CREDENTIAL - 96, // 3524 -> CONNECTIVITY_WIFI_LAN_IP_ADDRESS_ERROR + 97, // 3519 -> CONNECTIVITY_WIFI_LAN_INVALID_CREDENTIAL + 84, // 3520 -> CONNECTIVITY_WIFI_DIRECT_INVALID_CREDENTIAL + 91, // 3521 -> CONNECTIVITY_WIFI_HOTSPOT_INVALID_CREDENTIAL + 76, // 3522 -> CONNECTIVITY_WIFI_AWARE_INVALID_CREDENTIAL + 68, // 3523 -> CONNECTIVITY_WEB_RTC_INVALID_CREDENTIAL + 98, // 3524 -> CONNECTIVITY_WIFI_LAN_IP_ADDRESS_ERROR 53, // 3525 -> CONNECTIVITY_L2CAP_CLIENT_OBTAIN_FAIURE - 55, // 3526 -> CONNECTIVITY_L2CAP_DATA_CONNECTION_FAILURE - 75, // 3527 -> CONNECTIVITY_WIFI_AWARE_L2MESSAGE_NETWORK_AVAILABLE_FRAME_NULL - 76, // 3528 -> CONNECTIVITY_WIFI_AWARE_L2MESSAGE_SEND_HOST_NETWORK_FRAME_FAILURE - 61, // 3529 -> CONNECTIVITY_LAN_UNREACHABLE - 90, // 3530 -> CONNECTIVITY_WIFI_HOTSPOT_LOHS_CREATION_FAILURE - 59, // 3531 -> CONNECTIVITY_LAN_GET_NETWORK_INTERFACES_FAILURE - 80, // 3532 -> CONNECTIVITY_WIFI_DIRECT_GET_NETWORK_INTERFACES_FAILURE - 87, // 3533 -> CONNECTIVITY_WIFI_HOTSPOT_GET_NETWORK_INTERFACES_FAILURE - 91, // 3534 -> CONNECTIVITY_WIFI_HOTSPOT_P2P_CHANNEL_INITIALIZE_FAILURE - 83, // 3535 -> CONNECTIVITY_WIFI_DIRECT_P2P_CHANNEL_INITIALIZE_FAILURE - 92, // 3536 -> CONNECTIVITY_WIFI_HOTSPOT_P2P_GROUP_CREATION_FAILURE - 84, // 3537 -> CONNECTIVITY_WIFI_DIRECT_P2P_GROUP_CREATION_FAILURE + 56, // 3526 -> CONNECTIVITY_L2CAP_DATA_CONNECTION_FAILURE + 77, // 3527 -> CONNECTIVITY_WIFI_AWARE_L2MESSAGE_NETWORK_AVAILABLE_FRAME_NULL + 78, // 3528 -> CONNECTIVITY_WIFI_AWARE_L2MESSAGE_SEND_HOST_NETWORK_FRAME_FAILURE + 62, // 3529 -> CONNECTIVITY_LAN_UNREACHABLE + 92, // 3530 -> CONNECTIVITY_WIFI_HOTSPOT_LOHS_CREATION_FAILURE + 60, // 3531 -> CONNECTIVITY_LAN_GET_NETWORK_INTERFACES_FAILURE + 82, // 3532 -> CONNECTIVITY_WIFI_DIRECT_GET_NETWORK_INTERFACES_FAILURE + 89, // 3533 -> CONNECTIVITY_WIFI_HOTSPOT_GET_NETWORK_INTERFACES_FAILURE + 93, // 3534 -> CONNECTIVITY_WIFI_HOTSPOT_P2P_CHANNEL_INITIALIZE_FAILURE + 85, // 3535 -> CONNECTIVITY_WIFI_DIRECT_P2P_CHANNEL_INITIALIZE_FAILURE + 94, // 3536 -> CONNECTIVITY_WIFI_HOTSPOT_P2P_GROUP_CREATION_FAILURE + 86, // 3537 -> CONNECTIVITY_WIFI_DIRECT_P2P_GROUP_CREATION_FAILURE 49, // 3538 -> CONNECTIVITY_GATT_SERVER_OPEN_FAILURE 43, // 3539 -> CONNECTIVITY_BLE_SERVER_SOCKET_CREATION_FAILURE - 56, // 3540 -> CONNECTIVITY_L2CAP_SERVER_SOCKET_CREATION_FAILURE + 57, // 3540 -> CONNECTIVITY_L2CAP_SERVER_SOCKET_CREATION_FAILURE 47, // 3541 -> CONNECTIVITY_BT_SERVER_SOCKET_CREATION_FAILURE - 60, // 3542 -> CONNECTIVITY_LAN_SERVER_SOCKET_CREATION_FAILURE - 68, // 3543 -> CONNECTIVITY_WEB_RTC_SERVER_SOCKET_CREATION_FAILURE - 77, // 3544 -> CONNECTIVITY_WIFI_AWARE_SERVER_SOCKET_CREATION_FAILURE - 93, // 3545 -> CONNECTIVITY_WIFI_HOTSPOT_SERVER_SOCKET_CREATION_FAILURE - 85, // 3546 -> CONNECTIVITY_WIFI_DIRECT_SERVER_SOCKET_CREATION_FAILURE - 63, // 3547 -> CONNECTIVITY_NFC_SERVER_SOCKET_CREATION_FAILURE - 94, // 3548 -> CONNECTIVITY_WIFI_HOTSPOT_SOFT_AP_CREATION_FAILURE - 78, // 3549 -> CONNECTIVITY_WIFI_AWARE_UPDATE_PUBLISH_FAILURE + 61, // 3542 -> CONNECTIVITY_LAN_SERVER_SOCKET_CREATION_FAILURE + 69, // 3543 -> CONNECTIVITY_WEB_RTC_SERVER_SOCKET_CREATION_FAILURE + 79, // 3544 -> CONNECTIVITY_WIFI_AWARE_SERVER_SOCKET_CREATION_FAILURE + 95, // 3545 -> CONNECTIVITY_WIFI_HOTSPOT_SERVER_SOCKET_CREATION_FAILURE + 87, // 3546 -> CONNECTIVITY_WIFI_DIRECT_SERVER_SOCKET_CREATION_FAILURE + 64, // 3547 -> CONNECTIVITY_NFC_SERVER_SOCKET_CREATION_FAILURE + 96, // 3548 -> CONNECTIVITY_WIFI_HOTSPOT_SOFT_AP_CREATION_FAILURE + 80, // 3549 -> CONNECTIVITY_WIFI_AWARE_UPDATE_PUBLISH_FAILURE 52, // 3550 -> CONNECTIVITY_GENERIC_WRITING_CHANNEL_IO_ERROR 51, // 3551 -> CONNECTIVITY_GENERIC_WRITE_CLIENT_INTRODUCTION_ACK_IO_ERROR - 71, // 3552 -> CONNECTIVITY_WIFI_AWARE_DISCOVERED_PEER_NULL + 73, // 3552 -> CONNECTIVITY_WIFI_AWARE_DISCOVERED_PEER_NULL 50, // 3553 -> CONNECTIVITY_GENERIC_PAYLOAD_SENT_ERROR - 57, // 3554 -> CONNECTIVITY_L2CAP_SERVER_SOCKET_CREATION_SECURITY_EXCEPTION_FAILURE + 58, // 3554 -> CONNECTIVITY_L2CAP_SERVER_SOCKET_CREATION_SECURITY_EXCEPTION_FAILURE 48, // 3555 -> CONNECTIVITY_BT_SERVER_SOCKET_CREATION_SECURITY_EXCEPTION_FAILURE - 171, // 4500 -> NEARBY_BLE_ADVERTISEMENT_MAPPING_TO_MAC_ERROR - 176, // 4501 -> NEARBY_BLUETOOTH_MAC_ADDRESS_INVALID_FOR_CONNECT - 211, // 4502 -> NEARBY_WEB_RTC_CONNECTION_FLOW_NULL - 182, // 4503 -> NEARBY_GENERIC_CONNECTION_CLOSED - 172, // 4504 -> NEARBY_BLE_ENDPOINT_CHANNEL_CREATION_FAILURE - 198, // 4505 -> NEARBY_L2CAP_ENDPOINT_CHANNEL_CREATION_FAILURE - 177, // 4506 -> NEARBY_BT_ENDPOINT_CHANNEL_CREATION_FAILURE - 202, // 4507 -> NEARBY_LAN_ENDPOINT_CHANNEL_CREATION_FAILURE - 207, // 4508 -> NEARBY_NFC_ENDPOINT_CHANNEL_CREATION_FAILURE - 215, // 4509 -> NEARBY_WIFI_AWARE_ENDPOINT_CHANNEL_CREATION_FAILURE - 229, // 4510 -> NEARBY_WIFI_HOTSPOT_ENDPOINT_CHANNEL_CREATION_FAILURE - 218, // 4511 -> NEARBY_WIFI_DIRECT_ENDPOINT_CHANNEL_CREATION_FAILURE - 212, // 4512 -> NEARBY_WEB_RTC_ENDPOINT_CHANNEL_CREATION_FAILURE - 209, // 4513 -> NEARBY_USB_ENDPOINT_CHANNEL_CREATION_FAILURE - 183, // 4514 -> NEARBY_GENERIC_ENDPOINT_UNENCRYPTED - 173, // 4515 -> NEARBY_BLE_GATT_ADVERTISEMENT_NULL_FOR_CONNECTION - 219, // 4516 -> NEARBY_WIFI_DIRECT_HOST_ON_SRD_CHANNELS - 230, // 4517 -> NEARBY_WIFI_HOTSPOT_HOST_ON_SRD_CHANNELS - 174, // 4518 -> NEARBY_BLE_GATT_NULL_CALLBACK - 199, // 4519 -> NEARBY_L2CAP_NULL_CALLBACK - 179, // 4520 -> NEARBY_BT_NULL_CALLBACK - 210, // 4521 -> NEARBY_USB_NULL_CALLBACK - 208, // 4522 -> NEARBY_NFC_NULL_CALLBACK - 216, // 4523 -> NEARBY_WIFI_AWARE_NULL_CALLBACK - 213, // 4524 -> NEARBY_WEB_RTC_NULL_CALLBACK - 204, // 4525 -> NEARBY_LAN_NULL_CALLBACK - 233, // 4526 -> NEARBY_WIFI_HOTSPOT_NULL_CALLBACK - 221, // 4527 -> NEARBY_WIFI_DIRECT_NULL_CALLBACK - 223, // 4528 -> NEARBY_WIFI_DIRECT_NULL_SSID - 222, // 4529 -> NEARBY_WIFI_DIRECT_NULL_PASSWORD - 178, // 4530 -> NEARBY_BT_MULTIPLEX_SOCKET_DISABLED - 203, // 4531 -> NEARBY_LAN_MULTIPLEX_SOCKET_DISABLED - 185, // 4532 -> NEARBY_GENERIC_NEW_ENDPOINT_CHANNEL_NULL - 220, // 4533 -> NEARBY_WIFI_DIRECT_NO_GROUP_FOR_LISTENING - 232, // 4534 -> NEARBY_WIFI_HOTSPOT_NO_HOTSPOT_FOR_LISTENING - 186, // 4535 -> NEARBY_GENERIC_OLD_ENDPOINT_CHANNEL_NULL - 175, // 4536 -> NEARBY_BLE_OPERATION_REGISTERED_FAILED - 200, // 4537 -> NEARBY_L2CAP_OPERATION_REGISTERED_FAILED - 180, // 4538 -> NEARBY_BT_OPERATION_REGISTERED_FAILED - 205, // 4539 -> NEARBY_LAN_OPERATION_REGISTERED_FAILED - 214, // 4540 -> NEARBY_WEB_RTC_OPERATION_REGISTERED_FAILED - 217, // 4541 -> NEARBY_WIFI_AWARE_OPERATION_REGISTERED_FAILED - 228, // 4542 -> NEARBY_WIFI_HOTSPOT_DIRECT_OPERATION_REGISTERED_FAILED - 236, // 4543 -> NEARBY_WIFI_HOTSPOT_SOFT_AP_OPERATION_REGISTERED_FAILED - 231, // 4544 -> NEARBY_WIFI_HOTSPOT_LOHS_OPERATION_REGISTERED_FAILED - 227, // 4545 -> NEARBY_WIFI_HOTSPOT_CLIENT_OPERATION_REGISTERED_FAILED - 224, // 4546 -> NEARBY_WIFI_DIRECT_OPERATION_REGISTERED_FAILED - 187, // 4547 -> NEARBY_GENERIC_OUTGOING_PAYLOAD_CREATION_FAILURE - 234, // 4548 -> NEARBY_WIFI_HOTSPOT_P2P_NON_DBS_WANT_2G_BUT_AP_5G - 225, // 4549 -> NEARBY_WIFI_DIRECT_P2P_NON_DBS_WANT_2G_BUT_AP_5G - 235, // 4550 -> NEARBY_WIFI_HOTSPOT_P2P_NON_DBS_WANT_5G_BUT_AP_2G - 226, // 4551 -> NEARBY_WIFI_DIRECT_P2P_NON_DBS_WANT_5G_BUT_AP_2G - 184, // 4552 -> NEARBY_GENERIC_INCOMING_PAYLOAD_NOT_DATA_TYPE - 191, // 4553 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_EVENT_TYPE_ERROR - 193, // 4554 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_FRAME_TYPE_ERROR - 192, // 4555 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_FORMAT_ERROR - 188, // 4556 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_ACK_EVENT_TYPE_ERROR - 190, // 4557 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_ACK_FRAME_TYPE_ERROR - 189, // 4558 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_ACK_FORMAT_ERROR - 194, // 4559 -> NEARBY_GENERIC_REMOTE_ENDPOINT_STATUS_ERROR - 195, // 4560 -> NEARBY_GENERIC_REMOTE_REPORT_PAYLOADS_ERROR - 196, // 4561 -> NEARBY_GENERIC_REMOTE_UPGRADE_FAILURE - 197, // 4562 -> NEARBY_GENERIC_SEND_PAYLOAD_EXECUTOR_NULL - 181, // 4563 -> NEARBY_BT_VIRTUAL_SOCKET_CREATION_FAILURE - 206, // 4564 -> NEARBY_LAN_VIRTUAL_SOCKET_CREATION_FAILURE - 237, // 4565 -> NEARBY_WIFI_LAN_IP_ADDRESS_ERROR - 201, // 4566 -> NEARBY_L2CAP_PSM_NOT_POSITIVE + 55, // 3556 -> CONNECTIVITY_L2CAP_CLIENT_SOCKET_CREATION_TIMEOUT_FAILURE + 70, // 3557 -> CONNECTIVITY_WEB_RTC_UNSATISFIED_LINK_ERROR + 173, // 4500 -> NEARBY_BLE_ADVERTISEMENT_MAPPING_TO_MAC_ERROR + 178, // 4501 -> NEARBY_BLUETOOTH_MAC_ADDRESS_INVALID_FOR_CONNECT + 213, // 4502 -> NEARBY_WEB_RTC_CONNECTION_FLOW_NULL + 184, // 4503 -> NEARBY_GENERIC_CONNECTION_CLOSED + 174, // 4504 -> NEARBY_BLE_ENDPOINT_CHANNEL_CREATION_FAILURE + 200, // 4505 -> NEARBY_L2CAP_ENDPOINT_CHANNEL_CREATION_FAILURE + 179, // 4506 -> NEARBY_BT_ENDPOINT_CHANNEL_CREATION_FAILURE + 204, // 4507 -> NEARBY_LAN_ENDPOINT_CHANNEL_CREATION_FAILURE + 209, // 4508 -> NEARBY_NFC_ENDPOINT_CHANNEL_CREATION_FAILURE + 217, // 4509 -> NEARBY_WIFI_AWARE_ENDPOINT_CHANNEL_CREATION_FAILURE + 231, // 4510 -> NEARBY_WIFI_HOTSPOT_ENDPOINT_CHANNEL_CREATION_FAILURE + 220, // 4511 -> NEARBY_WIFI_DIRECT_ENDPOINT_CHANNEL_CREATION_FAILURE + 214, // 4512 -> NEARBY_WEB_RTC_ENDPOINT_CHANNEL_CREATION_FAILURE + 211, // 4513 -> NEARBY_USB_ENDPOINT_CHANNEL_CREATION_FAILURE + 185, // 4514 -> NEARBY_GENERIC_ENDPOINT_UNENCRYPTED + 175, // 4515 -> NEARBY_BLE_GATT_ADVERTISEMENT_NULL_FOR_CONNECTION + 221, // 4516 -> NEARBY_WIFI_DIRECT_HOST_ON_SRD_CHANNELS + 232, // 4517 -> NEARBY_WIFI_HOTSPOT_HOST_ON_SRD_CHANNELS + 176, // 4518 -> NEARBY_BLE_GATT_NULL_CALLBACK + 201, // 4519 -> NEARBY_L2CAP_NULL_CALLBACK + 181, // 4520 -> NEARBY_BT_NULL_CALLBACK + 212, // 4521 -> NEARBY_USB_NULL_CALLBACK + 210, // 4522 -> NEARBY_NFC_NULL_CALLBACK + 218, // 4523 -> NEARBY_WIFI_AWARE_NULL_CALLBACK + 215, // 4524 -> NEARBY_WEB_RTC_NULL_CALLBACK + 206, // 4525 -> NEARBY_LAN_NULL_CALLBACK + 235, // 4526 -> NEARBY_WIFI_HOTSPOT_NULL_CALLBACK + 223, // 4527 -> NEARBY_WIFI_DIRECT_NULL_CALLBACK + 225, // 4528 -> NEARBY_WIFI_DIRECT_NULL_SSID + 224, // 4529 -> NEARBY_WIFI_DIRECT_NULL_PASSWORD + 180, // 4530 -> NEARBY_BT_MULTIPLEX_SOCKET_DISABLED + 205, // 4531 -> NEARBY_LAN_MULTIPLEX_SOCKET_DISABLED + 187, // 4532 -> NEARBY_GENERIC_NEW_ENDPOINT_CHANNEL_NULL + 222, // 4533 -> NEARBY_WIFI_DIRECT_NO_GROUP_FOR_LISTENING + 234, // 4534 -> NEARBY_WIFI_HOTSPOT_NO_HOTSPOT_FOR_LISTENING + 188, // 4535 -> NEARBY_GENERIC_OLD_ENDPOINT_CHANNEL_NULL + 177, // 4536 -> NEARBY_BLE_OPERATION_REGISTERED_FAILED + 202, // 4537 -> NEARBY_L2CAP_OPERATION_REGISTERED_FAILED + 182, // 4538 -> NEARBY_BT_OPERATION_REGISTERED_FAILED + 207, // 4539 -> NEARBY_LAN_OPERATION_REGISTERED_FAILED + 216, // 4540 -> NEARBY_WEB_RTC_OPERATION_REGISTERED_FAILED + 219, // 4541 -> NEARBY_WIFI_AWARE_OPERATION_REGISTERED_FAILED + 230, // 4542 -> NEARBY_WIFI_HOTSPOT_DIRECT_OPERATION_REGISTERED_FAILED + 238, // 4543 -> NEARBY_WIFI_HOTSPOT_SOFT_AP_OPERATION_REGISTERED_FAILED + 233, // 4544 -> NEARBY_WIFI_HOTSPOT_LOHS_OPERATION_REGISTERED_FAILED + 229, // 4545 -> NEARBY_WIFI_HOTSPOT_CLIENT_OPERATION_REGISTERED_FAILED + 226, // 4546 -> NEARBY_WIFI_DIRECT_OPERATION_REGISTERED_FAILED + 189, // 4547 -> NEARBY_GENERIC_OUTGOING_PAYLOAD_CREATION_FAILURE + 236, // 4548 -> NEARBY_WIFI_HOTSPOT_P2P_NON_DBS_WANT_2G_BUT_AP_5G + 227, // 4549 -> NEARBY_WIFI_DIRECT_P2P_NON_DBS_WANT_2G_BUT_AP_5G + 237, // 4550 -> NEARBY_WIFI_HOTSPOT_P2P_NON_DBS_WANT_5G_BUT_AP_2G + 228, // 4551 -> NEARBY_WIFI_DIRECT_P2P_NON_DBS_WANT_5G_BUT_AP_2G + 186, // 4552 -> NEARBY_GENERIC_INCOMING_PAYLOAD_NOT_DATA_TYPE + 193, // 4553 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_EVENT_TYPE_ERROR + 195, // 4554 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_FRAME_TYPE_ERROR + 194, // 4555 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_FORMAT_ERROR + 190, // 4556 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_ACK_EVENT_TYPE_ERROR + 192, // 4557 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_ACK_FRAME_TYPE_ERROR + 191, // 4558 -> NEARBY_GENERIC_READ_CLIENT_INTRODUCTION_ACK_FORMAT_ERROR + 196, // 4559 -> NEARBY_GENERIC_REMOTE_ENDPOINT_STATUS_ERROR + 197, // 4560 -> NEARBY_GENERIC_REMOTE_REPORT_PAYLOADS_ERROR + 198, // 4561 -> NEARBY_GENERIC_REMOTE_UPGRADE_FAILURE + 199, // 4562 -> NEARBY_GENERIC_SEND_PAYLOAD_EXECUTOR_NULL + 183, // 4563 -> NEARBY_BT_VIRTUAL_SOCKET_CREATION_FAILURE + 208, // 4564 -> NEARBY_LAN_VIRTUAL_SOCKET_CREATION_FAILURE + 239, // 4565 -> NEARBY_WIFI_LAN_IP_ADDRESS_ERROR + 203, // 4566 -> NEARBY_L2CAP_PSM_NOT_POSITIVE }; -const std::string& OperationResultDetail_Name( - OperationResultDetail value) { +const std::string& OperationResultCode_Name( + OperationResultCode value) { static const bool dummy = ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - OperationResultDetail_entries, - OperationResultDetail_entries_by_number, - 238, OperationResultDetail_strings); + OperationResultCode_entries, + OperationResultCode_entries_by_number, + 240, OperationResultCode_strings); (void) dummy; int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - OperationResultDetail_entries, - OperationResultDetail_entries_by_number, - 238, value); + OperationResultCode_entries, + OperationResultCode_entries_by_number, + 240, value); return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - OperationResultDetail_strings[idx].get(); + OperationResultCode_strings[idx].get(); } -bool OperationResultDetail_Parse( - ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, OperationResultDetail* value) { +bool OperationResultCode_Parse( + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, OperationResultCode* value) { int int_value; bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - OperationResultDetail_entries, 238, name, &int_value); + OperationResultCode_entries, 240, name, &int_value); if (success) { - *value = static_cast(int_value); + *value = static_cast(int_value); } return success; } diff --git a/compiled_proto/proto/connections_enums.pb.h b/compiled_proto/proto/connections_enums.pb.h index c7023f89..8a173350 100644 --- a/compiled_proto/proto/connections_enums.pb.h +++ b/compiled_proto/proto/connections_enums.pb.h @@ -299,11 +299,12 @@ enum DisconnectionReason : int { UPGRADED = 4, SHUTDOWN = 5, UNFINISHED = 6, - PREV_CHANNEL_DISCONNECTION_IN_RECONNECT = 7 + PREV_CHANNEL_DISCONNECTION_IN_RECONNECT = 7, + AUTHENTICATION_FAILURE = 8 }; bool DisconnectionReason_IsValid(int value); constexpr DisconnectionReason DisconnectionReason_MIN = UNKNOWN_DISCONNECTION_REASON; -constexpr DisconnectionReason DisconnectionReason_MAX = PREV_CHANNEL_DISCONNECTION_IN_RECONNECT; +constexpr DisconnectionReason DisconnectionReason_MAX = AUTHENTICATION_FAILURE; constexpr int DisconnectionReason_ARRAYSIZE = DisconnectionReason_MAX + 1; const std::string& DisconnectionReason_Name(DisconnectionReason value); @@ -546,7 +547,7 @@ inline const std::string& OperationResultCategory_Name(T enum_t_value) { } bool OperationResultCategory_Parse( ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, OperationResultCategory* value); -enum OperationResultDetail : int { +enum OperationResultCode : int { DETAIL_UNKNOWN = 0, DETAIL_SUCCESS = 1, CLIENT_CANCELLATION_REMOTE_IN_CANCELED_STATE = 500, @@ -653,7 +654,7 @@ enum OperationResultDetail : int { IO_FOLDER_CREATION_ERROR = 3003, IO_STREAM_CREATE_PIPE_FAILURE = 3004, IO_ENDPOINT_IO_ERROR_ON_BLE = 3005, - IO_ENDPOINT_IO_ERROR_ON_L2CAP = 3006, + IO_ENDPOINT_IO_ERROR_ON_BLE_L2CAP = 3006, IO_ENDPOINT_IO_ERROR_ON_BT = 3007, IO_ENDPOINT_IO_ERROR_ON_WEB_RTC = 3008, IO_ENDPOINT_IO_ERROR_ON_LAN = 3009, @@ -718,6 +719,8 @@ enum OperationResultDetail : int { CONNECTIVITY_GENERIC_PAYLOAD_SENT_ERROR = 3553, CONNECTIVITY_L2CAP_SERVER_SOCKET_CREATION_SECURITY_EXCEPTION_FAILURE = 3554, CONNECTIVITY_BT_SERVER_SOCKET_CREATION_SECURITY_EXCEPTION_FAILURE = 3555, + CONNECTIVITY_L2CAP_CLIENT_SOCKET_CREATION_TIMEOUT_FAILURE = 3556, + CONNECTIVITY_WEB_RTC_UNSATISFIED_LINK_ERROR = 3557, NEARBY_BLE_ADVERTISEMENT_MAPPING_TO_MAC_ERROR = 4500, NEARBY_BLUETOOTH_MAC_ADDRESS_INVALID_FOR_CONNECT = 4501, NEARBY_WEB_RTC_CONNECTION_FLOW_NULL = 4502, @@ -786,21 +789,21 @@ enum OperationResultDetail : int { NEARBY_WIFI_LAN_IP_ADDRESS_ERROR = 4565, NEARBY_L2CAP_PSM_NOT_POSITIVE = 4566 }; -bool OperationResultDetail_IsValid(int value); -constexpr OperationResultDetail OperationResultDetail_MIN = DETAIL_UNKNOWN; -constexpr OperationResultDetail OperationResultDetail_MAX = NEARBY_L2CAP_PSM_NOT_POSITIVE; -constexpr int OperationResultDetail_ARRAYSIZE = OperationResultDetail_MAX + 1; +bool OperationResultCode_IsValid(int value); +constexpr OperationResultCode OperationResultCode_MIN = DETAIL_UNKNOWN; +constexpr OperationResultCode OperationResultCode_MAX = NEARBY_L2CAP_PSM_NOT_POSITIVE; +constexpr int OperationResultCode_ARRAYSIZE = OperationResultCode_MAX + 1; -const std::string& OperationResultDetail_Name(OperationResultDetail value); +const std::string& OperationResultCode_Name(OperationResultCode value); template -inline const std::string& OperationResultDetail_Name(T enum_t_value) { - static_assert(::std::is_same::value || +inline const std::string& OperationResultCode_Name(T enum_t_value) { + static_assert(::std::is_same::value || ::std::is_integral::value, - "Incorrect type passed to function OperationResultDetail_Name."); - return OperationResultDetail_Name(static_cast(enum_t_value)); + "Incorrect type passed to function OperationResultCode_Name."); + return OperationResultCode_Name(static_cast(enum_t_value)); } -bool OperationResultDetail_Parse( - ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, OperationResultDetail* value); +bool OperationResultCode_Parse( + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, OperationResultCode* value); // =================================================================== @@ -845,7 +848,7 @@ template <> struct is_proto_enum< ::location::nearby::proto::connections::Bandwi template <> struct is_proto_enum< ::location::nearby::proto::connections::LogSource> : ::std::true_type {}; template <> struct is_proto_enum< ::location::nearby::proto::connections::PowerLevel> : ::std::true_type {}; template <> struct is_proto_enum< ::location::nearby::proto::connections::OperationResultCategory> : ::std::true_type {}; -template <> struct is_proto_enum< ::location::nearby::proto::connections::OperationResultDetail> : ::std::true_type {}; +template <> struct is_proto_enum< ::location::nearby::proto::connections::OperationResultCode> : ::std::true_type {}; PROTOBUF_NAMESPACE_CLOSE From 7f7f097adbb04fd9a6a0f602df8e7b1cd9900c87 Mon Sep 17 00:00:00 2001 From: Anthony Rueda Date: Fri, 5 Jan 2024 11:22:00 -0800 Subject: [PATCH 091/683] [Presence] Deprecate Metadata and remove instances of Metadata from gmscore NP codes. PiperOrigin-RevId: 596041877 --- internal/proto/metadata.proto | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/proto/metadata.proto b/internal/proto/metadata.proto index ec4efbe4..3c9fa89c 100644 --- a/internal/proto/metadata.proto +++ b/internal/proto/metadata.proto @@ -46,7 +46,10 @@ message DeviceIdentityMetaData { // The metadata of a device. // Contains confidential data not to be broadcasted directly in OTA. +// Metadata is deprecated, use DeviceIdentityMetadata instead. message Metadata { + option deprecated = true; + // The type of the device. DeviceType device_type = 1; From 6ae46a94965f26bdbe8fa0613dfe2bb4f63c90dc Mon Sep 17 00:00:00 2001 From: hai007 Date: Fri, 5 Jan 2024 17:25:01 -0800 Subject: [PATCH 092/683] Add visibilities PiperOrigin-RevId: 596118852 --- connections/BUILD | 2 ++ connections/implementation/BUILD | 1 + internal/platform/BUILD | 1 + internal/platform/implementation/windows/BUILD | 1 + 4 files changed, 5 insertions(+) diff --git a/connections/BUILD b/connections/BUILD index a8f9d09d..bbe2b62a 100644 --- a/connections/BUILD +++ b/connections/BUILD @@ -23,6 +23,7 @@ cc_library( ], copts = ["-DCORE_ADAPTER_DLL"], visibility = [ + "//chrome/chromeos/assistant/data_migration/lib:__pkg__", "//connections:__subpackages__", "//location/nearby/cpp/sharing:__subpackages__", "//location/nearby/testing:__subpackages__", @@ -69,6 +70,7 @@ cc_library( ], copts = ["-DCORE_ADAPTER_DLL"], visibility = [ + "//chrome/chromeos/assistant/data_migration/lib:__pkg__", "//connections:__subpackages__", "//location/nearby/cpp/sharing:__subpackages__", "//location/nearby/testing:__subpackages__", diff --git a/connections/implementation/BUILD b/connections/implementation/BUILD index 2564fbf8..4491e930 100644 --- a/connections/implementation/BUILD +++ b/connections/implementation/BUILD @@ -106,6 +106,7 @@ cc_library( "-DNO_WEBRTC", ], visibility = [ + "//chrome/chromeos/assistant/data_migration/lib:__pkg__", "//connections:__pkg__", "//connections/implementation/fuzzers:__pkg__", "//location/nearby/cpp/sharing/implementation:__pkg__", diff --git a/internal/platform/BUILD b/internal/platform/BUILD index 20c15bfd..0e5a61e1 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -46,6 +46,7 @@ cc_library( ], copts = ["-DCORE_ADAPTER_DLL"], visibility = [ + "//chrome/chromeos/assistant/data_migration/lib:__pkg__", "//connections:__subpackages__", "//fastpair:__subpackages__", "//internal/auth:__subpackages__", diff --git a/internal/platform/implementation/windows/BUILD b/internal/platform/implementation/windows/BUILD index 91f25e99..31abb0a9 100644 --- a/internal/platform/implementation/windows/BUILD +++ b/internal/platform/implementation/windows/BUILD @@ -202,6 +202,7 @@ cc_library( ], defines = ["_SILENCE_CLANG_COROUTINE_MESSAGE"], visibility = [ + "//chrome/chromeos/assistant/data_migration/lib:__pkg__", "//connections:__subpackages__", "//fastpair:__subpackages__", "//location/nearby:__subpackages__", From 97a3ceb31156ff9dd2e9bb36bcabd747f3807423 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Mon, 8 Jan 2024 10:06:56 -0800 Subject: [PATCH 093/683] - Remove unused data manager classes. PiperOrigin-RevId: 596628112 --- internal/data/BUILD | 3 - internal/data/data_manager.h | 53 ----------- internal/data/memory_data_set.h | 109 --------------------- internal/data/memory_data_set_test.cc | 71 -------------- internal/test/BUILD | 4 - internal/test/fake_data_set.h | 132 -------------------------- internal/test/fake_data_set_test.cc | 107 --------------------- 7 files changed, 479 deletions(-) delete mode 100644 internal/data/data_manager.h delete mode 100644 internal/data/memory_data_set.h delete mode 100644 internal/data/memory_data_set_test.cc delete mode 100644 internal/test/fake_data_set.h delete mode 100644 internal/test/fake_data_set_test.cc diff --git a/internal/data/BUILD b/internal/data/BUILD index dce7d36c..a8342387 100644 --- a/internal/data/BUILD +++ b/internal/data/BUILD @@ -9,10 +9,8 @@ package(default_visibility = [ cc_library( name = "data_manager", hdrs = [ - "data_manager.h", "data_set.h", "leveldb_data_set.h", - "memory_data_set.h", ], deps = [ "//internal/platform:types", @@ -43,7 +41,6 @@ cc_test( timeout = "short", srcs = [ "leveldb_data_set_test.cc", - "memory_data_set_test.cc", ], shard_count = 8, deps = [ diff --git a/internal/data/data_manager.h b/internal/data/data_manager.h deleted file mode 100644 index 3f42f456..00000000 --- a/internal/data/data_manager.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2022 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 THIRD_PARTY_NEARBY_INTERNAL_DATA_DATA_MANAGER_H_ -#define THIRD_PARTY_NEARBY_INTERNAL_DATA_DATA_MANAGER_H_ - -#include - -#include "absl/strings/string_view.h" -#include "internal/data/data_set.h" -#include "internal/data/leveldb_data_set.h" -#include "internal/data/memory_data_set.h" - -namespace nearby { -namespace data { - -class DataManager { - public: - enum class DataStorageType : int { kMemory = 0, kLevelDb = 1 }; - explicit DataManager(DataStorageType data_storage_type) - : data_storage_type_(data_storage_type) {} - ~DataManager() = default; - - template - std::unique_ptr> GetDataSet(absl::string_view path) { - if (data_storage_type_ == DataStorageType::kMemory) { - return std::make_unique>(path); - } else if (data_storage_type_ == DataStorageType::kLevelDb) { - return std::make_unique>(path); - } else { - return nullptr; - } - } - - private: - DataStorageType data_storage_type_; -}; - -} // namespace data -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_INTERNAL_DATA_DATA_MANAGER_H_ diff --git a/internal/data/memory_data_set.h b/internal/data/memory_data_set.h deleted file mode 100644 index 9cf5fca2..00000000 --- a/internal/data/memory_data_set.h +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2022 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 THIRD_PARTY_NEARBY_INTERNAL_DATA_MEMORY_DATA_SET_H_ -#define THIRD_PARTY_NEARBY_INTERNAL_DATA_MEMORY_DATA_SET_H_ - -#include -#include -#include -#include - -#include "absl/container/flat_hash_map.h" -#include "absl/functional/any_invocable.h" -#include "absl/strings/string_view.h" -#include "absl/synchronization/mutex.h" -#include "internal/data/data_set.h" - -namespace nearby { -namespace data { - -template -class MemoryDataSet : public DataSet { - public: - using KeyEntryVector = std::vector>; - - explicit MemoryDataSet(absl::string_view path) : path_(path) {} - ~MemoryDataSet() override = default; - - void Initialize(absl::AnyInvocable callback) override; - void LoadEntries( - absl::AnyInvocable>) &&> - callback) override; - void UpdateEntries(std::unique_ptr entries_to_save, - std::unique_ptr> keys_to_remove, - absl::AnyInvocable callback) override; - void Destroy(absl::AnyInvocable callback) override; - - private: - std::string path_; - - absl::Mutex mutex_; - absl::flat_hash_map entries_; -}; - -template -void MemoryDataSet::Initialize( - absl::AnyInvocable callback) { - std::move(callback)(InitStatus::kOK); -} - -template -void MemoryDataSet::LoadEntries( - absl::AnyInvocable>) &&> - callback) { - auto result = std::make_unique>(); - auto it = entries_.begin(); - while (it != entries_.end()) { - result->push_back(it->second); - ++it; - } - - std::move(callback)(true, std::move(result)); -} - -template -void MemoryDataSet::UpdateEntries( - std::unique_ptr entries_to_save, - std::unique_ptr> keys_to_remove, - absl::AnyInvocable callback) { - if (entries_to_save != nullptr) { - auto it = entries_to_save->begin(); - while (it != entries_to_save->end()) { - entries_.emplace(it->first, it->second); - ++it; - } - } - - if (keys_to_remove != nullptr) { - auto it = keys_to_remove->begin(); - while (it != keys_to_remove->end()) { - entries_.erase(*it); - ++it; - } - } - - std::move(callback)(true); -} - -template -void MemoryDataSet::Destroy(absl::AnyInvocable callback) { - entries_.clear(); - std::move(callback)(true); -} - -} // namespace data -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_INTERNAL_DATA_MEMORY_DATA_SET_H_ diff --git a/internal/data/memory_data_set_test.cc b/internal/data/memory_data_set_test.cc deleted file mode 100644 index e5e3a13d..00000000 --- a/internal/data/memory_data_set_test.cc +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2022 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 "internal/data/memory_data_set.h" - -#include -#include -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" - -namespace nearby { -namespace data { -namespace { - -TEST(MemoryDataSet, TestUpdateEntries) { - bool result = false; - MemoryDataSet string_set{""}; - - auto temp = MemoryDataSet::KeyEntryVector( - {{"id1", "string1"}, {"id2", "string2"}}); - - auto data = - std::make_unique::KeyEntryVector>(temp); - string_set.UpdateEntries(std::move(data), nullptr, - [&result](bool res) { result = res; }); - EXPECT_TRUE(result); -} - -TEST(MemoryDataSet, TestLoadEntries) { - std::vector result = {}; - MemoryDataSet string_set{""}; - - auto temp = MemoryDataSet::KeyEntryVector( - {{"id1", "string1"}, {"id2", "string2"}}); - auto data = - std::make_unique::KeyEntryVector>(temp); - - string_set.UpdateEntries(std::move(data), nullptr, [](bool ans) {}); - string_set.LoadEntries( - [&result](bool ans, std::unique_ptr> res) { - auto it = res->begin(); - while (it != res->end()) { - result.push_back(*it); - ++it; - } - }); - - EXPECT_THAT(result, testing::SizeIs(2)); - std::sort(result.begin(), result.end()); - EXPECT_EQ(result, std::vector({"string1", "string2"})); -} - -} // namespace -} // namespace data -} // namespace nearby diff --git a/internal/test/BUILD b/internal/test/BUILD index 5d9b2c8f..1bb96584 100644 --- a/internal/test/BUILD +++ b/internal/test/BUILD @@ -27,7 +27,6 @@ cc_library( hdrs = [ "fake_account_manager.h", "fake_clock.h", - "fake_data_set.h", "fake_device_info.h", "fake_http_client.h", "fake_http_client_factory.h", @@ -42,7 +41,6 @@ cc_library( visibility = ["//visibility:public"], deps = [ "//internal/base", - "//internal/data:data_manager", "//internal/network:types", "//internal/platform:comm", "//internal/platform:types", @@ -65,7 +63,6 @@ cc_test( timeout = "short", srcs = [ "fake_clock_test.cc", - "fake_data_set_test.cc", "fake_device_info_test.cc", "fake_http_client_test.cc", "fake_task_runner_test.cc", @@ -77,7 +74,6 @@ cc_test( shard_count = 8, deps = [ ":test", - "//internal/data:data_manager", "//internal/network:types", "//internal/platform:types", "//internal/platform/implementation:types", diff --git a/internal/test/fake_data_set.h b/internal/test/fake_data_set.h deleted file mode 100644 index 43494207..00000000 --- a/internal/test/fake_data_set.h +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright 2022 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 THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_DATA_SET_H_ -#define THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_DATA_SET_H_ - -#include -#include -#include -#include -#include - -#include "absl/container/flat_hash_map.h" -#include "absl/functional/any_invocable.h" -#include "internal/data/data_set.h" - -namespace nearby { -namespace data { - -template -class FakeDataSet : public DataSet { - public: - using KeyEntryVector = std::vector>; - - explicit FakeDataSet(const absl::flat_hash_map& entries_map) - : entries_map_(entries_map) {} - - void Initialize(absl::AnyInvocable callback) override { - init_callback_ = std::move(callback); - } - - void LoadEntries( - absl::AnyInvocable>) &&> - callback) override { - load_callback_ = std::move(callback); - } - - void UpdateEntries(std::unique_ptr entries_to_save, - std::unique_ptr> keys_to_remove, - absl::AnyInvocable callback) override { - entries_to_save_ = std::move(entries_to_save); - keys_to_remove_ = std::move(keys_to_remove); - update_callback_ = std::move(callback); - } - - void Destroy(absl::AnyInvocable callback) override { - destroy_callback_ = std::move(callback); - } - - // Mocked methods - void InitStatusCallback(InitStatus status) { - if (auto callback = std::move(init_callback_)) { - std::move(callback)(status); - } - } - - void LoadCallback(bool success) { - if (auto callback = std::move(load_callback_)) { - auto entries = std::make_unique>(); - for (auto it = entries_map_.begin(); it != entries_map_.end(); ++it) { - entries->push_back(it->second); - } - std::move(callback)(success, std::move(entries)); - } - } - - void UpdateCallback(bool success) { - if (success) { - if (entries_to_save_ != nullptr) { - for (auto it = entries_to_save_->begin(); it != entries_to_save_->end(); - ++it) { - auto entry = entries_map_.find(it->first); - if (entry == entries_map_.end()) { - entries_map_.emplace(it->first, it->second); - } else { - entry->second = it->second; - } - } - } - - if (keys_to_remove_ != nullptr) { - for (auto it = keys_to_remove_->begin(); it != keys_to_remove_->end(); - ++it) { - entries_map_.erase(*it); - } - } - } - - entries_to_save_ = nullptr; - keys_to_remove_ = nullptr; - if (auto callback = std::move(update_callback_)) { - std::move(callback)(success); - } - } - - void DestroyCallback(bool success) { - if (success) { - entries_map_.clear(); - } - if (auto callback = std::move(destroy_callback_)) { - std::move(callback)(success); - } - } - - absl::flat_hash_map& entries_map() { return entries_map_; } - - private: - absl::flat_hash_map entries_map_ = nullptr; - absl::AnyInvocable init_callback_ = nullptr; - absl::AnyInvocable>) &&> - load_callback_ = nullptr; - std::unique_ptr entries_to_save_ = nullptr; - std::unique_ptr> keys_to_remove_ = nullptr; - absl::AnyInvocable update_callback_ = nullptr; - absl::AnyInvocable destroy_callback_ = nullptr; -}; - -} // namespace data -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_DATA_SET_H_ diff --git a/internal/test/fake_data_set_test.cc b/internal/test/fake_data_set_test.cc deleted file mode 100644 index fb7da29d..00000000 --- a/internal/test/fake_data_set_test.cc +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2022 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 "internal/test/fake_data_set.h" - -#include -#include -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "internal/data/data_set.h" - -namespace nearby { -namespace data { -namespace { - -TEST(FakeDataSet, TestInitialize) { - InitStatus result = InitStatus::kNotInitialized; - FakeDataSet string_set({}); - - string_set.Initialize([&result](InitStatus res) { result = res; }); - string_set.InitStatusCallback(InitStatus::kOK); - EXPECT_EQ(result, InitStatus::kOK); -} - -TEST(FakeDataSet, TestUpdateEntries) { - bool result = false; - FakeDataSet string_set({}); - - auto temp = FakeDataSet::KeyEntryVector( - {{"id1", "string1"}, {"id2", "string2"}}); - - auto data = std::make_unique::KeyEntryVector>(temp); - - string_set.UpdateEntries(std::move(data), nullptr, - [&result](bool res) { result = res; }); - - string_set.UpdateCallback(true); - EXPECT_TRUE(result); - data = std::make_unique::KeyEntryVector>(temp); - string_set.UpdateEntries(std::move(data), nullptr, - [&result](bool res) { result = res; }); - string_set.UpdateCallback(false); - EXPECT_FALSE(result); -} - -TEST(FakeDataSet, TestLoadEntries) { - std::vector result = {}; - FakeDataSet string_set({}); - - auto temp = FakeDataSet::KeyEntryVector( - {{"id1", "string1"}, {"id2", "string2"}}); - auto data = std::make_unique::KeyEntryVector>(temp); - - string_set.UpdateEntries(std::move(data), nullptr, [](bool ans) {}); - string_set.UpdateCallback(true); - string_set.LoadEntries( - [&result](bool ans, std::unique_ptr> res) { - auto it = res->begin(); - while (it != res->end()) { - result.push_back(*it); - ++it; - } - }); - string_set.LoadCallback(true); - EXPECT_THAT(result, testing::SizeIs(2)); - std::sort(result.begin(), result.end()); - EXPECT_EQ(result, std::vector({"string1", "string2"})); -} - -TEST(MockDataSet, TestDestroy) { - bool result; - std::vector data = {}; - FakeDataSet string_set({{"id1", "string1"}, {"id2", "string2"}}); - string_set.Destroy([&result](bool res) { result = res; }); - string_set.DestroyCallback(true); - EXPECT_TRUE(result); - string_set.LoadEntries( - [&data](bool ans, std::unique_ptr> res) { - auto it = res->begin(); - while (it != res->end()) { - data.push_back(*it); - ++it; - } - }); - string_set.LoadCallback(true); - EXPECT_THAT(data, ::testing::SizeIs(0)); -} - -} // namespace -} // namespace data -} // namespace nearby From 1072030be85a61cef5e0a72b925bd6728e18f320 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Mon, 8 Jan 2024 10:19:03 -0800 Subject: [PATCH 094/683] Copy sharing/internal, sharing/common and sharing/scheduling to github. - Move Abseil pin to same as that used in Chromium. - Disabled layering_check due to build failure in absl. PiperOrigin-RevId: 596631921 --- .github/workflows/validate.yaml | 10 +- WORKSPACE | 32 +- connections/BUILD | 4 +- connections/implementation/BUILD | 2 +- internal/analytics/BUILD | 2 +- internal/base/BUILD | 4 +- internal/network/BUILD | 4 +- internal/platform/BUILD | 6 +- internal/platform/implementation/BUILD | 4 +- internal/platform/implementation/apple/BUILD | 2 +- internal/platform/implementation/g3/BUILD | 4 +- .../platform/implementation/windows/BUILD | 4 +- .../implementation/windows/generated/BUILD | 2 +- sharing/common/BUILD | 69 +++ sharing/common/compatible_u8_string.h | 34 ++ ...fake_nearby_share_profile_info_provider.cc | 40 ++ .../fake_nearby_share_profile_info_provider.h | 48 ++ sharing/common/nearby_share_enums.h | 114 +++++ sharing/common/nearby_share_prefs.cc | 177 ++++++++ sharing/common/nearby_share_prefs.h | 88 ++++ .../nearby_share_profile_info_provider.h | 39 ++ sharing/common/nearby_share_switches.cc | 41 ++ sharing/common/nearby_share_switches.h | 34 ++ sharing/internal/api/BUILD | 73 ++++ sharing/internal/api/app_info.h | 61 +++ sharing/internal/api/bluetooth_adapter.h | 105 +++++ sharing/internal/api/fast_init_ble_beacon.h | 151 +++++++ .../internal/api/fast_initiation_manager.h | 65 +++ sharing/internal/api/mock_app_info.h | 49 +++ sharing/internal/api/mock_bluetooth_adapter.h | 58 +++ sharing/internal/api/mock_network_monitor.h | 38 ++ .../internal/api/mock_public_certificate_db.h | 59 +++ sharing/internal/api/mock_sharing_platform.h | 100 +++++ sharing/internal/api/mock_system_info.h | 66 +++ sharing/internal/api/network_monitor.h | 61 +++ sharing/internal/api/preference_manager.h | 132 ++++++ .../internal/api/private_certificate_data.h | 75 ++++ .../api/public_certificate_database.h | 76 ++++ sharing/internal/api/sharing_platform.h | 96 ++++ sharing/internal/api/shell.h | 43 ++ sharing/internal/api/system_info.h | 183 ++++++++ sharing/internal/api/wifi_adapter.h | 91 ++++ sharing/internal/public/BUILD | 84 ++++ .../internal/public/connectivity_manager.h | 55 +++ .../public/connectivity_manager_impl.cc | 95 ++++ .../public/connectivity_manager_impl.h | 55 +++ .../public/connectivity_manager_impl_test.cc | 108 +++++ sharing/internal/public/context.h | 77 ++++ sharing/internal/public/context_impl.cc | 102 +++++ sharing/internal/public/context_impl.h | 68 +++ sharing/internal/public/logging.h | 44 ++ sharing/internal/test/BUILD | 87 ++++ .../internal/test/fake_bluetooth_adapter.h | 192 ++++++++ .../test/fake_bluetooth_adapter_observer.h | 63 +++ .../test/fake_bluetooth_adapter_test.cc | 241 +++++++++++ .../internal/test/fake_connectivity_manager.h | 64 +++ .../test/fake_connectivity_manager_test.cc | 71 +++ sharing/internal/test/fake_context.cc | 108 +++++ sharing/internal/test/fake_context.h | 74 ++++ sharing/internal/test/fake_context_test.cc | 48 ++ .../test/fake_fast_initiation_manager.h | 98 +++++ .../test/fake_fast_initiation_manager_test.cc | 83 ++++ sharing/internal/test/fake_network_monitor.h | 51 +++ .../internal/test/fake_preference_manager.cc | 325 ++++++++++++++ .../internal/test/fake_preference_manager.h | 153 +++++++ .../test/fake_public_certificate_db.cc | 81 ++++ .../test/fake_public_certificate_db.h | 64 +++ sharing/internal/test/fake_shell.h | 60 +++ sharing/internal/test/fake_shell_test.cc | 42 ++ sharing/internal/test/fake_wifi_adapter.h | 125 ++++++ .../test/fake_wifi_adapter_observer.h | 61 +++ .../internal/test/fake_wifi_adapter_test.cc | 162 +++++++ sharing/scheduling/BUILD | 106 +++++ .../scheduling/fake_nearby_share_scheduler.cc | 94 ++++ .../scheduling/fake_nearby_share_scheduler.h | 76 ++++ .../fake_nearby_share_scheduler_factory.cc | 124 ++++++ .../fake_nearby_share_scheduler_factory.h | 133 ++++++ sharing/scheduling/format.cc | 35 ++ sharing/scheduling/format.h | 31 ++ .../nearby_share_expiration_scheduler.cc | 55 +++ .../nearby_share_expiration_scheduler.h | 59 +++ .../nearby_share_expiration_scheduler_test.cc | 105 +++++ .../nearby_share_on_demand_scheduler.cc | 47 ++ .../nearby_share_on_demand_scheduler.h | 51 +++ .../nearby_share_on_demand_scheduler_test.cc | 59 +++ .../nearby_share_periodic_scheduler.cc | 58 +++ .../nearby_share_periodic_scheduler.h | 59 +++ .../nearby_share_periodic_scheduler_test.cc | 86 ++++ sharing/scheduling/nearby_share_scheduler.cc | 45 ++ sharing/scheduling/nearby_share_scheduler.h | 91 ++++ .../scheduling/nearby_share_scheduler_base.cc | 340 +++++++++++++++ .../scheduling/nearby_share_scheduler_base.h | 130 ++++++ .../nearby_share_scheduler_base_test.cc | 409 ++++++++++++++++++ .../nearby_share_scheduler_factory.cc | 102 +++++ .../nearby_share_scheduler_factory.h | 96 ++++ .../nearby_share_scheduler_fields.h | 34 ++ .../nearby_share_scheduler_utils.cc | 85 ++++ .../scheduling/nearby_share_scheduler_utils.h | 32 ++ .../nearby_share_scheduler_utils_test.cc | 118 +++++ 99 files changed, 7914 insertions(+), 33 deletions(-) create mode 100644 sharing/common/BUILD create mode 100644 sharing/common/compatible_u8_string.h create mode 100644 sharing/common/fake_nearby_share_profile_info_provider.cc create mode 100644 sharing/common/fake_nearby_share_profile_info_provider.h create mode 100644 sharing/common/nearby_share_enums.h create mode 100644 sharing/common/nearby_share_prefs.cc create mode 100644 sharing/common/nearby_share_prefs.h create mode 100644 sharing/common/nearby_share_profile_info_provider.h create mode 100644 sharing/common/nearby_share_switches.cc create mode 100644 sharing/common/nearby_share_switches.h create mode 100644 sharing/internal/api/BUILD create mode 100644 sharing/internal/api/app_info.h create mode 100644 sharing/internal/api/bluetooth_adapter.h create mode 100644 sharing/internal/api/fast_init_ble_beacon.h create mode 100644 sharing/internal/api/fast_initiation_manager.h create mode 100644 sharing/internal/api/mock_app_info.h create mode 100644 sharing/internal/api/mock_bluetooth_adapter.h create mode 100644 sharing/internal/api/mock_network_monitor.h create mode 100644 sharing/internal/api/mock_public_certificate_db.h create mode 100644 sharing/internal/api/mock_sharing_platform.h create mode 100644 sharing/internal/api/mock_system_info.h create mode 100644 sharing/internal/api/network_monitor.h create mode 100644 sharing/internal/api/preference_manager.h create mode 100644 sharing/internal/api/private_certificate_data.h create mode 100644 sharing/internal/api/public_certificate_database.h create mode 100644 sharing/internal/api/sharing_platform.h create mode 100644 sharing/internal/api/shell.h create mode 100644 sharing/internal/api/system_info.h create mode 100644 sharing/internal/api/wifi_adapter.h create mode 100644 sharing/internal/public/BUILD create mode 100644 sharing/internal/public/connectivity_manager.h create mode 100644 sharing/internal/public/connectivity_manager_impl.cc create mode 100644 sharing/internal/public/connectivity_manager_impl.h create mode 100644 sharing/internal/public/connectivity_manager_impl_test.cc create mode 100644 sharing/internal/public/context.h create mode 100644 sharing/internal/public/context_impl.cc create mode 100644 sharing/internal/public/context_impl.h create mode 100644 sharing/internal/public/logging.h create mode 100644 sharing/internal/test/BUILD create mode 100644 sharing/internal/test/fake_bluetooth_adapter.h create mode 100644 sharing/internal/test/fake_bluetooth_adapter_observer.h create mode 100644 sharing/internal/test/fake_bluetooth_adapter_test.cc create mode 100644 sharing/internal/test/fake_connectivity_manager.h create mode 100644 sharing/internal/test/fake_connectivity_manager_test.cc create mode 100644 sharing/internal/test/fake_context.cc create mode 100644 sharing/internal/test/fake_context.h create mode 100644 sharing/internal/test/fake_context_test.cc create mode 100644 sharing/internal/test/fake_fast_initiation_manager.h create mode 100644 sharing/internal/test/fake_fast_initiation_manager_test.cc create mode 100644 sharing/internal/test/fake_network_monitor.h create mode 100644 sharing/internal/test/fake_preference_manager.cc create mode 100644 sharing/internal/test/fake_preference_manager.h create mode 100644 sharing/internal/test/fake_public_certificate_db.cc create mode 100644 sharing/internal/test/fake_public_certificate_db.h create mode 100644 sharing/internal/test/fake_shell.h create mode 100644 sharing/internal/test/fake_shell_test.cc create mode 100644 sharing/internal/test/fake_wifi_adapter.h create mode 100644 sharing/internal/test/fake_wifi_adapter_observer.h create mode 100644 sharing/internal/test/fake_wifi_adapter_test.cc create mode 100644 sharing/scheduling/BUILD create mode 100644 sharing/scheduling/fake_nearby_share_scheduler.cc create mode 100644 sharing/scheduling/fake_nearby_share_scheduler.h create mode 100644 sharing/scheduling/fake_nearby_share_scheduler_factory.cc create mode 100644 sharing/scheduling/fake_nearby_share_scheduler_factory.h create mode 100644 sharing/scheduling/format.cc create mode 100644 sharing/scheduling/format.h create mode 100644 sharing/scheduling/nearby_share_expiration_scheduler.cc create mode 100644 sharing/scheduling/nearby_share_expiration_scheduler.h create mode 100644 sharing/scheduling/nearby_share_expiration_scheduler_test.cc create mode 100644 sharing/scheduling/nearby_share_on_demand_scheduler.cc create mode 100644 sharing/scheduling/nearby_share_on_demand_scheduler.h create mode 100644 sharing/scheduling/nearby_share_on_demand_scheduler_test.cc create mode 100644 sharing/scheduling/nearby_share_periodic_scheduler.cc create mode 100644 sharing/scheduling/nearby_share_periodic_scheduler.h create mode 100644 sharing/scheduling/nearby_share_periodic_scheduler_test.cc create mode 100644 sharing/scheduling/nearby_share_scheduler.cc create mode 100644 sharing/scheduling/nearby_share_scheduler.h create mode 100644 sharing/scheduling/nearby_share_scheduler_base.cc create mode 100644 sharing/scheduling/nearby_share_scheduler_base.h create mode 100644 sharing/scheduling/nearby_share_scheduler_base_test.cc create mode 100644 sharing/scheduling/nearby_share_scheduler_factory.cc create mode 100644 sharing/scheduling/nearby_share_scheduler_factory.h create mode 100644 sharing/scheduling/nearby_share_scheduler_fields.h create mode 100644 sharing/scheduling/nearby_share_scheduler_utils.cc create mode 100644 sharing/scheduling/nearby_share_scheduler_utils.h create mode 100644 sharing/scheduling/nearby_share_scheduler_utils_test.cc diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index 2d03dcd2..334c01a7 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -31,14 +31,14 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - with: - submodules: recursive + # Disbale layering_check to work around ABSL build failure. + # see https://github.com/bazelbuild/bazel/issues/15359 - name: Build Connections - run: CC=clang CXX=clang++ bazel build --check_visibility=false //connections:core --spawn_strategy=standalone + run: CC=clang CXX=clang++ bazel build --features=-layering_check //connections:core --spawn_strategy=standalone - name: Build Presence - run: CC=clang CXX=clang++ bazel build --check_visibility=false //presence --spawn_strategy=standalone + run: CC=clang CXX=clang++ bazel build --features=-layering_check //presence --spawn_strategy=standalone - name: Build Sharing - run: CC=clang CXX=clang++ bazel build --check_visibility=false //sharing/proto:all --spawn_strategy=standalone + run: CC=clang CXX=clang++ bazel build --features=-layering_check //sharing/proto:all //sharing/internal/public:nearby_context //sharing/common:all //sharing/scheduling:scheduling --spawn_strategy=standalone build-rust-linux: name: Build Rust on Linux diff --git a/WORKSPACE b/WORKSPACE index 5ff5e67f..052d8da6 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -1,17 +1,17 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") # Rule repository, note that it's recommended to use a pinned commit to a released version of the rules -http_archive( - name = "rules_foreign_cc", - strip_prefix = "rules_foreign_cc-0.6.0", - url = "https://github.com/bazelbuild/rules_foreign_cc/archive/0.6.0.tar.gz", -) +# http_archive( +# name = "rules_foreign_cc", +# strip_prefix = "rules_foreign_cc-0.6.0", +# url = "https://github.com/bazelbuild/rules_foreign_cc/archive/0.6.0.tar.gz", +#) -load("@rules_foreign_cc//foreign_cc:repositories.bzl", "rules_foreign_cc_dependencies") +# load("@rules_foreign_cc//foreign_cc:repositories.bzl", "rules_foreign_cc_dependencies") # This sets up some common toolchains for building targets. For more details, please see # https://github.com/bazelbuild/rules_foreign_cc/tree/main/docs#rules_foreign_cc_dependencies -rules_foreign_cc_dependencies() +# rules_foreign_cc_dependencies() _ALL_CONTENT = """\ filegroup( @@ -21,10 +21,24 @@ filegroup( ) """ +http_archive( + name = "bazel_skylib", # 2023-05-31T19:24:07Z + sha256 = "08c0386f45821ce246bbbf77503c973246ed6ee5c3463e41efc197fa9bc3a7f4", + strip_prefix = "bazel-skylib-288731ef9f7f688932bd50e704a91a45ec185f9b", + urls = ["https://github.com/bazelbuild/bazel-skylib/archive/288731ef9f7f688932bd50e704a91a45ec185f9b.zip"], +) + +http_archive( + name = "platforms", # 2023-07-28T19:44:27Z + sha256 = "40eb313613ff00a5c03eed20aba58890046f4d38dec7344f00bb9a8867853526", + strip_prefix = "platforms-4ad40ef271da8176d4fc0194d2089b8a76e19d7b", + urls = ["https://github.com/bazelbuild/platforms/archive/4ad40ef271da8176d4fc0194d2089b8a76e19d7b.zip"], +) + http_archive( name = "com_google_absl", - strip_prefix = "abseil-cpp-20230802.1", - urls = ["https://github.com/abseil/abseil-cpp/archive/refs/tags/20230802.1.zip"], + strip_prefix = "abseil-cpp-4038192a57cb75f7ee671f81a3378ff4c74c4f8e", + urls = ["https://github.com/abseil/abseil-cpp/archive/4038192a57cb75f7ee671f81a3378ff4c74c4f8e.zip"], ) # Using a protobuf javalite version that contains @com_google_protobuf_javalite//:javalite_toolchain diff --git a/connections/BUILD b/connections/BUILD index bbe2b62a..2ab67e4c 100644 --- a/connections/BUILD +++ b/connections/BUILD @@ -27,7 +27,7 @@ cc_library( "//connections:__subpackages__", "//location/nearby/cpp/sharing:__subpackages__", "//location/nearby/testing:__subpackages__", - "//third_party/nearby/sharing:__subpackages__", + "//sharing:__subpackages__", ], deps = [ ":core_types", @@ -74,7 +74,7 @@ cc_library( "//connections:__subpackages__", "//location/nearby/cpp/sharing:__subpackages__", "//location/nearby/testing:__subpackages__", - "//third_party/nearby/sharing:__subpackages__", + "//sharing:__subpackages__", ], deps = [ "//internal/platform:base", diff --git a/connections/implementation/BUILD b/connections/implementation/BUILD index 4491e930..ee9cac0b 100644 --- a/connections/implementation/BUILD +++ b/connections/implementation/BUILD @@ -110,7 +110,7 @@ cc_library( "//connections:__pkg__", "//connections/implementation/fuzzers:__pkg__", "//location/nearby/cpp/sharing/implementation:__pkg__", - "//third_party/nearby/sharing:__subpackages__", + "//sharing:__subpackages__", ], deps = [ "//connections:core_types", diff --git a/internal/analytics/BUILD b/internal/analytics/BUILD index 4d6bfc2d..bc15387e 100644 --- a/internal/analytics/BUILD +++ b/internal/analytics/BUILD @@ -24,7 +24,7 @@ cc_library( "//location/nearby/analytics/cpp:__subpackages__", "//location/nearby/cpp/experiments:__subpackages__", "//location/nearby/cpp/sharing:__subpackages__", - "//third_party/nearby/sharing:__subpackages__", + "//sharing:__subpackages__", ], deps = ["@com_google_protobuf//:protobuf"], ) diff --git a/internal/base/BUILD b/internal/base/BUILD index 35d66268..99450c74 100644 --- a/internal/base/BUILD +++ b/internal/base/BUILD @@ -18,7 +18,7 @@ cc_library( "//internal/test:__pkg__", "//location/nearby/cpp/experiments:__subpackages__", "//location/nearby/cpp/sharing:__subpackages__", - "//third_party/nearby/sharing:__subpackages__", + "//sharing:__subpackages__", ], deps = [ "//internal/platform:types", @@ -42,7 +42,7 @@ cc_library( "//fastpair:__subpackages__", "//internal:__subpackages__", "//location/nearby/cpp/sharing:__subpackages__", - "//third_party/nearby/sharing:__subpackages__", + "//sharing:__subpackages__", ], deps = [ "@com_google_absl//absl/strings", diff --git a/internal/network/BUILD b/internal/network/BUILD index 52f6f3de..0620b329 100644 --- a/internal/network/BUILD +++ b/internal/network/BUILD @@ -24,7 +24,7 @@ cc_library( "//internal:__pkg__", "//internal:__subpackages__", "//location/nearby/cpp/sharing:__subpackages__", - "//third_party/nearby/sharing:__subpackages__", + "//sharing:__subpackages__", ], deps = [ "//internal/platform:types", @@ -53,7 +53,7 @@ cc_library( "//internal:__pkg__", "//internal:__subpackages__", "//location/nearby/cpp/sharing:__subpackages__", - "//third_party/nearby/sharing:__subpackages__", + "//sharing:__subpackages__", ], deps = [ ":types", diff --git a/internal/platform/BUILD b/internal/platform/BUILD index 0e5a61e1..2f151ab9 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -56,7 +56,7 @@ cc_library( "//internal/weave:__subpackages__", "//location/nearby/cpp:__subpackages__", "//presence:__subpackages__", - "//third_party/nearby/sharing:__subpackages__", + "//sharing:__subpackages__", ], deps = [ "//proto:connections_enums_cc_proto", @@ -197,7 +197,7 @@ cc_library( "//fastpair:__subpackages__", "//internal/platform/implementation:__subpackages__", "//presence:__subpackages__", - "//third_party/nearby/sharing:__subpackages__", + "//sharing:__subpackages__", ], deps = [ ":base", @@ -347,7 +347,7 @@ cc_library( "//location/nearby/cpp:__subpackages__", "//location/nearby/testing/nearby_native:__subpackages__", "//presence:__subpackages__", - "//third_party/nearby/sharing:__subpackages__", + "//sharing:__subpackages__", ], deps = [ ":base", diff --git a/internal/platform/implementation/BUILD b/internal/platform/implementation/BUILD index 3b11e279..a8194618 100644 --- a/internal/platform/implementation/BUILD +++ b/internal/platform/implementation/BUILD @@ -53,7 +53,7 @@ cc_library( "//location/nearby/cpp/common:__subpackages__", "//location/nearby/cpp/sharing:__subpackages__", "//presence:__subpackages__", - "//third_party/nearby/sharing:__subpackages__", + "//sharing:__subpackages__", ], deps = [ "//internal/crypto_cros", @@ -126,7 +126,7 @@ cc_library( "//internal/platform/implementation:__subpackages__", "//location/nearby/analytics/cpp:__subpackages__", "//location/nearby/cpp/sharing:__subpackages__", - "//third_party/nearby/sharing:__subpackages__", + "//sharing:__subpackages__", ], deps = [ ":comm", diff --git a/internal/platform/implementation/apple/BUILD b/internal/platform/implementation/apple/BUILD index 0e2b044e..5b0914ce 100644 --- a/internal/platform/implementation/apple/BUILD +++ b/internal/platform/implementation/apple/BUILD @@ -17,7 +17,7 @@ package(default_visibility = [ "//connections:__subpackages__", "//internal/platform/implementation/apple:__subpackages__", "//location/nearby:__subpackages__", - "//third_party/nearby/sharing:__subpackages__", + "//sharing:__subpackages__", ]) objc_library( diff --git a/internal/platform/implementation/g3/BUILD b/internal/platform/implementation/g3/BUILD index 9a4359d6..db01a738 100644 --- a/internal/platform/implementation/g3/BUILD +++ b/internal/platform/implementation/g3/BUILD @@ -38,7 +38,7 @@ cc_library( visibility = [ "//internal/test:__subpackages__", "//location/nearby/cpp:__subpackages__", - "//third_party/nearby/sharing:__subpackages__", + "//sharing:__subpackages__", ], deps = [ ":preferences_repository", @@ -155,7 +155,7 @@ cc_library( "//internal/weave:__subpackages__", "//location/nearby/cpp:__subpackages__", "//presence:__subpackages__", - "//third_party/nearby/sharing:__subpackages__", + "//sharing:__subpackages__", ], deps = [ ":comm", diff --git a/internal/platform/implementation/windows/BUILD b/internal/platform/implementation/windows/BUILD index 31abb0a9..ae26985a 100644 --- a/internal/platform/implementation/windows/BUILD +++ b/internal/platform/implementation/windows/BUILD @@ -47,7 +47,7 @@ cc_library( "-Wno-vla-extension", ], defines = ["_SILENCE_CLANG_COROUTINE_MESSAGE"], - visibility = ["//third_party/nearby/sharing/internal/impl/windows:__pkg__"], + visibility = ["//sharing/internal/impl/windows:__pkg__"], deps = [ ":comm", "//base", @@ -207,7 +207,7 @@ cc_library( "//fastpair:__subpackages__", "//location/nearby:__subpackages__", "//presence:__subpackages__", - "//third_party/nearby/sharing:__subpackages__", + "//sharing:__subpackages__", ], deps = [ ":comm", diff --git a/internal/platform/implementation/windows/generated/BUILD b/internal/platform/implementation/windows/generated/BUILD index 1036e17b..6434f51d 100644 --- a/internal/platform/implementation/windows/generated/BUILD +++ b/internal/platform/implementation/windows/generated/BUILD @@ -46,6 +46,6 @@ cc_library( "//internal:__subpackages__", "//internal/platform/implementation/windows:__subpackages__", "//location/nearby/cpp/sharing/implementation/internal:__subpackages__", - "//third_party/nearby/sharing:__subpackages__", + "//sharing:__subpackages__", ], ) diff --git a/sharing/common/BUILD b/sharing/common/BUILD new file mode 100644 index 00000000..a46bee3a --- /dev/null +++ b/sharing/common/BUILD @@ -0,0 +1,69 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +licenses(["notice"]) + +cc_library( + name = "common", + srcs = [ + "nearby_share_prefs.cc", + "nearby_share_switches.cc", + ], + hdrs = [ + "nearby_share_enums.h", + "nearby_share_prefs.h", + "nearby_share_profile_info_provider.h", + "nearby_share_switches.h", + ], + visibility = ["//visibility:public"], + deps = [ + "//sharing/internal/api:platform", + "//sharing/proto:share_cc_proto", + "@com_google_absl//absl/base:core_headers", + "@com_google_absl//absl/status", + "@com_google_absl//absl/time", + ], +) + +cc_library( + name = "test_support", + testonly = True, + srcs = [ + "fake_nearby_share_profile_info_provider.cc", + ], + hdrs = [ + "fake_nearby_share_profile_info_provider.h", + "nearby_share_profile_info_provider.h", + ], + visibility = ["//visibility:public"], + deps = [], +) + +cc_library( + name = "enum", + srcs = [ + ], + hdrs = [ + "nearby_share_enums.h", + ], + visibility = ["//visibility:public"], + deps = [ + ], +) + +cc_library( + name = "compatible_u8_string", + hdrs = ["compatible_u8_string.h"], + visibility = ["//sharing:__subpackages__"], +) diff --git a/sharing/common/compatible_u8_string.h b/sharing/common/compatible_u8_string.h new file mode 100644 index 00000000..ca9ac276 --- /dev/null +++ b/sharing/common/compatible_u8_string.h @@ -0,0 +1,34 @@ +// Copyright 2024 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 THIRD_PARTY_NEARBY_SHARING_COMMON_COMPATIBLE_U8_STRING_H_ +#define THIRD_PARTY_NEARBY_SHARING_COMMON_COMPATIBLE_U8_STRING_H_ + +#include + +namespace nearby { +namespace sharing { + +#if defined(__cpp_lib_char8_t) +inline std::string GetCompatibleU8String(std::u8string str) { + return reinterpret_cast(str.c_str()); +} +#else +inline std::string GetCompatibleU8String(std::string str) { return str; } +#endif + +} // namespace sharing +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_COMMON_COMPATIBLE_U8_STRING_H_ diff --git a/sharing/common/fake_nearby_share_profile_info_provider.cc b/sharing/common/fake_nearby_share_profile_info_provider.cc new file mode 100644 index 00000000..97abfec1 --- /dev/null +++ b/sharing/common/fake_nearby_share_profile_info_provider.cc @@ -0,0 +1,40 @@ +// 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 "sharing/common/fake_nearby_share_profile_info_provider.h" + +#include +#include + +namespace nearby { +namespace sharing { + +FakeNearbyShareProfileInfoProvider::FakeNearbyShareProfileInfoProvider() = + default; + +FakeNearbyShareProfileInfoProvider::~FakeNearbyShareProfileInfoProvider() = + default; + +std::optional FakeNearbyShareProfileInfoProvider::GetGivenName() + const { + return given_name_; +} + +std::optional +FakeNearbyShareProfileInfoProvider::GetProfileUserName() const { + return profile_user_name_; +} + +} // namespace sharing +} // namespace nearby diff --git a/sharing/common/fake_nearby_share_profile_info_provider.h b/sharing/common/fake_nearby_share_profile_info_provider.h new file mode 100644 index 00000000..b0f6ec24 --- /dev/null +++ b/sharing/common/fake_nearby_share_profile_info_provider.h @@ -0,0 +1,48 @@ +// 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 THIRD_PARTY_NEARBY_SHARING_COMMON_FAKE_NEARBY_SHARE_PROFILE_INFO_PROVIDER_H_ +#define THIRD_PARTY_NEARBY_SHARING_COMMON_FAKE_NEARBY_SHARE_PROFILE_INFO_PROVIDER_H_ + +#include +#include + +#include "sharing/common/nearby_share_profile_info_provider.h" + +namespace nearby { +namespace sharing { + +class FakeNearbyShareProfileInfoProvider + : public NearbyShareProfileInfoProvider { + public: + FakeNearbyShareProfileInfoProvider(); + ~FakeNearbyShareProfileInfoProvider() override; + + // NearbyShareProfileInfoProvider: + std::optional GetGivenName() const override; + std::optional GetProfileUserName() const override; + + void set_given_name(const std::optional& given_name) { + given_name_ = given_name; + } + + private: + std::optional given_name_; + std::optional profile_user_name_; +}; + +} // namespace sharing +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_COMMON_FAKE_NEARBY_SHARE_PROFILE_INFO_PROVIDER_H_ diff --git a/sharing/common/nearby_share_enums.h b/sharing/common/nearby_share_enums.h new file mode 100644 index 00000000..b17903af --- /dev/null +++ b/sharing/common/nearby_share_enums.h @@ -0,0 +1,114 @@ +// Copyright 2021-2023 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 THIRD_PARTY_NEARBY_SHARING_COMMON_NEARBY_SHARE_ENUMS_H_ +#define THIRD_PARTY_NEARBY_SHARING_COMMON_NEARBY_SHARE_ENUMS_H_ + +namespace nearby { +namespace sharing { + +// Represents the advertising bluetooth power for Nearby Connections. +enum class PowerLevel { + kUnknown = 0, + kLowPower = 1, + kMediumPower = 2, + kHighPower = 3, + kMaxValue = kHighPower +}; + +enum class DeviceNameValidationResult { + // The device name was valid. + kValid = 0, + // The device name must not be empty. + kErrorEmpty = 1, + // The device name is too long. + kErrorTooLong = 2, + // The device name is not valid UTF-8. + kErrorNotValidUtf8 = 3 +}; + +// Describes the type of device for a ShareTarget. +// The numeric values are used to encode/decode advertisement bytes, and must +// be kept in sync with Android implementation. +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class ShareTargetType { + // Unknown device type. + kUnknown = 0, + // A phone. + kPhone = 1, + // A tablet. + kTablet = 2, + // A laptop. + kLaptop = 3, +}; + +// This enum combines both text and file share attachment types into a single +// enum that more directly maps to what is shown to the user for preview. +enum class ShareType { + // A generic non-file text share. + kText, + // A text share representing a url, opened in browser. + kUrl, + // A text share representing a phone number, opened in dialer. + kPhone, + // A text share representing an address, opened in browser. + kAddress, + // Multiple files are being shared, we don't capture the specific types. + kMultipleFiles, + // Single file attachment with a mime type of 'image/*'. + kImageFile, + // Single file attachment with a mime type of 'video/*'. + kVideoFile, + // Single file attachment with a mime type of 'audio/*'. + kAudioFile, + // Single file attachment with a mime type of 'application/pdf'. + kPdfFile, + // Single file attachment with a mime type of + // 'application/vnd.google-apps.document'. + kGoogleDocsFile, + // Single file attachment with a mime type of + // 'application/vnd.google-apps.spreadsheet'. + kGoogleSheetsFile, + // Single file attachment with a mime type of + // 'application/vnd.google-apps.presentation'. + kGoogleSlidesFile, + // Single file attachment with mime type of + // 'text/plain' + kTextFile, + // Single file attachment with un-matched mime type. + kUnknownFile, + // Single WiFi credentials attachment. + kWifiCredentials, +}; + +enum class FileSenderType { + kUnknown = 0, + // The user sends files using context menu. + kContextMenu = 1, + // The user sends files using drag and drop. + kDragAndDrop = 2, + // The user sends files by clicking the "Select files" button. + kSelectFilesButton = 3, + // The user sends files by pasting (e.g. ctrl+v) into the Nearby Share app. + kPaste = 4, + // The user sends files by clicking the "Select folders" button. + kSelectFoldersButton = 5, + kMaxValue = kSelectFoldersButton +}; + +} // namespace sharing +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_COMMON_NEARBY_SHARE_ENUMS_H_ diff --git a/sharing/common/nearby_share_prefs.cc b/sharing/common/nearby_share_prefs.cc new file mode 100644 index 00000000..b395f741 --- /dev/null +++ b/sharing/common/nearby_share_prefs.cc @@ -0,0 +1,177 @@ +// Copyright 2021-2023 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 "sharing/common/nearby_share_prefs.h" + +#include +#include + +#include "absl/time/clock.h" +#include "sharing/internal/api/preference_manager.h" +#include "sharing/proto/enums.pb.h" + +namespace nearby { +namespace sharing { +namespace prefs { +namespace { +using ::nearby::sharing::api::PreferenceManager; + +using DataUsage = ::nearby::sharing::proto::DataUsage; +using FastInitiationNotificationState = + ::nearby::sharing::proto::FastInitiationNotificationState; +} // namespace + +const char kNearbySharingAllowedContactsName[] = + "nearby_sharing.allowed_contacts"; +const char kNearbySharingBackgroundVisibilityName[] = + "nearby_sharing.background_visibility"; +const char kNearbySharingBackgroundTemporarilyVisibleName[] = + "nearby_sharing.background_temporarily_visible"; +const char kNearbySharingBackgroundFallbackVisibilityName[] = + "nearby_sharing.background_fallback_visibility"; +const char kNearbySharingBackgroundVisibilityExpirationSeconds[] = + "nearby_sharing.background_visibility_expiration_seconds"; +const char kNearbySharingContactUploadHashName[] = + "nearby_sharing.contact_upload_hash"; +const char kNearbySharingCustomSavePath[] = "nearby_sharing.custom_save_path"; +const char kNearbySharingDataUsageName[] = "nearby_sharing.data_usage"; +const char kNearbySharingDeviceIdName[] = "nearby_sharing.device_id"; +const char kNearbySharingDeviceNameName[] = "nearby_sharing.device_name"; +const char kNearbySharingEnabledName[] = "nearby_sharing.enabled"; +const char kNearbySharingFastInitiationNotificationStateName[] = + "nearby_sharing.fast_initiation_notification_state"; +const char kNearbySharingOnboardingCompleteName[] = + "nearby_sharing.onboarding_complete"; +const char kNearbySharingFullNameName[] = "nearby_sharing.full_name"; +const char kNearbySharingIconUrlName[] = "nearby_sharing.icon_url"; +const char kNearbySharingIconTokenName[] = "nearby_sharing.icon_token"; +const char kNearbySharingOnboardingDismissedTimeName[] = + "nearby_sharing.onboarding_dismissed_time"; +const char kNearbySharingPublicCertificateExpirationDictName[] = + "nearbyshare.public_certificate_expiration_dict"; +const char kNearbySharingPrivateCertificateListName[] = + "nearbyshare.private_certificate_list"; +const char kNearbySharingSchedulerContactDownloadAndUploadName[] = + "nearby_sharing.scheduler.contact_download_and_upload"; +const char kNearbySharingSchedulerDownloadDeviceDataName[] = + "nearby_sharing.scheduler.download_device_data"; +const char kNearbySharingSchedulerDownloadPublicCertificatesName[] = + "nearby_sharing.scheduler.download_public_certificates"; +const char kNearbySharingSchedulerPeriodicContactUploadName[] = + "nearby_sharing.scheduler.periodic_contact_upload"; +const char kNearbySharingSchedulerPrivateCertificateExpirationName[] = + "nearby_sharing.scheduler.private_certificate_expiration"; +const char kNearbySharingSchedulerPublicCertificateExpirationName[] = + "nearby_sharing.scheduler.public_certificate_expiration"; +const char kNearbySharingSchedulerUploadDeviceNameName[] = + "nearby_sharing.scheduler.upload_device_name"; +const char kNearbySharingSchedulerUploadLocalDeviceCertificatesName[] = + "nearby_sharing.scheduler.upload_local_device_certificates"; +const char kNearbySharingUsersName[] = "nearby_sharing.users"; +const char kNearbySharingIsReceivingName[] = "nearby_sharing.is_receiving"; +const char kNearbySharingIsAnalyticsEnabledName[] = + "nearby_sharing.is_analytics_enabled"; +const char kNearbySharingIsAllContactsEnabledName[] = + "nearby_sharing.is_all_contacts_enabled"; +const char kNearbySharingAutoAppStartEnabledName[] = + "nearby_sharing.auto_app_start_enabled"; + +void RegisterNearbySharingPrefs(PreferenceManager& preference_manager, + bool skip_persistent_ones) { + // These prefs are not synced across devices on purpose. + + if (!skip_persistent_ones) { + // During logging out, we reset all settings and set these settings to new + // values. To avoid setting them twice, we skip them here if + // skip_persistent_ones is set to true. + preference_manager.SetBoolean(kNearbySharingEnabledName, false); + preference_manager.SetString(kNearbySharingCustomSavePath, std::string()); + preference_manager.SetBoolean(kNearbySharingOnboardingCompleteName, false); + preference_manager.SetInteger(kNearbySharingBackgroundVisibilityName, + static_cast(kDefaultVisibility)); + preference_manager.SetInteger( + kNearbySharingBackgroundFallbackVisibilityName, + static_cast(kDefaultFallbackVisibility)); + preference_manager.SetBoolean(kNearbySharingIsReceivingName, true); + } + + preference_manager.SetInteger( + kNearbySharingFastInitiationNotificationStateName, + /*value=*/static_cast( + FastInitiationNotificationState::ENABLED_FAST_INIT)); + + preference_manager.SetInteger( + kNearbySharingDataUsageName, + static_cast(DataUsage::WIFI_ONLY_DATA_USAGE)); + + preference_manager.SetString(kNearbySharingContactUploadHashName, + std::string()); + + preference_manager.SetString(kNearbySharingDeviceIdName, std::string()); + + preference_manager.SetString(kNearbySharingDeviceNameName, std::string()); + + preference_manager.SetStringArray(kNearbySharingAllowedContactsName, + std::vector()); + + preference_manager.SetString(kNearbySharingFullNameName, std::string()); + + preference_manager.SetString(kNearbySharingIconUrlName, std::string()); + + preference_manager.SetString(kNearbySharingIconTokenName, std::string()); + + preference_manager.SetTime(kNearbySharingOnboardingDismissedTimeName, + absl::Now()); + + preference_manager.Remove(kNearbySharingPublicCertificateExpirationDictName); + preference_manager.Remove(kNearbySharingPrivateCertificateListName); + preference_manager.Remove( + kNearbySharingSchedulerContactDownloadAndUploadName); + preference_manager.Remove(kNearbySharingSchedulerDownloadDeviceDataName); + preference_manager.Remove( + kNearbySharingSchedulerDownloadPublicCertificatesName); + preference_manager.Remove(kNearbySharingSchedulerPeriodicContactUploadName); + preference_manager.Remove( + kNearbySharingSchedulerPrivateCertificateExpirationName); + preference_manager.Remove( + kNearbySharingSchedulerPublicCertificateExpirationName); + preference_manager.Remove(kNearbySharingSchedulerUploadDeviceNameName); + preference_manager.Remove( + kNearbySharingSchedulerUploadLocalDeviceCertificatesName); + preference_manager.Remove(kNearbySharingUsersName); + + preference_manager.SetBoolean(kNearbySharingIsAnalyticsEnabledName, false); + preference_manager.SetBoolean(kNearbySharingIsAllContactsEnabledName, true); + preference_manager.SetBoolean(kNearbySharingAutoAppStartEnabledName, true); +} + +void ResetSchedulers(PreferenceManager& preference_manager) { + preference_manager.Remove( + kNearbySharingSchedulerContactDownloadAndUploadName); + preference_manager.Remove(kNearbySharingSchedulerDownloadDeviceDataName); + preference_manager.Remove( + kNearbySharingSchedulerDownloadPublicCertificatesName); + preference_manager.Remove(kNearbySharingSchedulerPeriodicContactUploadName); + preference_manager.Remove( + kNearbySharingSchedulerPrivateCertificateExpirationName); + preference_manager.Remove( + kNearbySharingSchedulerPublicCertificateExpirationName); + preference_manager.Remove(kNearbySharingSchedulerUploadDeviceNameName); + preference_manager.Remove( + kNearbySharingSchedulerUploadLocalDeviceCertificatesName); +} + +} // namespace prefs +} // namespace sharing +} // namespace nearby diff --git a/sharing/common/nearby_share_prefs.h b/sharing/common/nearby_share_prefs.h new file mode 100644 index 00000000..cafc243c --- /dev/null +++ b/sharing/common/nearby_share_prefs.h @@ -0,0 +1,88 @@ +// Copyright 2021-2023 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 THIRD_PARTY_NEARBY_SHARING_COMMON_NEARBY_SHARE_PREFS_H_ +#define THIRD_PARTY_NEARBY_SHARING_COMMON_NEARBY_SHARE_PREFS_H_ + +#include "absl/base/attributes.h" +#include "sharing/internal/api/preference_manager.h" +#include "sharing/proto/enums.pb.h" + +namespace nearby { +namespace sharing { +namespace prefs { + +ABSL_CONST_INIT extern const char kNearbySharingAllowedContactsName[]; +ABSL_CONST_INIT extern const char kNearbySharingBackgroundVisibilityName[]; +ABSL_CONST_INIT extern const char + kNearbySharingBackgroundTemporarilyVisibleName[]; +ABSL_CONST_INIT extern const char + kNearbySharingBackgroundFallbackVisibilityName[]; +ABSL_CONST_INIT extern const char + kNearbySharingBackgroundVisibilityExpirationSeconds[]; +ABSL_CONST_INIT extern const char kNearbySharingContactUploadHashName[]; +ABSL_CONST_INIT extern const char kNearbySharingCustomSavePath[]; +ABSL_CONST_INIT extern const char kNearbySharingDataUsageName[]; +ABSL_CONST_INIT extern const char kNearbySharingDeviceIdName[]; +ABSL_CONST_INIT extern const char kNearbySharingDeviceNameName[]; +ABSL_CONST_INIT extern const char kNearbySharingEnabledName[]; +ABSL_CONST_INIT extern const char + kNearbySharingFastInitiationNotificationStateName[]; +ABSL_CONST_INIT extern const char kNearbySharingOnboardingCompleteName[]; +ABSL_CONST_INIT extern const char kNearbySharingFullNameName[]; +ABSL_CONST_INIT extern const char kNearbySharingIconUrlName[]; +ABSL_CONST_INIT extern const char kNearbySharingIconTokenName[]; +ABSL_CONST_INIT extern const char kNearbySharingOnboardingDismissedTimeName[]; +ABSL_CONST_INIT extern const char kNearbySharingPrivateCertificateListName[]; +ABSL_CONST_INIT extern const char + kNearbySharingPublicCertificateExpirationDictName[]; +ABSL_CONST_INIT extern const char + kNearbySharingSchedulerContactDownloadAndUploadName[]; +ABSL_CONST_INIT extern const char + kNearbySharingSchedulerDownloadDeviceDataName[]; +ABSL_CONST_INIT extern const char + kNearbySharingSchedulerDownloadPublicCertificatesName[]; +ABSL_CONST_INIT extern const char + kNearbySharingSchedulerPeriodicContactUploadName[]; +ABSL_CONST_INIT extern const char + kNearbySharingSchedulerPrivateCertificateExpirationName[]; +ABSL_CONST_INIT extern const char + kNearbySharingSchedulerPublicCertificateExpirationName[]; +ABSL_CONST_INIT extern const char kNearbySharingSchedulerUploadDeviceNameName[]; +ABSL_CONST_INIT extern const char + kNearbySharingSchedulerUploadLocalDeviceCertificatesName[]; +ABSL_CONST_INIT extern const char kNearbySharingUsersName[]; +ABSL_CONST_INIT extern const char kNearbySharingIsReceivingName[]; +ABSL_CONST_INIT extern const char kNearbySharingIsAnalyticsEnabledName[]; +ABSL_CONST_INIT extern const char kNearbySharingIsAllContactsEnabledName[]; +ABSL_CONST_INIT extern const char kNearbySharingAutoAppStartEnabledName[]; + +ABSL_CONST_INIT const proto::DeviceVisibility kDefaultVisibility = + proto::DeviceVisibility::DEVICE_VISIBILITY_HIDDEN; +ABSL_CONST_INIT const proto::DeviceVisibility kDefaultFallbackVisibility = + proto::DeviceVisibility::DEVICE_VISIBILITY_HIDDEN; +ABSL_CONST_INIT const int kDefaultMaxVisibilityExpirationSeconds = 300; + +void RegisterNearbySharingPrefs( + nearby::sharing::api::PreferenceManager& preference_manager, + bool skip_persistent_ones = false); + +void ResetSchedulers( + nearby::sharing::api::PreferenceManager& preference_manager); + +} // namespace prefs +} // namespace sharing +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_COMMON_NEARBY_SHARE_PREFS_H_ diff --git a/sharing/common/nearby_share_profile_info_provider.h b/sharing/common/nearby_share_profile_info_provider.h new file mode 100644 index 00000000..0de5feb1 --- /dev/null +++ b/sharing/common/nearby_share_profile_info_provider.h @@ -0,0 +1,39 @@ +// 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 THIRD_PARTY_NEARBY_SHARING_COMMON_NEARBY_SHARE_PROFILE_INFO_PROVIDER_H_ +#define THIRD_PARTY_NEARBY_SHARING_COMMON_NEARBY_SHARE_PROFILE_INFO_PROVIDER_H_ + +#include +#include + +namespace nearby { +namespace sharing { +class NearbyShareProfileInfoProvider { + public: + NearbyShareProfileInfoProvider() = default; + virtual ~NearbyShareProfileInfoProvider() = default; + + // Returns UTF-8 encoded given name of current account. + // Returns absl::nullopt if a valid given name cannot be returned. + virtual std::optional GetGivenName() const = 0; + + // Proxy for Profile::GetProfileUserName(). Returns absl::nullopt if a valid + // username cannot be returned. + virtual std::optional GetProfileUserName() const = 0; +}; +} // namespace sharing +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_COMMON_NEARBY_SHARE_PROFILE_INFO_PROVIDER_H_ diff --git a/sharing/common/nearby_share_switches.cc b/sharing/common/nearby_share_switches.cc new file mode 100644 index 00000000..df4ff3a3 --- /dev/null +++ b/sharing/common/nearby_share_switches.cc @@ -0,0 +1,41 @@ +// 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 "sharing/common/nearby_share_switches.h" + +#include +#include + +namespace nearby { +namespace sharing { +namespace switches { + +int global_host_size = 0; +char global_host[256]; + +void SetNearbySharedHttpHost(const std::string& host) { + if (host.size() > 256) { + return; + } + global_host_size = host.size(); + memcpy(global_host, host.c_str(), global_host_size); +} + +std::string GetNearbySharedHttpHost() { + return std::string(global_host, global_host_size); +} + +} // namespace switches +} // namespace sharing +} // namespace nearby diff --git a/sharing/common/nearby_share_switches.h b/sharing/common/nearby_share_switches.h new file mode 100644 index 00000000..61abfd5f --- /dev/null +++ b/sharing/common/nearby_share_switches.h @@ -0,0 +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 THIRD_PARTY_NEARBY_SHARING_COMMON_NEARBY_SHARE_SWITCHES_H_ +#define THIRD_PARTY_NEARBY_SHARING_COMMON_NEARBY_SHARE_SWITCHES_H_ + +#include + +namespace nearby { +namespace sharing { +namespace switches { + +// All switches in alphabetical order. The switches should be documented +// alongside the definition of their values in the .cc file. + +void SetNearbySharedHttpHost(const std::string& host); +std::string GetNearbySharedHttpHost(); + +} // namespace switches +} // namespace sharing +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_COMMON_NEARBY_SHARE_SWITCHES_H_ diff --git a/sharing/internal/api/BUILD b/sharing/internal/api/BUILD new file mode 100644 index 00000000..795111af --- /dev/null +++ b/sharing/internal/api/BUILD @@ -0,0 +1,73 @@ +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +licenses(["notice"]) + +cc_library( + name = "platform", + hdrs = [ + "app_info.h", + "bluetooth_adapter.h", + "fast_init_ble_beacon.h", + "fast_initiation_manager.h", + "network_monitor.h", + "preference_manager.h", + "private_certificate_data.h", + "public_certificate_database.h", + "sharing_platform.h", + "shell.h", + "system_info.h", + "wifi_adapter.h", + ], + visibility = [ + "//location/nearby/analytics/cpp/logging:__pkg__", + "//location/nearby/apps/better_together/macos/nearby_share:__subpackages__", + "//location/nearby/cpp/sharing:__subpackages__", + "//sharing:__subpackages__", + ], + deps = [ + "//internal/platform:types", + "//internal/platform/implementation:types", + "//sharing/proto:share_cc_proto", + "@com_google_absl//absl/functional:any_invocable", + "@com_google_absl//absl/status", + "@com_google_absl//absl/strings:string_view", + "@com_google_absl//absl/time", + "@com_google_absl//absl/types:span", + ], +) + +cc_library( + name = "mock_sharing_platform", + testonly = True, + hdrs = [ + "mock_app_info.h", + "mock_bluetooth_adapter.h", + "mock_network_monitor.h", + "mock_public_certificate_db.h", + "mock_sharing_platform.h", + "mock_system_info.h", + ], + visibility = ["//visibility:public"], + deps = [ + ":platform", + "//internal/platform:types", + "//internal/platform/implementation:types", + "@com_google_absl//absl/functional:any_invocable", + "@com_google_absl//absl/status", + "@com_google_absl//absl/strings", + "@com_google_absl//absl/types:span", + "@com_google_googletest//:gtest_for_library_testonly", + ], +) diff --git a/sharing/internal/api/app_info.h b/sharing/internal/api/app_info.h new file mode 100644 index 00000000..2efe2c4b --- /dev/null +++ b/sharing/internal/api/app_info.h @@ -0,0 +1,61 @@ +// Copyright 2023 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_APP_INFO_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_APP_INFO_H_ + +#include +#include + +namespace nearby { +namespace api { + +// AppInfo provides information about the app, such as version, update track and +// language. +class AppInfo { + public: + virtual ~AppInfo() = default; + + // The current app version, e.g. "1.0.4.2". + virtual std::optional GetAppVersion() = 0; + + // The language the user uses in the app. This should only include the + // language code and not the region code, e.g. "en" NOT "en_US". + virtual std::optional GetAppLanguage() = 0; + + // The track to update the app. + // + // In NearbyShare Windows app, it's from the registry value set by the + // installer, and could be "NearbyManualQA", "NearbyDeveloper", + // "NearbyDogfood". + // + // It's a string instead of enum to provide flexibility so that any new value + // can be recognized without adding the enum value first. + virtual std::optional GetUpdateTrack() = 0; + + // Indicates how the client desktop application was installed on the device, + // e.g. manually installed by the user or OEM preinstall. + virtual std::optional GetAppInstallSource() = 0; + + // Whether the app install event has already been logged. + virtual bool GetFirstRunDone() = 0; + + // Sets whether the app install event has been logged. + virtual bool SetFirstRunDone(bool value) = 0; +}; + +} // namespace api +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_APP_INFO_H_ diff --git a/sharing/internal/api/bluetooth_adapter.h b/sharing/internal/api/bluetooth_adapter.h new file mode 100644 index 00000000..63527d54 --- /dev/null +++ b/sharing/internal/api/bluetooth_adapter.h @@ -0,0 +1,105 @@ +// Copyright 2022 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_BLUETOOTH_ADAPTER_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_BLUETOOTH_ADAPTER_H_ + +#include +#include +#include +#include + +namespace nearby { +namespace sharing { +namespace api { + +class BluetoothAdapter { + public: + enum class PermissionStatus { + kUndetermined = 0, + kSystemDenied, + kUserDenied, + kAllowed + }; + + class Observer { + public: + virtual ~Observer() = default; + + // Called when the presence of the adapter |adapter| changes. When |present| + // is true the adapter is now present, false means the adapter has been + // removed from the system. + virtual void AdapterPresentChanged(BluetoothAdapter* adapter, + bool present) {} + + // Called when the radio power state of the adapter |adapter| changes. When + // |powered| is true the adapter radio is powered, false means the adapter + // radio is off. + virtual void AdapterPoweredChanged(BluetoothAdapter* adapter, + bool powered) {} + }; + + virtual ~BluetoothAdapter() = default; + + // Indicates whether the adapter is actually present on the system. An adapter + // is only considered present if the bluetooth mac address has been obtained. + virtual bool IsPresent() const = 0; + + // Indicates whether the adapter radio is powered. + virtual bool IsPowered() const = 0; + + // Indicates whether the adapter supports BLE. + virtual bool IsLowEnergySupported() const = 0; + + // Indicates whether the adapter supports BLE offloads to scan. + virtual bool IsScanOffloadSupported() const = 0; + + // Indicates whether the adapter supports BLE advertisement offload. + virtual bool IsAdvertisementOffloadSupported() const = 0; + + // Indicates whether the adapter supports BLE 5.0 Extended Advertising. + virtual bool IsExtendedAdvertisingSupported() const = 0; + + // Indicates whether the adapter supports BLE Peripheral Role. + virtual bool IsPeripheralRoleSupported() const = 0; + + // Returns the status of the browser's Bluetooth permission status. + virtual PermissionStatus GetOsPermissionStatus() const = 0; + + // Requests a change to the adapter radio power. Setting |powered| to true + // will turn on the radio and false will turn it off. On success, + // |success_callback| will be called. On failure, |error_callback| will be + // called. + virtual void SetPowered(bool powered, std::function success_callback, + std::function error_callback) = 0; + + // The unique ID/name of this adapter. + virtual std::optional GetAdapterId() const = 0; + + // The mac address of this adapter. + virtual std::optional> GetAddress() const = 0; + + // Adds and removes observers for events on this bluetooth adapter. If + // monitoring multiple adapters, check the |adapter| parameter of observer + // methods to determine which adapter is issuing the event. + virtual void AddObserver(Observer* observer) = 0; + virtual void RemoveObserver(Observer* observer) = 0; + virtual bool HasObserver(Observer* observer) = 0; +}; + +} // namespace api +} // namespace sharing +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_BLUETOOTH_ADAPTER_H_ diff --git a/sharing/internal/api/fast_init_ble_beacon.h b/sharing/internal/api/fast_init_ble_beacon.h new file mode 100644 index 00000000..0a578a9d --- /dev/null +++ b/sharing/internal/api/fast_init_ble_beacon.h @@ -0,0 +1,151 @@ +// Copyright 2022 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_FAST_INIT_BLE_BEACON_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_FAST_INIT_BLE_BEACON_H_ + +#include +#include + +namespace nearby { +namespace api { + +class FastInitBleBeacon { + public: + // Possible types of error raised while registering or unregistering Fast + // Initiation BLE Beacon. + enum class ErrorCode : int { + kUnsupportedPlatform = 0, // BLE Beacon not supported + // on current platform. + kBeaconAlreadyExists, // A BLE Beacon is already + // registered. + kBeaconDoesNotExist, // Unregistering a BLE Beacon which + // is not registered. + kBeaconInvalidLength, // BLE Beacon is not of a valid + // length. + kFailToStartBeacon, // Error when starting the BLE Beacon + // scanning/advertising through a platform API. + kFailToStopBeacon, // Error when stopping the BLE Beacon + // scanning/advertising through a platform API. + kFailToResetBeacon, // Error while resetting BLE Beacon. + kAdapterPoweredOff, // Error because the adapter is off + kUnknown + }; + + enum class FastInitVersion : int { kV1 = 0 }; + + enum class FastInitType : int { kNotify = 0, kSilent = 1 }; + + static constexpr uint8_t kFastInitServiceUuid[] = {0xfe, 0x2c}; + static constexpr uint8_t kFastInitModelId[] = {0xfc, 0x12, 0x8e}; + + // Size of fields in AdvertisingData Service Data (in bytes) + static constexpr uint8_t kFastInitServiceUuidSize = 2; + static constexpr uint8_t kFastInitModelIdSize = 3; + // FastInit V1 Metadata (2 bytes) + // (1 byte) [ version (3 bits) | type (3 bits) | uwb_supported (1 bit) | + // sender_cert_supported (1 bit)] + // (1 byte) [ adjusted_tx_power] + static constexpr uint8_t kUwbMetadataSize = 1; + static constexpr uint8_t kUwbAddressSize = 8; + static constexpr uint8_t kSaltSize = 1; + static constexpr uint8_t kSecretIdHashSize = 8; + + // require_bt_advertising (1 bit) | self_only_advertising (1 bit) | + // unused (6 bits) + static constexpr uint8_t kRequireBtAdvertising = 1; + static constexpr uint8_t kSelfOnlyAdvertising = 1; + + static constexpr uint8_t kAdvertiseDataTotalSize = 26; + + virtual ~FastInitBleBeacon() = default; + + FastInitVersion GetVersion() const { return version_; } + FastInitType GetType() const { return type_; } + bool GetUwbSupported() const { return is_uwb_supported_; } + bool GetSenderCertSupported() const { return is_sender_cert_supported_; } + int8_t GetAdjustedTxPower() const { return adjusted_tx_power_; } + std::array GetUwbMetadata() const { + return uwb_metadata_; + } + std::array GetUwbAddress() const { + return uwb_address_; + } + std::array GetSalt() const { return salt_; } + std::array GetSecretIdHash() const { + return secret_id_hash_; + } + bool GetRequireBtAdvertising() const { return require_bt_advertising_; } + bool GetSelfOnlyAdvertising() const { return self_only_advertising_; } + + void SetVersion(FastInitVersion version) { version_ = version; } + void SetType(FastInitType type) { type_ = type; } + void SetUwbSupported(bool is_supported) { is_uwb_supported_ = is_supported; } + void SetSenderCertSupported(bool is_supported) { + is_sender_cert_supported_ = is_supported; + } + void SetAdjustedTxPower(int8_t signed_value) { + adjusted_tx_power_ = signed_value; + } + void SetUwbMetadata(std::array byte_array) { + uwb_metadata_ = byte_array; + } + void SetUwbAddress(std::array byte_array) { + uwb_address_ = byte_array; + } + void SetSalt(std::array byte_array) { + salt_ = byte_array; + } + void SetSecretIdHash(std::array byte_array) { + secret_id_hash_ = byte_array; + } + + std::array GetAdDataByteArray() { + return advertising_data_byte_array_; + } + void SetAdDataByteArray( + std::array byte_array) { + advertising_data_byte_array_ = byte_array; + } + + void SetRequireBtAdvertising(bool require_bt_advertising) { + require_bt_advertising_ = require_bt_advertising; + } + void SetSelfOnlyAdvertising(bool self_only_advertising) { + self_only_advertising_ = self_only_advertising; + } + + virtual void SerializeToByteArray() = 0; + virtual void ParseFromByteArray() = 0; + + protected: + FastInitVersion version_; + FastInitType type_; + bool is_uwb_supported_; + bool is_sender_cert_supported_; + int8_t adjusted_tx_power_; + std::array uwb_metadata_; + std::array uwb_address_; + std::array salt_; + std::array secret_id_hash_; + bool require_bt_advertising_; + bool self_only_advertising_; + + std::array advertising_data_byte_array_; +}; + +} // namespace api +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_FAST_INIT_BLE_BEACON_H_ diff --git a/sharing/internal/api/fast_initiation_manager.h b/sharing/internal/api/fast_initiation_manager.h new file mode 100644 index 00000000..aec7c3be --- /dev/null +++ b/sharing/internal/api/fast_initiation_manager.h @@ -0,0 +1,65 @@ +// Copyright 2022 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_FAST_INITIATION_MANAGER_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_FAST_INITIATION_MANAGER_H_ + +#include + +#include "sharing/internal/api/fast_init_ble_beacon.h" + +namespace nearby { +namespace api { + +class FastInitiationManager { + public: + enum class Error : int { + kUnknown = 0, + kBluetoothRadioUnavailable, + kResourceInUse, + kDisabledByPolicy, + kDisabledByUser, + kHardwareNotSupported, + kTransportNotSupported, + kConsentRequired + }; + + FastInitiationManager() = default; + virtual ~FastInitiationManager() = default; + + virtual void StartAdvertising( + api::FastInitBleBeacon::FastInitType type, + std::function callback, + std::function + error_callback) = 0; + + virtual void StopAdvertising(std::function callback) = 0; + + virtual void StartScanning( + std::function devices_discovered_callback, + std::function devices_not_discovered_callback, + std::function + error_callback) = 0; + + virtual void StopScanning(std::function callback) = 0; + + virtual bool IsAdvertising() = 0; + + virtual bool IsScanning() = 0; +}; + +} // namespace api +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_FAST_INITIATION_MANAGER_H_ diff --git a/sharing/internal/api/mock_app_info.h b/sharing/internal/api/mock_app_info.h new file mode 100644 index 00000000..1d9a5c94 --- /dev/null +++ b/sharing/internal/api/mock_app_info.h @@ -0,0 +1,49 @@ +// Copyright 2023 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_MOCK_APP_INFO_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_MOCK_APP_INFO_H_ + +#include +#include + +#include "sharing/internal/api/app_info.h" + +#include "gmock/gmock.h" + +namespace nearby::sharing::api { + +class MockAppInfo : public nearby::api::AppInfo { + public: + MockAppInfo() = default; + MockAppInfo(const MockAppInfo&) = delete; + MockAppInfo& operator=(const MockAppInfo&) = delete; + ~MockAppInfo() override = default; + + MOCK_METHOD(std::optional, GetAppVersion, (), (override)); + + MOCK_METHOD(std::optional, GetAppLanguage, (), (override)); + + MOCK_METHOD(std::optional, GetUpdateTrack, (), (override)); + + MOCK_METHOD(std::optional, GetAppInstallSource, (), (override)); + + MOCK_METHOD(bool, GetFirstRunDone, (), (override)); + + MOCK_METHOD(bool, SetFirstRunDone, (bool value), (override)); +}; + +} // namespace nearby::sharing::api + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_MOCK_APP_INFO_H_ diff --git a/sharing/internal/api/mock_bluetooth_adapter.h b/sharing/internal/api/mock_bluetooth_adapter.h new file mode 100644 index 00000000..66cce74f --- /dev/null +++ b/sharing/internal/api/mock_bluetooth_adapter.h @@ -0,0 +1,58 @@ +// Copyright 2023 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_MOCK_BLUETOOTH_ADAPTER_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_MOCK_BLUETOOTH_ADAPTER_H_ + +#include +#include +#include +#include +#include + +#include "gmock/gmock.h" +#include "sharing/internal/api/bluetooth_adapter.h" + +namespace nearby::sharing::api { + +class MockBluetoothAdapter : public nearby::sharing::api::BluetoothAdapter { + public: + MockBluetoothAdapter() = default; + MockBluetoothAdapter(const MockBluetoothAdapter&) = delete; + MockBluetoothAdapter& operator=(const MockBluetoothAdapter&) = delete; + ~MockBluetoothAdapter() override = default; + + MOCK_METHOD(bool, IsPresent, (), (const, override)); + MOCK_METHOD(bool, IsPowered, (), (const, override)); + MOCK_METHOD(bool, IsLowEnergySupported, (), (const, override)); + MOCK_METHOD(bool, IsScanOffloadSupported, (), (const, override)); + MOCK_METHOD(bool, IsAdvertisementOffloadSupported, (), (const, override)); + MOCK_METHOD(bool, IsExtendedAdvertisingSupported, (), (const, override)); + MOCK_METHOD(bool, IsPeripheralRoleSupported, (), (const, override)); + MOCK_METHOD(PermissionStatus, GetOsPermissionStatus, (), (const, override)); + MOCK_METHOD(void, SetPowered, + (bool powered, std::function success_callback, + std::function error_callback), + (override)); + MOCK_METHOD(std::optional, GetAdapterId, (), (const, override)); + MOCK_METHOD((std::optional>), GetAddress, (), + (const, override)); + MOCK_METHOD(void, AddObserver, (Observer * observer), (override)); + MOCK_METHOD(void, RemoveObserver, (Observer * observer), (override)); + MOCK_METHOD(bool, HasObserver, (Observer * observer), (override)); +}; + +} // namespace nearby::sharing::api + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_MOCK_BLUETOOTH_ADAPTER_H_ diff --git a/sharing/internal/api/mock_network_monitor.h b/sharing/internal/api/mock_network_monitor.h new file mode 100644 index 00000000..5a2ca490 --- /dev/null +++ b/sharing/internal/api/mock_network_monitor.h @@ -0,0 +1,38 @@ +// Copyright 2023 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_MOCK_NETWORK_MONITOR_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_MOCK_NETWORK_MONITOR_H_ + +#include "sharing/internal/api/network_monitor.h" + +#include "gmock/gmock.h" + +namespace nearby::sharing::api { + +class MockNetworkMonitor : public nearby::api::NetworkMonitor { + public: + MockNetworkMonitor() : nearby::api::NetworkMonitor(nullptr) {} + MockNetworkMonitor(const MockNetworkMonitor&) = delete; + MockNetworkMonitor& operator=(const MockNetworkMonitor&) = delete; + ~MockNetworkMonitor() override = default; + + MOCK_METHOD(bool, IsLanConnected, (), (override)); + + MOCK_METHOD(ConnectionType, GetCurrentConnection, (), (override)); +}; + +} // namespace nearby::sharing::api + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_MOCK_NETWORK_MONITOR_H_ diff --git a/sharing/internal/api/mock_public_certificate_db.h b/sharing/internal/api/mock_public_certificate_db.h new file mode 100644 index 00000000..e289ce54 --- /dev/null +++ b/sharing/internal/api/mock_public_certificate_db.h @@ -0,0 +1,59 @@ +// Copyright 2024 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_MOCK_PUBLIC_CERTIFICATE_DB_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_MOCK_PUBLIC_CERTIFICATE_DB_H_ + +#include +#include +#include + +#include "gmock/gmock.h" +#include "absl/functional/any_invocable.h" +#include "absl/types/span.h" +#include "sharing/internal/api/public_certificate_database.h" + +namespace nearby::sharing::api { +class MockPublicCertificateDb : public PublicCertificateDatabase { + public: + MockPublicCertificateDb() = default; + MockPublicCertificateDb(const PublicCertificateDatabase&) = delete; + MockPublicCertificateDb& operator=(const PublicCertificateDatabase&) = delete; + ~MockPublicCertificateDb() override = default; + + MOCK_METHOD(void, Initialize, + (absl::AnyInvocable callback), (override)); + MOCK_METHOD( + void, LoadEntries, + (absl::AnyInvocable< + void(bool, std::unique_ptr>) &&> + callback), + (override)); + MOCK_METHOD( + void, AddCertificates, + (absl::Span certificates, + absl::AnyInvocable callback), + (override)); + MOCK_METHOD(void, RemoveCertificatesById, + (std::vector ids_to_remove, + absl::AnyInvocable callback), + (override)); + MOCK_METHOD(void, Destroy, (absl::AnyInvocable callback), + (override)); +}; + +} // namespace nearby::sharing::api + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_MOCK_PUBLIC_CERTIFICATE_DB_H_ diff --git a/sharing/internal/api/mock_sharing_platform.h b/sharing/internal/api/mock_sharing_platform.h new file mode 100644 index 00000000..d9159e16 --- /dev/null +++ b/sharing/internal/api/mock_sharing_platform.h @@ -0,0 +1,100 @@ +// Copyright 2023 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_MOCK_SHARING_PLATFORM_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_MOCK_SHARING_PLATFORM_H_ + +#include +#include + +#include "gmock/gmock.h" +#include "absl/status/status.h" +#include "absl/strings/string_view.h" +#include "internal/platform/device_info.h" +#include "internal/platform/implementation/account_manager.h" +#include "internal/platform/task_runner.h" +#include "sharing/internal/api/app_info.h" +#include "sharing/internal/api/bluetooth_adapter.h" +#include "sharing/internal/api/fast_init_ble_beacon.h" +#include "sharing/internal/api/fast_initiation_manager.h" +#include "sharing/internal/api/network_monitor.h" +#include "sharing/internal/api/preference_manager.h" +#include "sharing/internal/api/public_certificate_database.h" +#include "sharing/internal/api/sharing_platform.h" +#include "sharing/internal/api/shell.h" +#include "sharing/internal/api/system_info.h" +#include "sharing/internal/api/wifi_adapter.h" + +namespace nearby::sharing::api { + +class MockSharingPlatform : public SharingPlatform { + public: + MockSharingPlatform() = default; + MockSharingPlatform(const MockSharingPlatform&) = delete; + MockSharingPlatform& operator=(const MockSharingPlatform&) = delete; + ~MockSharingPlatform() override = default; + + MOCK_METHOD(void, InitLogging, (), (override)); + + MOCK_METHOD(void, UpdateLoggingLevel, (), (override)); + + MOCK_METHOD( + std::unique_ptr, CreateNetworkMonitor, + (std::function + callback), + (override)); + + MOCK_METHOD(nearby::sharing::api::BluetoothAdapter&, GetBluetoothAdapter, (), + (override)); + + MOCK_METHOD(nearby::sharing::api::WifiAdapter&, GetWifiAdapter, (), + (override)); + + MOCK_METHOD(void, LaunchDefaultBrowserFromURL, + (absl::string_view url, + std::function callback), + (override)); + + MOCK_METHOD(nearby::api::Shell&, GetShell, (), (override)); + + MOCK_METHOD(nearby::api::FastInitBleBeacon&, GetFastInitBleBeacon, (), + (override)); + + MOCK_METHOD(nearby::api::FastInitiationManager&, GetFastInitiationManager, (), + (override)); + + MOCK_METHOD(void, CopyText, + (absl::string_view text, + std::function callback), + (override)); + + MOCK_METHOD(std::unique_ptr, CreateSystemInfo, (), + (override)); + + MOCK_METHOD(std::unique_ptr, CreateAppInfo, (), + (override)); + + MOCK_METHOD(PreferenceManager&, GetPreferenceManager, (), (override)); + + MOCK_METHOD(AccountManager&, GetAccountManager, (), (override)); + MOCK_METHOD(TaskRunner&, GetDefaultTaskRunner, (), (override)); + MOCK_METHOD(nearby::DeviceInfo&, GetDeviceInfo, (), (override)); + MOCK_METHOD(std::unique_ptr, + CreatePublicCertificateDatabase, + (absl::string_view database_path), (override)); +}; + +} // namespace nearby::sharing::api + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_MOCK_SHARING_PLATFORM_H_ diff --git a/sharing/internal/api/mock_system_info.h b/sharing/internal/api/mock_system_info.h new file mode 100644 index 00000000..6c6a6b98 --- /dev/null +++ b/sharing/internal/api/mock_system_info.h @@ -0,0 +1,66 @@ +// Copyright 2023 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_MOCK_SYSTEM_INFO_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_MOCK_SYSTEM_INFO_H_ + +#include +#include +#include + +#include "gmock/gmock.h" +#include "absl/strings/string_view.h" +#include "sharing/internal/api/system_info.h" + +namespace nearby::sharing::api { + +class MockSystemInfo : public nearby::api::SystemInfo { + public: + MockSystemInfo() = default; + MockSystemInfo(const MockSystemInfo&) = delete; + MockSystemInfo& operator=(const MockSystemInfo&) = delete; + ~MockSystemInfo() override = default; + + MOCK_METHOD(std::string, GetComputerManufacturer, (), (override)); + MOCK_METHOD(std::string, GetComputerModel, (), (override)); + MOCK_METHOD(int64_t, GetComputerPhysicalMemory, (), (override)); + MOCK_METHOD(int, GetComputerProcessorCount, (), (override)); + MOCK_METHOD(int, GetComputerLogicProcessorCount, (), (override)); + MOCK_METHOD(int, GetProcessorMemoryInfo, (), (override)); + + MOCK_METHOD(BatteryChargeStatus, QueryBatteryInfo, + (int& seconds, int& percent, bool& battery_saver), (override)); + + // Operating system related information. + MOCK_METHOD(std::string, GetOsManufacturer, (), (override)); + MOCK_METHOD(std::string, GetOsName, (), (override)); + MOCK_METHOD(std::string, GetOsVersion, (), (override)); + MOCK_METHOD(std::string, GetOsArchitecture, (), (override)); + MOCK_METHOD(std::string, GetOsLanguage, (), (override)); + + // CPU related information. + MOCK_METHOD(std::string, GetProcessorManufacturer, (), (override)); + MOCK_METHOD(std::string, GetProcessorName, (), (override)); + + // Driver related information. + MOCK_METHOD(std::list, GetBluetoothDriverInfos, (), (override)); + MOCK_METHOD(std::list, GetNetworkDriverInfos, (), (override)); + + MOCK_METHOD(void, GetBatteryUsageReport, (absl::string_view save_path), + (override)); +}; + +} // namespace nearby::sharing::api + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_MOCK_SYSTEM_INFO_H_ diff --git a/sharing/internal/api/network_monitor.h b/sharing/internal/api/network_monitor.h new file mode 100644 index 00000000..bf0e45aa --- /dev/null +++ b/sharing/internal/api/network_monitor.h @@ -0,0 +1,61 @@ +// Copyright 2022 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_NETWORK_MONITOR_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_NETWORK_MONITOR_H_ + +#include +#include +#include + +namespace nearby { +namespace api { + +class NetworkMonitor { + public: + enum class ConnectionType : int { + kUnknown = 0, // A connection exists, but its type is unknown. + // Also used as a default value. + kEthernet = 1, + kWifi = 2, + k2G = 3, + k3G = 4, + k4G = 5, + kNone = 6, // No connection. + kBluetooth = 7, + k5G = 8, + kLast = k5G + }; + + explicit NetworkMonitor(std::function callback) { + callback_ = std::move(callback); + } + + virtual ~NetworkMonitor() = default; + + // Returns true if connected to an AP (Access Point), not necessarily + // connected to the internet + virtual bool IsLanConnected() = 0; + + // Returns the type of connection used currently to access the internet + virtual ConnectionType GetCurrentConnection() = 0; + + protected: + std::function callback_; +}; + +} // namespace api +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_NETWORK_MONITOR_H_ diff --git a/sharing/internal/api/preference_manager.h b/sharing/internal/api/preference_manager.h new file mode 100644 index 00000000..c15d57bb --- /dev/null +++ b/sharing/internal/api/preference_manager.h @@ -0,0 +1,132 @@ +// Copyright 2023 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_PREFERENCE_MANAGER_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_PREFERENCE_MANAGER_H_ + +#include +#include +#include +#include +#include +#include + +#include "absl/strings/string_view.h" +#include "absl/time/time.h" +#include "absl/types/span.h" +#include "sharing/internal/api/private_certificate_data.h" + +namespace nearby::sharing::api { + +class PreferenceManager { + public: + virtual ~PreferenceManager() = default; + + virtual void SetBoolean(absl::string_view key, bool value) = 0; + virtual void SetInteger(absl::string_view key, int value) = 0; + virtual void SetInt64(absl::string_view key, int64_t value) = 0; + virtual void SetString(absl::string_view key, absl::string_view value) = 0; + virtual void SetTime(absl::string_view key, absl::Time value) = 0; + + // Array operations, where key contains an array. + virtual void SetBooleanArray(absl::string_view key, + absl::Span value) = 0; + virtual void SetIntegerArray(absl::string_view key, + absl::Span value) = 0; + virtual void SetInt64Array(absl::string_view key, + absl::Span value) = 0; + virtual void SetStringArray(absl::string_view key, + absl::Span value) = 0; + virtual void SetPrivateCertificateArray( + absl::string_view key, + absl::Span value) = 0; + // Expiration data is a std::pair containing the certificate ID base64 encoded + // according to RFC 4648 section 5 and the expiration time in nanos since Unix + // Epoch. + virtual void SetCertificateExpirationArray( + absl::string_view key, + absl::Span> value) = 0; + + // Dictionary operations, where key contains a dictionary, and dictionary_item + // is modified. + // If key is empty, a new dictionary containing the new dictionary_item is + // created. + // If key exists and does not contain a dictionary, the operation fails + // silently. + virtual void SetDictionaryBooleanValue(absl::string_view key, + absl::string_view dictionary_item, + bool value) = 0; + virtual void SetDictionaryIntegerValue(absl::string_view key, + absl::string_view dictionary_item, + int value) = 0; + virtual void SetDictionaryInt64Value(absl::string_view key, + absl::string_view dictionary_item, + int64_t value) = 0; + virtual void SetDictionaryStringValue(absl::string_view key, + absl::string_view dictionary_item, + std::string value) = 0; + virtual void RemoveDictionaryItem(absl::string_view key, + absl::string_view dictionary_item) = 0; + // Gets values + virtual bool GetBoolean(absl::string_view key, bool default_value) const = 0; + virtual int GetInteger(absl::string_view key, int default_value) const = 0; + virtual int64_t GetInt64(absl::string_view key, + int64_t default_value) const = 0; + virtual std::string GetString(absl::string_view key, + const std::string& default_value) const = 0; + virtual absl::Time GetTime(absl::string_view key, + absl::Time default_value) const = 0; + + virtual std::vector GetBooleanArray( + absl::string_view key, absl::Span default_value) const = 0; + virtual std::vector GetIntegerArray( + absl::string_view key, absl::Span default_value) const = 0; + virtual std::vector GetInt64Array( + absl::string_view key, absl::Span default_value) const = 0; + virtual std::vector GetStringArray( + absl::string_view key, + absl::Span default_value) const = 0; + virtual std::vector GetPrivateCertificateArray( + absl::string_view key) const = 0; + // Expiration data is a std::pair containing the certificate ID base64 encoded + // according to RFC 4648 section 5 and the expiration time in nanos since Unix + // Epoch. + virtual std::vector> + GetCertificateExpirationArray(absl::string_view key) const = 0; + + // Dictionary operations, where key contains a dictionary. + // If key does not exist, does not contain a dictionary, or the dictionary + // does not contain dictionary_item, std::nullopt is returned. + virtual std::optional GetDictionaryBooleanValue( + absl::string_view key, absl::string_view dictionary_item) const = 0; + virtual std::optional GetDictionaryIntegerValue( + absl::string_view key, absl::string_view dictionary_item) const = 0; + virtual std::optional GetDictionaryInt64Value( + absl::string_view key, absl::string_view dictionary_item) const = 0; + virtual std::optional GetDictionaryStringValue( + absl::string_view key, absl::string_view dictionary_item) const = 0; + + // Removes preferences + virtual void Remove(absl::string_view key) = 0; + + // Adds preference observer + virtual void AddObserver( + absl::string_view name, + std::function observer) = 0; + virtual void RemoveObserver(absl::string_view name) = 0; +}; + +} // namespace nearby::sharing::api + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_PREFERENCE_MANAGER_H_ diff --git a/sharing/internal/api/private_certificate_data.h b/sharing/internal/api/private_certificate_data.h new file mode 100644 index 00000000..9a18ff2c --- /dev/null +++ b/sharing/internal/api/private_certificate_data.h @@ -0,0 +1,75 @@ +// Copyright 2023 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_PRIVATE_CERTIFICATE_DATA_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_PRIVATE_CERTIFICATE_DATA_H_ + +#include +#include + +namespace nearby::sharing::api { + +// Intermediate data structure for serializing NearbySharePrivateCertificate +// into preference storage. +struct PrivateCertificateData { + // Dictionary keys used in serialization to and from JSON. + static inline constexpr char kVisibility[] = "visibility"; + static inline constexpr char kNotBefore[] = "not_before"; + static inline constexpr char kNotAfter[] = "not_after"; + static inline constexpr char kKeyPair[] = "key_pair"; + static inline constexpr char kSecretKey[] = "secret_key"; + static inline constexpr char kMetadataEncryptionKey[] = + "metadata_encryption_key"; + static inline constexpr char kId[] = "id"; + static inline constexpr char kUnencryptedMetadata[] = "unencrypted_metadata"; + static inline constexpr char kConsumedSalts[] = "consumed_salts"; + + // One of the DeviceVisibility values. + int visibility; + // Not before time in nanos since Unix epoch + int64_t not_before; + // Not after time in nanos since Unix epoch + int64_t not_after; + // Private key in PKCS #8 PrivateKeyInfo block base64 encoded according to + // RFC 4648 section 5. + std::string key_pair; + // Secret key base64 encoded according to RFC 4648 section 5. + std::string secret_key; + // Metadata encryption key base64 encoded according to RFC 4648 section 5. + std::string metadata_encryption_key; + // Certificate ID base64 encoded according to RFC 4648 section 5. + std::string id; + // Serialized clear text metadata proto base64 encoded according to RFC 4648 + // section 5. + std::string unencrypted_metadata_proto; + // Concatenation of hex encoded 2byte salt values that have already been used. + std::string consumed_salts; +}; + +inline bool operator==(const PrivateCertificateData& lhs, + const PrivateCertificateData& rhs) { + return lhs.visibility == rhs.visibility && + lhs.not_before == rhs.not_before && + lhs.not_after == rhs.not_after && + lhs.key_pair == rhs.key_pair && + lhs.secret_key == rhs.secret_key && + lhs.metadata_encryption_key == rhs.metadata_encryption_key && + lhs.id == rhs.id && + lhs.unencrypted_metadata_proto == rhs.unencrypted_metadata_proto && + lhs.consumed_salts == rhs.consumed_salts; +} + +} // namespace nearby::sharing::api + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_PRIVATE_CERTIFICATE_DATA_H_ diff --git a/sharing/internal/api/public_certificate_database.h b/sharing/internal/api/public_certificate_database.h new file mode 100644 index 00000000..4c6b0e51 --- /dev/null +++ b/sharing/internal/api/public_certificate_database.h @@ -0,0 +1,76 @@ +// Copyright 2023 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_PUBLIC_CERTIFICATE_DATABASE_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_PUBLIC_CERTIFICATE_DATABASE_H_ + +#include +#include +#include + +#include "absl/functional/any_invocable.h" +#include "absl/types/span.h" +#include "sharing/proto/rpc_resources.pb.h" + +namespace nearby::sharing::api { + +class PublicCertificateDatabase { + public: + enum class InitStatus { + // Initialization successful. + kOk = 0, + // Failed to create database. + kError = 1, + // Existing database files are corrupt. Caller should delete the database + // and try to create it again. + kCorrupt = 2, + }; + + PublicCertificateDatabase() = default; + virtual ~PublicCertificateDatabase() = default; + + // Asynchronously initializes the object, which must have been created by the + // DataManager::GetDataSet function. |callback| can be invoked on an + // executor thread when complete. + virtual void Initialize(absl::AnyInvocable callback) = 0; + + // Asynchronously loads all entries from the database and invokes |callback| + // when complete. + virtual void LoadEntries( + absl::AnyInvocable< + void(bool, std::unique_ptr>) &&> + callback) = 0; + + // Asynchronously saves |certificates| to the database. + // |callback| can be invoked on an executor thread when complete. + virtual void AddCertificates( + absl::Span certificates, + absl::AnyInvocable callback) = 0; + + // Asynchronously deletes certificates with IDs in |ids_to_remove| from the + // database. + // |callback| can be invoked on an executor thread when complete. + virtual void RemoveCertificatesById( + std::vector ids_to_remove, + absl::AnyInvocable callback) = 0; + + // Asynchronously destroys the database. Use this call only if the database + // needs to be destroyed for this particular profile. + virtual void Destroy(absl::AnyInvocable callback) = 0; +}; + +} // namespace nearby::sharing::api + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_PUBLIC_CERTIFICATE_DATABASE_H_ diff --git a/sharing/internal/api/sharing_platform.h b/sharing/internal/api/sharing_platform.h new file mode 100644 index 00000000..2deebb23 --- /dev/null +++ b/sharing/internal/api/sharing_platform.h @@ -0,0 +1,96 @@ +// Copyright 2023 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_SHARING_PLATFORM_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_SHARING_PLATFORM_H_ + +#include +#include + +#include "absl/status/status.h" +#include "absl/strings/string_view.h" +#include "internal/platform/device_info.h" +#include "internal/platform/implementation/account_manager.h" +#include "internal/platform/task_runner.h" +#include "sharing/internal/api/app_info.h" +#include "sharing/internal/api/bluetooth_adapter.h" +#include "sharing/internal/api/fast_init_ble_beacon.h" +#include "sharing/internal/api/fast_initiation_manager.h" +#include "sharing/internal/api/network_monitor.h" +#include "sharing/internal/api/preference_manager.h" +#include "sharing/internal/api/public_certificate_database.h" +#include "sharing/internal/api/shell.h" +#include "sharing/internal/api/system_info.h" +#include "sharing/internal/api/wifi_adapter.h" + +namespace nearby::sharing::api { + +constexpr char kSharingPreferencesFilePath[] = "Google/Nearby/Sharing"; + +// Platform abstraction interface for NearbyShare cross-platform compatibility. +class SharingPlatform { + public: + virtual ~SharingPlatform() = default; + + // This function should only be called once. + virtual void InitLogging() = 0; + + // Platform specific implementation to set default logging levels. + virtual void UpdateLoggingLevel() = 0; + + virtual std::unique_ptr CreateNetworkMonitor( + std::function + callback) = 0; + + virtual BluetoothAdapter& GetBluetoothAdapter() = 0; + + virtual WifiAdapter& GetWifiAdapter() = 0; + + virtual void LaunchDefaultBrowserFromURL( + absl::string_view url, std::function callback) = 0; + + virtual nearby::api::Shell& GetShell() = 0; + + virtual nearby::api::FastInitBleBeacon& GetFastInitBleBeacon() = 0; + + virtual nearby::api::FastInitiationManager& GetFastInitiationManager() = 0; + + // Make calls to OS to copy text to clipboard + // + // @param text is a text to copy to clipboard. + // @param callback + // + // If it is successfully copied, callback provided is executed with + // absl::OkStatus. Otherwise, absl::InternalError. + virtual void CopyText(absl::string_view text, + std::function callback) = 0; + + // Creates system information class. SystemInfo provides APIs to access + // system information. + virtual std::unique_ptr CreateSystemInfo() = 0; + + // Creates app information class. AppInfo provides APIs to access app + // information, such as app version. + virtual std::unique_ptr CreateAppInfo() = 0; + + virtual PreferenceManager& GetPreferenceManager() = 0; + virtual AccountManager& GetAccountManager() = 0; + virtual TaskRunner& GetDefaultTaskRunner() = 0; + virtual nearby::DeviceInfo& GetDeviceInfo() = 0; + virtual std::unique_ptr + CreatePublicCertificateDatabase(absl::string_view database_path) = 0; +}; +} // namespace nearby::sharing::api + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_SHARING_PLATFORM_H_ diff --git a/sharing/internal/api/shell.h b/sharing/internal/api/shell.h new file mode 100644 index 00000000..0934fa61 --- /dev/null +++ b/sharing/internal/api/shell.h @@ -0,0 +1,43 @@ +// Copyright 2022 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_SHELL_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_SHELL_H_ + +#include // NOLINT(build/c++17) +#include + +#include "absl/status/status.h" + +namespace nearby { +namespace api { + +// Shell defines interfaces to interact with platform core features. +class Shell { + public: + virtual ~Shell() = default; + + // Opens the |path| file or folder with default application. if |path| + // is a directory, will open the folder by explore, otherwise it will + // try to open the file with application supports it. |callback| is called + // when the open operation completed, and absl::StatusCodes::kOk returned + // only when open the path successfully. + virtual void Open(const std::filesystem::path& path, + std::function callback) = 0; +}; + +} // namespace api +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_SHELL_H_ diff --git a/sharing/internal/api/system_info.h b/sharing/internal/api/system_info.h new file mode 100644 index 00000000..638f1068 --- /dev/null +++ b/sharing/internal/api/system_info.h @@ -0,0 +1,183 @@ +// Copyright 2022 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_SYSTEM_INFO_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_SYSTEM_INFO_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "absl/strings/string_view.h" + +namespace nearby { +namespace api { + +// SystemInfo provides information about the current computer system, such as +// CPU, memory, OS, driver and configuration information. SystemInfo doesn't +// include specific user information. +class SystemInfo { + public: + typedef struct _DriverInfo { + std::string manufacturer; + std::string device_name; + std::string driver_provider_name; + std::string driver_version; + std::string driver_date; + } DriverInfo; + + enum class BatteryChargeStatus { + UNKNOWN = 0, + NO_BATTERY, + CHARGING, + CHARGED, + ON_BATTERY + }; + + virtual ~SystemInfo() = default; + + // Computer related information. + virtual std::string GetComputerManufacturer() = 0; + virtual std::string GetComputerModel() = 0; + virtual int64_t GetComputerPhysicalMemory() = 0; + virtual int GetComputerProcessorCount() = 0; + virtual int GetComputerLogicProcessorCount() = 0; + virtual int GetProcessorMemoryInfo() = 0; + + virtual BatteryChargeStatus QueryBatteryInfo(int& seconds, int& percent, + bool& battery_saver) = 0; + + // Operating system related information. + virtual std::string GetOsManufacturer() = 0; + virtual std::string GetOsName() = 0; + virtual std::string GetOsVersion() = 0; + virtual std::string GetOsArchitecture() = 0; + virtual std::string GetOsLanguage() = 0; + + // CPU related information. + virtual std::string GetProcessorManufacturer() = 0; + virtual std::string GetProcessorName() = 0; + + // Driver related information. + virtual std::list GetBluetoothDriverInfos() = 0; + virtual std::list GetNetworkDriverInfos() = 0; + + virtual void GetBatteryUsageReport(absl::string_view save_path) = 0; + + // Outputs all system information to a readable string. + std::string Dump() { + std::ostringstream oss; + oss << "System Information" << std::endl; + oss << " Manufacturer: " << GetComputerManufacturer() << std::endl + << " Model: " << GetComputerModel() << std::endl + << " Physical Memory: " << GetComputerPhysicalMemory() << std::endl + << " Processor Count: " << GetComputerProcessorCount() << std::endl + << " Logic Processor Count: " << GetComputerLogicProcessorCount() + << std::endl + << " OS Manufacturer: " << GetOsManufacturer() << std::endl + << " OS Name: " << GetOsName() << std::endl + << " OS Version: " << GetOsVersion() << std::endl + << " OS Architecture: " << GetOsArchitecture() << std::endl + << " OS Language: " << GetOsLanguage() << std::endl + << " CPU Manufacturer: " << GetProcessorManufacturer() << std::endl + << " CPU Name: " << GetProcessorName() << std::endl; + + oss << std::endl; + std::optional> bluetooth_drivers = + GetBluetoothDriverInfos(); + if (bluetooth_drivers.has_value()) { + oss << " Bluetooth Driver Information:" << std::endl; + for (const DriverInfo& driver_info : *bluetooth_drivers) { + oss << " Manufacturer: " << driver_info.manufacturer << std::endl + << " Device Name: " << driver_info.device_name << std::endl + << " Driver Provider Name: " << driver_info.driver_provider_name + << std::endl + << " Driver Version: " << driver_info.driver_version << std::endl + << " Driver Date: " << driver_info.driver_date << std::endl; + } + } else { + oss << " No Bluetooth Driver Information." << std::endl; + } + + oss << std::endl; + std::optional> network_drivers = + GetNetworkDriverInfos(); + if (network_drivers.has_value()) { + oss << " Network Driver Information:" << std::endl; + for (const DriverInfo& driver_info : *network_drivers) { + oss << " Manufacturer: " << driver_info.manufacturer << std::endl + << " Device Name: " << driver_info.device_name << std::endl + << " Driver Provider Name: " << driver_info.driver_provider_name + << std::endl + << " Driver Version: " << driver_info.driver_version << std::endl + << " Driver Date: " << driver_info.driver_date << std::endl; + } + } else { + oss << " No Network Driver Information." << std::endl; + } + + oss << std::endl; + int seconds = 0, percentage = 0; + bool battery_saver = false; + BatteryChargeStatus battery_charge_status = + QueryBatteryInfo(seconds, percentage, battery_saver); + if (battery_charge_status == BatteryChargeStatus::UNKNOWN || + battery_charge_status == BatteryChargeStatus::NO_BATTERY) { + oss << " Computer Battery Information: UNKNOWN or NO_BATTERY" + << std::endl; + } else { + oss << " Computer Battery Information:" << std::endl; + oss << " Power State: " + << BatteryChargeStatusToString(battery_charge_status) << std::endl + << " Battery Percentage: " << percentage << std::endl + << " Battery Left (Seconds): " << seconds << std::endl + << " Battery Saver: " << battery_saver << std::endl; + } + + oss << std::endl; + oss << " Current Process Information:" << std::endl; + oss << " Physical Memory currently in use: " << std::fixed + << std::setprecision(2) + << GetProcessorMemoryInfo() / static_cast(1024 * 1024) << "MB" + << std::endl; + + return oss.str(); + } + + private: + std::string BatteryChargeStatusToString(const BatteryChargeStatus state) { + switch (state) { + case BatteryChargeStatus::NO_BATTERY: + return "NO_BATTERY"; + case BatteryChargeStatus::CHARGING: + return "CHARGING"; + case BatteryChargeStatus::CHARGED: + return "CHARGED"; + case BatteryChargeStatus::ON_BATTERY: + return "ON_BATTERY"; + default: + return "UNKNOWN"; + } + } +}; + +} // namespace api +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_SYSTEM_INFO_H_ diff --git a/sharing/internal/api/wifi_adapter.h b/sharing/internal/api/wifi_adapter.h new file mode 100644 index 00000000..2f7aa680 --- /dev/null +++ b/sharing/internal/api/wifi_adapter.h @@ -0,0 +1,91 @@ +// Copyright 2023 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_WIFI_ADAPTER_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_WIFI_ADAPTER_H_ + +#include +#include +#include +#include + +#include "absl/status/status.h" + +namespace nearby { +namespace sharing { +namespace api { + +class WifiAdapter { + public: + enum class PermissionStatus { + kUndetermined = 0, + kSystemDenied, + kUserDenied, + kAllowed + }; + + class Observer { + public: + virtual ~Observer() = default; + + // Called when the presence of the adapter `adapter` changes. When `present` + // is true the adapter is now present, false means the adapter has been + // removed from the system. + virtual void AdapterPresentChanged(WifiAdapter* adapter, bool present) {} + + // Called when the radio power state of the adapter `adapter` changes. When + // `powered` is true the adapter radio is powered, false means the adapter + // radio is off. + virtual void AdapterPoweredChanged(WifiAdapter* adapter, bool powered) {} + }; + + virtual ~WifiAdapter() = default; + + // Indicates whether the adapter is actually present/not disabled by the + // device firmware or hardware switch on the system. + virtual bool IsPresent() const = 0; + + // Indicates whether the adapter radio is powered. + virtual bool IsPowered() const = 0; + + // Returns the status of the browser's Wi-Fi permission status. + virtual PermissionStatus GetOsPermissionStatus() const = 0; + + // Requests a change to the adapter radio power. Setting `powered` to true + // will turn on the radio and false will turn it off. On success, + // `success_callback` will be called. On failure, `error_callback` will be + // called. + virtual void SetPowered(bool powered, std::function success_callback, + std::function error_callback) = 0; + + // The unique ID/name of this adapter. + virtual std::optional GetAdapterId() const = 0; + + // Adds and removes observers for events on this Wi-Fi adapter. If + // monitoring multiple adapters, check the `adapter` parameter of observer + // methods to determine which adapter is issuing the event. + virtual void AddObserver(Observer* observer) = 0; + virtual void RemoveObserver(Observer* observer) = 0; + virtual bool HasObserver(Observer* observer) = 0; + + // Requests to join a Wi-Fi network. + virtual void JoinNetwork(absl::string_view ssid, absl::string_view password, + std::function callback) = 0; +}; + +} // namespace api +} // namespace sharing +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_API_WIFI_ADAPTER_H_ diff --git a/sharing/internal/public/BUILD b/sharing/internal/public/BUILD new file mode 100644 index 00000000..24cc9c1c --- /dev/null +++ b/sharing/internal/public/BUILD @@ -0,0 +1,84 @@ +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +licenses(["notice"]) + +cc_library( + name = "types", + hdrs = [ + "connectivity_manager.h", + "context.h", + ], + visibility = ["//visibility:public"], + deps = [ + "//internal/network:types", + "//internal/platform:types", + "//sharing/internal/api:platform", + "@com_google_absl//absl/status", + "@com_google_absl//absl/strings", + ], +) + +cc_library( + name = "nearby_context", + srcs = [ + "connectivity_manager_impl.cc", + "context_impl.cc", + ], + hdrs = [ + "connectivity_manager_impl.h", + "context_impl.h", + ], + visibility = ["//visibility:public"], + deps = [ + ":logging", + ":types", + "//internal/network:types", + "//internal/platform:types", + "//sharing/internal/api:platform", + "@com_google_absl//absl/container:flat_hash_map", + "@com_google_absl//absl/status", + "@com_google_absl//absl/strings", + ], +) + +cc_test( + name = "nearby_context_test", + size = "small", + timeout = "short", + srcs = [ + "connectivity_manager_impl_test.cc", + ], + shard_count = 8, + deps = [ + ":nearby_context", + ":types", + "//internal/platform/implementation/g3", # fixdeps: keep + "//sharing/internal/api:mock_sharing_platform", + "@com_github_protobuf_matchers//protobuf-matchers", + "@com_google_googletest//:gtest_main", + ], +) + +cc_library( + name = "logging", + hdrs = [ + "logging.h", + ], + visibility = ["//visibility:public"], + deps = [ + "@com_google_absl//absl/log", + "@com_google_absl//absl/log:check", + ], +) diff --git a/sharing/internal/public/connectivity_manager.h b/sharing/internal/public/connectivity_manager.h new file mode 100644 index 00000000..8e697e26 --- /dev/null +++ b/sharing/internal/public/connectivity_manager.h @@ -0,0 +1,55 @@ +// 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_PUBLIC_CONNECTIVITY_MANAGER_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_PUBLIC_CONNECTIVITY_MANAGER_H_ + +#include + +#include "absl/strings/string_view.h" + +namespace nearby { + +class ConnectivityManager { + public: + enum class ConnectionType { + kUnknown = 0, // A connection exists, but its type is unknown. + // Also used as a default value. + kEthernet = 1, + kWifi = 2, + k2G = 3, + k3G = 4, + k4G = 5, + kNone = 6, // No connection. + kBluetooth = 7, + k5G = 8, + kLast = k5G + }; + + virtual ~ConnectivityManager() = default; + + virtual bool IsLanConnected() = 0; + + virtual ConnectionType GetConnectionType() = 0; + + virtual void RegisterConnectionListener( + absl::string_view listener_name, + std::function) = 0; + virtual void UnregisterConnectionListener( + absl::string_view listener_name) = 0; +}; + +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_PUBLIC_CONNECTIVITY_MANAGER_H_ diff --git a/sharing/internal/public/connectivity_manager_impl.cc b/sharing/internal/public/connectivity_manager_impl.cc new file mode 100644 index 00000000..8628afe5 --- /dev/null +++ b/sharing/internal/public/connectivity_manager_impl.cc @@ -0,0 +1,95 @@ +// Copyright 2022 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 "sharing/internal/public/connectivity_manager_impl.h" + +#include +#include +#include +#include + +#include "absl/container/flat_hash_map.h" +#include "absl/strings/string_view.h" +#include "sharing/internal/api/network_monitor.h" +#include "sharing/internal/api/sharing_platform.h" +#include "sharing/internal/public/connectivity_manager.h" +#include "sharing/internal/public/logging.h" + +namespace nearby { +namespace { + +using ::nearby::sharing::api::SharingPlatform; +using ConnectionType = ConnectivityManager::ConnectionType; + +std::string GetConnectionTypeString(ConnectionType connection_type) { + switch (connection_type) { + case ConnectionType::k2G: + return "2G"; + case ConnectionType::k3G: + return "3G"; + case ConnectionType::k4G: + return "4G"; + case ConnectionType::k5G: + return "5G"; + case ConnectionType::kBluetooth: + return "Bluetooth"; + case ConnectionType::kEthernet: + return "Ethernet"; + case ConnectionType::kWifi: + return "WiFi"; + default: + return "Unknown"; + } +} + +} // namespace + +ConnectivityManagerImpl::ConnectivityManagerImpl(SharingPlatform& platform) { + network_monitor_ = platform.CreateNetworkMonitor( + [this](api::NetworkMonitor::ConnectionType connection_type, + bool is_lan_connected) { + ConnectionType new_connection_type = + static_cast(connection_type); + NL_VLOG(1) << ": New connection type:" + << GetConnectionTypeString(new_connection_type); + for (auto& listener : listeners_) { + listener.second(new_connection_type, is_lan_connected); + } + }); +} + +bool ConnectivityManagerImpl::IsLanConnected() { + return network_monitor_->IsLanConnected(); +} + +ConnectionType ConnectivityManagerImpl::GetConnectionType() { + return static_cast(network_monitor_->GetCurrentConnection()); +} + +void ConnectivityManagerImpl::RegisterConnectionListener( + absl::string_view listener_name, + std::function callback) { + listeners_.emplace(listener_name, std::move(callback)); +} + +void ConnectivityManagerImpl::UnregisterConnectionListener( + absl::string_view listener_name) { + listeners_.erase(listener_name); +} + +int ConnectivityManagerImpl::GetListenerCount() const { + return listeners_.size(); +} + +} // namespace nearby diff --git a/sharing/internal/public/connectivity_manager_impl.h b/sharing/internal/public/connectivity_manager_impl.h new file mode 100644 index 00000000..07b70ec6 --- /dev/null +++ b/sharing/internal/public/connectivity_manager_impl.h @@ -0,0 +1,55 @@ +// 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_PUBLIC_CONNECTIVITY_MANAGER_IMPL_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_PUBLIC_CONNECTIVITY_MANAGER_IMPL_H_ + +#include +#include +#include + +#include "absl/container/flat_hash_map.h" +#include "absl/strings/string_view.h" +#include "sharing/internal/api/network_monitor.h" +#include "sharing/internal/api/sharing_platform.h" +#include "sharing/internal/public/connectivity_manager.h" + +namespace nearby { + +// Limitation: this is not thread safe and needs to be enhanced +class ConnectivityManagerImpl : public ConnectivityManager { + public: + explicit ConnectivityManagerImpl( + nearby::sharing::api::SharingPlatform& platform); + + bool IsLanConnected() override; + + ConnectionType GetConnectionType() override; + + void RegisterConnectionListener( + absl::string_view listener_name, + std::function callback) override; + void UnregisterConnectionListener(absl::string_view listener_name) override; + + int GetListenerCount() const; + + private: + absl::flat_hash_map> + listeners_; + std::unique_ptr network_monitor_; +}; + +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_PUBLIC_CONNECTIVITY_MANAGER_IMPL_H_ diff --git a/sharing/internal/public/connectivity_manager_impl_test.cc b/sharing/internal/public/connectivity_manager_impl_test.cc new file mode 100644 index 00000000..3d9f60a3 --- /dev/null +++ b/sharing/internal/public/connectivity_manager_impl_test.cc @@ -0,0 +1,108 @@ +// Copyright 2022 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 "sharing/internal/public/connectivity_manager_impl.h" + +#include +#include +#include + +#include "gmock/gmock.h" +#include "protobuf-matchers/protocol-buffer-matchers.h" +#include "gtest/gtest.h" +#include "sharing/internal/api/mock_network_monitor.h" +#include "sharing/internal/api/mock_sharing_platform.h" +#include "sharing/internal/public/connectivity_manager.h" + +namespace nearby { +namespace { +using ::nearby::sharing::api::MockNetworkMonitor; +using ::nearby::sharing::api::MockSharingPlatform; +using ::testing::_; +using ::testing::ByMove; +using ::testing::Return; + +TEST(ConnectivityManagerImpl, IsLanConnected) { + MockSharingPlatform sharing_platform; + auto network_monitor = std::make_unique(); + MockNetworkMonitor* mock_network_monitor = network_monitor.get(); + EXPECT_CALL(*mock_network_monitor, IsLanConnected()).WillOnce(Return(true)); + EXPECT_CALL(sharing_platform, CreateNetworkMonitor(_)) + .WillOnce(Return(ByMove(std::move(network_monitor)))); + + ConnectivityManagerImpl connectivity_manager_impl(sharing_platform); + EXPECT_TRUE(connectivity_manager_impl.IsLanConnected()); +} + +TEST(ConnectivityManagerImpl, GetConnectionType) { + MockSharingPlatform sharing_platform; + auto network_monitor = std::make_unique(); + MockNetworkMonitor* mock_network_monitor = network_monitor.get(); + EXPECT_CALL(sharing_platform, CreateNetworkMonitor(_)) + .WillOnce(Return(ByMove(std::move(network_monitor)))); + EXPECT_CALL(*mock_network_monitor, GetCurrentConnection()) + .WillOnce(Return(MockNetworkMonitor::ConnectionType::kWifi)); + + ConnectivityManagerImpl connectivity_manager_impl(sharing_platform); + EXPECT_EQ(connectivity_manager_impl.GetConnectionType(), + ConnectivityManager::ConnectionType::kWifi); +} + +TEST(ConnectivityManagerImpl, RegisterConnectionListener) { + std::function listener_1 = + [](ConnectivityManager::ConnectionType connection_type, + bool is_lan_connected) {}; + std::function listener_2 = + [](ConnectivityManager::ConnectionType connection_type, + bool is_lan_connected) {}; + + MockSharingPlatform sharing_platform; + ConnectivityManagerImpl connectivity_manager_impl(sharing_platform); + EXPECT_EQ(connectivity_manager_impl.GetListenerCount(), 0); + + connectivity_manager_impl.RegisterConnectionListener("listener_1", + listener_1); + EXPECT_EQ(connectivity_manager_impl.GetListenerCount(), 1); + + connectivity_manager_impl.RegisterConnectionListener("listener_2", + listener_2); + EXPECT_EQ(connectivity_manager_impl.GetListenerCount(), 2); +} + +TEST(ConnectivityManagerImpl, UnregisterConnectionListener) { + std::function listener_1 = + [](ConnectivityManager::ConnectionType connection_type, + bool is_lan_connected) {}; + std::function listener_2 = + [](ConnectivityManager::ConnectionType connection_type, + bool is_lan_connected) {}; + + MockSharingPlatform sharing_platform; + ConnectivityManagerImpl connectivity_manager_impl(sharing_platform); + connectivity_manager_impl.RegisterConnectionListener("listener_1", + listener_1); + connectivity_manager_impl.RegisterConnectionListener("listener_2", + listener_2); + + EXPECT_EQ(connectivity_manager_impl.GetListenerCount(), 2); + + connectivity_manager_impl.UnregisterConnectionListener("listener_1"); + EXPECT_EQ(connectivity_manager_impl.GetListenerCount(), 1); + + connectivity_manager_impl.UnregisterConnectionListener("listener_2"); + EXPECT_EQ(connectivity_manager_impl.GetListenerCount(), 0); +} + +} // namespace +} // namespace nearby diff --git a/sharing/internal/public/context.h b/sharing/internal/public/context.h new file mode 100644 index 00000000..facc1fd7 --- /dev/null +++ b/sharing/internal/public/context.h @@ -0,0 +1,77 @@ +// Copyright 2021-2023 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_PUBLIC_CONTEXT_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_PUBLIC_CONTEXT_H_ + +#include + +#include +#include + +#include "absl/status/status.h" +#include "absl/strings/string_view.h" +#include "internal/network/url.h" +#include "internal/platform/clock.h" +#include "internal/platform/task_runner.h" +#include "internal/platform/timer.h" +#include "sharing/internal/api/bluetooth_adapter.h" +#include "sharing/internal/api/fast_initiation_manager.h" +#include "sharing/internal/api/shell.h" +#include "sharing/internal/api/wifi_adapter.h" +#include "sharing/internal/public/connectivity_manager.h" + +namespace nearby { + +// Context defines platform implementation-related interfaces. Nearby Sharing +// components should access these interfaces under their environment. +// On different platforms, the implementation of these interfaces are different. +// In order to support test cases on Google3, Nearby Sharing SDK also provides +// a mock implementation of these interfaces. +class Context { + public: + virtual ~Context() = default; + + virtual Clock* GetClock() const = 0; + virtual std::unique_ptr CreateTimer() = 0; + + // Opens a URL by calling the platform API. The platform API should run + // in async mode. However, the callback might be called before + // this function returns, for example if the URL has an error. + // |url| is the URL to open. |callback| is called when the platform API + // completes. absl::StatusCode::kOk is returned when the URL opens + // successfully. + virtual void OpenUrl(const nearby::network::Url& url, + std::function callback) = 0; + virtual ConnectivityManager* GetConnectivityManager() const = 0; + virtual sharing::api::BluetoothAdapter& GetBluetoothAdapter() const = 0; + virtual sharing::api::WifiAdapter& GetWifiAdapter() const = 0; + virtual api::FastInitiationManager& GetFastInitiationManager() const = 0; + virtual std::unique_ptr CreateSequencedTaskRunner() const = 0; + virtual void CopyText(absl::string_view text, + std::function callback) = 0; + + // Creates task runner concurrently. |concurrent_count| is the maximum + // count of tasks running at the same time. + virtual std::unique_ptr CreateConcurrentTaskRunner( + uint32_t concurrent_count) const = 0; + virtual api::Shell& GetShell() const = 0; + + // Provides the API to retrieve TaskRunner to run a task globally. + virtual TaskRunner* GetTaskRunner() = 0; +}; + +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_PUBLIC_CONTEXT_H_ diff --git a/sharing/internal/public/context_impl.cc b/sharing/internal/public/context_impl.cc new file mode 100644 index 00000000..c256a14f --- /dev/null +++ b/sharing/internal/public/context_impl.cc @@ -0,0 +1,102 @@ +// Copyright 2021-2023 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 "sharing/internal/public/context_impl.h" + +#include + +#include +#include +#include + +#include "absl/status/status.h" +#include "absl/strings/string_view.h" +#include "internal/network/url.h" +#include "internal/platform/clock.h" +#include "internal/platform/clock_impl.h" +#include "internal/platform/task_runner.h" +#include "internal/platform/task_runner_impl.h" +#include "internal/platform/timer.h" +#include "internal/platform/timer_impl.h" +#include "sharing/internal/api/bluetooth_adapter.h" +#include "sharing/internal/api/fast_initiation_manager.h" +#include "sharing/internal/api/sharing_platform.h" +#include "sharing/internal/api/shell.h" +#include "sharing/internal/api/wifi_adapter.h" +#include "sharing/internal/public/connectivity_manager.h" +#include "sharing/internal/public/connectivity_manager_impl.h" + +namespace nearby { + +using ::nearby::sharing::api::SharingPlatform; + +ContextImpl::ContextImpl(SharingPlatform& platform) + : platform_(platform), + clock_(std::make_unique()), + connectivity_manager_( + std::make_unique(platform_)) {} + +Clock* ContextImpl::GetClock() const { return clock_.get(); } + +std::unique_ptr ContextImpl::CreateTimer() { + return std::make_unique(); +} + +void ContextImpl::OpenUrl(const nearby::network::Url& url, + std::function callback) { + platform_.LaunchDefaultBrowserFromURL(url.GetUrlPath(), std::move(callback)); +} + +ConnectivityManager* ContextImpl::GetConnectivityManager() const { + return connectivity_manager_.get(); +} + +sharing::api::BluetoothAdapter& ContextImpl::GetBluetoothAdapter() const { + return platform_.GetBluetoothAdapter(); +} + +sharing::api::WifiAdapter& ContextImpl::GetWifiAdapter() const { + return platform_.GetWifiAdapter(); +} + +api::FastInitiationManager& ContextImpl::GetFastInitiationManager() const { + return platform_.GetFastInitiationManager(); +} + +std::unique_ptr ContextImpl::CreateSequencedTaskRunner() const { + std::unique_ptr task_runner = std::make_unique(1); + return task_runner; +} + +std::unique_ptr ContextImpl::CreateConcurrentTaskRunner( + uint32_t concurrent_count) const { + std::unique_ptr task_runner = + std::make_unique(concurrent_count); + return task_runner; +} + +api::Shell& ContextImpl::GetShell() const { + return platform_.GetShell(); +} + +void ContextImpl::CopyText(absl::string_view text, + std::function callback) { + platform_.CopyText(text, callback); +} + +TaskRunner* ContextImpl::GetTaskRunner() { + return &platform_.GetDefaultTaskRunner(); +} + +} // namespace nearby diff --git a/sharing/internal/public/context_impl.h b/sharing/internal/public/context_impl.h new file mode 100644 index 00000000..4b3d612d --- /dev/null +++ b/sharing/internal/public/context_impl.h @@ -0,0 +1,68 @@ +// Copyright 2021-2023 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_PUBLIC_CONTEXT_IMPL_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_PUBLIC_CONTEXT_IMPL_H_ + +#include + +#include +#include + +#include "absl/status/status.h" +#include "absl/strings/string_view.h" +#include "internal/network/url.h" +#include "internal/platform/clock.h" +#include "internal/platform/task_runner.h" +#include "internal/platform/timer.h" +#include "sharing/internal/api/bluetooth_adapter.h" +#include "sharing/internal/api/fast_initiation_manager.h" +#include "sharing/internal/api/sharing_platform.h" +#include "sharing/internal/api/shell.h" +#include "sharing/internal/api/wifi_adapter.h" +#include "sharing/internal/public/connectivity_manager.h" +#include "sharing/internal/public/context.h" + +namespace nearby { + +class ContextImpl : public Context { + public: + explicit ContextImpl(nearby::sharing::api::SharingPlatform& platform); + ~ContextImpl() override = default; + + Clock* GetClock() const override; + std::unique_ptr CreateTimer() override; + void OpenUrl(const nearby::network::Url& url, + std::function callback) override; + ConnectivityManager* GetConnectivityManager() const override; + sharing::api::BluetoothAdapter& GetBluetoothAdapter() const override; + sharing::api::WifiAdapter& GetWifiAdapter() const override; + api::FastInitiationManager& GetFastInitiationManager() const override; + std::unique_ptr CreateSequencedTaskRunner() const override; + std::unique_ptr CreateConcurrentTaskRunner( + uint32_t concurrent_count) const override; + api::Shell& GetShell() const override; + void CopyText(absl::string_view text, + std::function callback) override; + TaskRunner* GetTaskRunner() override; + + private: + nearby::sharing::api::SharingPlatform& platform_; + std::unique_ptr clock_; + std::unique_ptr connectivity_manager_; +}; + +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_PUBLIC_CONTEXT_IMPL_H_ diff --git a/sharing/internal/public/logging.h b/sharing/internal/public/logging.h new file mode 100644 index 00000000..35261248 --- /dev/null +++ b/sharing/internal/public/logging.h @@ -0,0 +1,44 @@ +// 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_PUBLIC_LOGGING_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_PUBLIC_LOGGING_H_ + +#include "absl/log/check.h" +#include "absl/log/log.h" + +// Public APIs +// The stream statement must come last, or it won't compile. +#define NL_VLOG(level) VLOG(level) +#define NL_LOG(severity) LOG(severity) + +#define NL_DLOG(severity) DLOG(severity) + +#define NL_CHECK(expr) CHECK(expr) +#define NL_CHECK_EQ(a, b) CHECK_EQ((a), (b)) +#define NL_CHECK_NE(a, b) CHECK_NE((a), (b)) +#define NL_CHECK_GE(a, b) CHECK_GE((a), (b)) +#define NL_CHECK_GT(a, b) CHECK_GT((a), (b)) +#define NL_CHECK_LE(a, b) CHECK_LE((a), (b)) +#define NL_CHECK_LT(a, b) CHECK_LT((a), (b)) + +#define NL_DCHECK(expr) DCHECK((expr)) +#define NL_DCHECK_EQ(a, b) DCHECK_EQ((a), (b)) +#define NL_DCHECK_NE(a, b) DCHECK_NE((a), (b)) +#define NL_DCHECK_GE(a, b) DCHECK_GE((a), (b)) +#define NL_DCHECK_GT(a, b) DCHECK_GT((a), (b)) +#define NL_DCHECK_LE(a, b) DCHECK_LE((a), (b)) +#define NL_DCHECK_LT(a, b) DCHECK_LT((a), (b)) + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_PUBLIC_LOGGING_H_ diff --git a/sharing/internal/test/BUILD b/sharing/internal/test/BUILD new file mode 100644 index 00000000..e9a89663 --- /dev/null +++ b/sharing/internal/test/BUILD @@ -0,0 +1,87 @@ +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +licenses(["notice"]) + +cc_library( + name = "nearby_test", + testonly = True, + srcs = [ + "fake_context.cc", + "fake_preference_manager.cc", + "fake_public_certificate_db.cc", + ], + hdrs = [ + "fake_bluetooth_adapter.h", + "fake_bluetooth_adapter_observer.h", + "fake_connectivity_manager.h", + "fake_context.h", + "fake_fast_initiation_manager.h", + "fake_network_monitor.h", + "fake_preference_manager.h", + "fake_public_certificate_db.h", + "fake_shell.h", + "fake_wifi_adapter.h", + "fake_wifi_adapter_observer.h", + ], + visibility = ["//visibility:public"], + deps = [ + "//internal/base", + "//internal/base:bluetooth_address", + "//internal/network:types", + "//internal/platform:types", + "//internal/test", + "//sharing/internal/api:platform", + "//sharing/internal/public:logging", + "//sharing/internal/public:types", + "//sharing/proto:share_cc_proto", + "@com_google_absl//absl/container:flat_hash_map", + "@com_google_absl//absl/functional:any_invocable", + "@com_google_absl//absl/status", + "@com_google_absl//absl/strings", + "@com_google_absl//absl/time", + "@com_google_absl//absl/types:span", + ], +) + +cc_test( + name = "nearby_test_test", + size = "small", + timeout = "short", + srcs = [ + "fake_bluetooth_adapter_test.cc", + "fake_connectivity_manager_test.cc", + "fake_context_test.cc", + "fake_fast_initiation_manager_test.cc", + "fake_shell_test.cc", + "fake_wifi_adapter_test.cc", + ], + shard_count = 8, + deps = [ + ":nearby_test", + "//internal/network:types", + "//internal/platform:types", + "//internal/platform/implementation/g3", # fixdeps: keep + "//sharing/internal/api:platform", # fixdeps: keep + "//sharing/internal/public:types", + "@com_github_protobuf_matchers//protobuf-matchers", + "@com_google_absl//absl/container:flat_hash_map", + "@com_google_absl//absl/status", + "@com_google_absl//absl/status:statusor", + "@com_google_absl//absl/strings", + "@com_google_absl//absl/synchronization", + "@com_google_absl//absl/time", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/sharing/internal/test/fake_bluetooth_adapter.h b/sharing/internal/test/fake_bluetooth_adapter.h new file mode 100644 index 00000000..da7698db --- /dev/null +++ b/sharing/internal/test/fake_bluetooth_adapter.h @@ -0,0 +1,192 @@ +// Copyright 2022 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_BLUETOOTH_ADAPTER_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_BLUETOOTH_ADAPTER_H_ + +#include + +#include +#include +#include +#include + +#include "absl/strings/string_view.h" +#include "absl/types/span.h" +#include "internal/base/bluetooth_address.h" +#include "internal/base/observer_list.h" +#include "sharing/internal/api/bluetooth_adapter.h" + +namespace nearby { + +class FakeBluetoothAdapter : public sharing::api::BluetoothAdapter { + public: + FakeBluetoothAdapter() { + num_present_received_ = 0; + num_powered_received_ = 0; + } + + ~FakeBluetoothAdapter() override = default; + + bool IsPresent() const override { return is_present_; } + + bool IsPowered() const override { + // If the bluetooth adapter is not present, return false for power status. + if (!is_present_) { + return false; + } + + return is_powered_; + } + + bool IsLowEnergySupported() const override { + return is_low_energy_supported_; + } + + bool IsScanOffloadSupported() const override { + return is_scan_offload_supported_; + } + + bool IsAdvertisementOffloadSupported() const override { + return is_advertisement_offload_supported_; + } + + bool IsExtendedAdvertisingSupported() const override { + return is_extended_advertising_supported_; + } + + bool IsPeripheralRoleSupported() const override { + return is_peripheral_role_supported_; + } + + sharing::api::BluetoothAdapter::PermissionStatus GetOsPermissionStatus() + const override { + return sharing::api::BluetoothAdapter::PermissionStatus::kAllowed; + } + + void SetPowered(bool powered, std::function success_callback, + std::function error_callback) override { + success_callback(); + } + + std::optional GetAdapterId() const override { return "nearby"; } + + std::optional> GetAddress() const override { + std::array output; + if (device::ParseBluetoothAddress( + mac_address_.value(), + absl::MakeSpan(output.data(), output.size()))) { + return output; + } + return {}; + } + + void SetAddress(std::optional bluetooth_address) { + mac_address_ = std::nullopt; + if (bluetooth_address.has_value()) { + mac_address_ = std::make_optional(std::string(bluetooth_address.value())); + } + } + + void AddObserver(Observer* observer) override { + observer_list_.AddObserver(observer); + } + void RemoveObserver(Observer* observer) override { + observer_list_.RemoveObserver(observer); + } + bool HasObserver(Observer* observer) override { + return observer_list_.HasObserver(observer); + } + + // Mock OS bluetooth adapter presence state changed events + void ReceivedAdapterPresentChangedFromOs(bool present) { + num_present_received_ += 1; + + bool was_present = IsPresent(); + bool is_present = present; + + // Only trigger when state of presence changes values + if (was_present != is_present) { + is_present_ = is_present; + for (Observer* observer : observer_list_.GetObservers()) { + if (observer != nullptr) { + observer->AdapterPresentChanged(this, is_present_); + } + } + } + } + + // Mock OS bluetooth adapter powered state changed events + void ReceivedAdapterPoweredChangedFromOs(bool powered) { + num_powered_received_ += 1; + + bool was_powered = IsPowered(); + bool is_powered = powered; + + // Only trigger when state of power changes values + if (was_powered != is_powered) { + is_powered_ = is_powered; + for (Observer* observer : observer_list_.GetObservers()) { + if (observer != nullptr) { + observer->AdapterPoweredChanged(this, is_powered_); + } + } + } + } + + // Mock the behavior where the device does not support BLE + void SetLowEnergySupported(bool is_supported) { + is_low_energy_supported_ = is_supported; + } + + // Mock the behavior where the device/OS not supports BLE scan offload + void SetScanOffloadSupported(bool is_supported) { + is_scan_offload_supported_ = is_supported; + } + + // Mock the behavior where the device does not support offloaded advertisement + void SetAdvertisementOffloadSupported(bool is_supported) { + is_advertisement_offload_supported_ = is_supported; + } + + // Mock the behavior where the device does not support extended advertising + void SetExtendedAdvertisingSupported(bool is_supported) { + is_extended_advertising_supported_ = is_supported; + } + + // Mock the behavior where the device does not support BLE Peripheral Role + void SetPeripheralRoleSupported(bool is_supported) { + is_peripheral_role_supported_ = is_supported; + } + + int GetNumPresentReceivedFromOS() { return num_present_received_; } + int GetNumPoweredReceivedFromOS() { return num_powered_received_; } + + private: + ObserverList observer_list_; + std::optional mac_address_; + bool is_present_ = true; + bool is_powered_ = true; + bool is_low_energy_supported_ = true; + bool is_scan_offload_supported_ = true; + bool is_advertisement_offload_supported_ = true; + bool is_extended_advertising_supported_ = true; + bool is_peripheral_role_supported_ = true; + int num_present_received_; + int num_powered_received_; +}; + +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_BLUETOOTH_ADAPTER_H_ diff --git a/sharing/internal/test/fake_bluetooth_adapter_observer.h b/sharing/internal/test/fake_bluetooth_adapter_observer.h new file mode 100644 index 00000000..2412801e --- /dev/null +++ b/sharing/internal/test/fake_bluetooth_adapter_observer.h @@ -0,0 +1,63 @@ +// Copyright 2022 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 LOCATION_NEARBY_CPP_SHARING_IMPLEMENTATION_INTERNAL_TEST_FAKE_BLUETOOTH_ADAPTER_OBSERVER_H_ +#define LOCATION_NEARBY_CPP_SHARING_IMPLEMENTATION_INTERNAL_TEST_FAKE_BLUETOOTH_ADAPTER_OBSERVER_H_ + +#include "sharing/internal/api/bluetooth_adapter.h" + +namespace nearby { + +class FakeBluetoothAdapterObserver + : public sharing::api::BluetoothAdapter::Observer { + public: + explicit FakeBluetoothAdapterObserver( + sharing::api::BluetoothAdapter* adapter) { + adapter_ = adapter; + num_adapter_present_changed_ = 0; + num_adapter_powered_changed_ = 0; + } + + void AdapterPresentChanged(sharing::api::BluetoothAdapter* adapter, + bool present) override { + if (adapter == adapter_) { + observed_present_value_ = present; + num_adapter_present_changed_ += 1; + } + } + + void AdapterPoweredChanged(sharing::api::BluetoothAdapter* adapter, + bool powered) override { + if (adapter == adapter_) { + observed_powered_value_ = powered; + num_adapter_powered_changed_ += 1; + } + } + bool GetObservedPresentValue() { return observed_present_value_; } + bool GetObservedPoweredValue() { return observed_powered_value_; } + + int GetNumAdapterPresentChanged() { return num_adapter_present_changed_; } + int GetNumAdapterPoweredChanged() { return num_adapter_powered_changed_; } + + private: + sharing::api::BluetoothAdapter* adapter_; + bool observed_present_value_ = true; + bool observed_powered_value_ = true; + int num_adapter_present_changed_; + int num_adapter_powered_changed_; +}; + +} // namespace nearby + +#endif // LOCATION_NEARBY_CPP_SHARING_IMPLEMENTATION_INTERNAL_TEST_FAKE_BLUETOOTH_ADAPTER_OBSERVER_H_ diff --git a/sharing/internal/test/fake_bluetooth_adapter_test.cc b/sharing/internal/test/fake_bluetooth_adapter_test.cc new file mode 100644 index 00000000..268b2a1f --- /dev/null +++ b/sharing/internal/test/fake_bluetooth_adapter_test.cc @@ -0,0 +1,241 @@ +// Copyright 2022 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 "sharing/internal/test/fake_bluetooth_adapter.h" + +#include + +#include +#include +#include + +#include "gtest/gtest.h" +#include "absl/strings/string_view.h" +#include "sharing/internal/api/bluetooth_adapter.h" +#include "sharing/internal/test/fake_bluetooth_adapter_observer.h" + +namespace nearby { +namespace { + +TEST(FakeBluetoothAdapter, IsPresent) { + FakeBluetoothAdapter fake_bluetooth_adapter; + EXPECT_TRUE(fake_bluetooth_adapter.IsPresent()); +} + +TEST(FakeBluetoothAdapter, IsPowered) { + FakeBluetoothAdapter fake_bluetooth_adapter; + EXPECT_TRUE(fake_bluetooth_adapter.IsPowered()); +} + +TEST(FakeBluetoothAdapter, IsLowEnergySupported) { + FakeBluetoothAdapter fake_bluetooth_adapter; + EXPECT_TRUE(fake_bluetooth_adapter.IsLowEnergySupported()); +} + +TEST(FakeBluetoothAdapter, IsScanOffloadSupported) { + FakeBluetoothAdapter fake_bluetooth_adapter; + EXPECT_TRUE(fake_bluetooth_adapter.IsScanOffloadSupported()); +} + +TEST(FakeBluetoothAdapter, IsAdvertisementOffloadSupported) { + FakeBluetoothAdapter fake_bluetooth_adapter; + EXPECT_TRUE(fake_bluetooth_adapter.IsAdvertisementOffloadSupported()); +} + +TEST(FakeBluetoothAdapter, IsExtendedAdvertisingSupported) { + FakeBluetoothAdapter fake_bluetooth_adapter; + EXPECT_TRUE(fake_bluetooth_adapter.IsExtendedAdvertisingSupported()); +} + +TEST(FakeBluetoothAdapter, IsPeripheralRoleSupported) { + FakeBluetoothAdapter fake_bluetooth_adapter; + EXPECT_TRUE(fake_bluetooth_adapter.IsPeripheralRoleSupported()); +} + +TEST(FakeBluetoothAdapter, GetOSPermissionStatus) { + FakeBluetoothAdapter fake_bluetooth_adapter; + EXPECT_EQ(fake_bluetooth_adapter.GetOsPermissionStatus(), + sharing::api::BluetoothAdapter::PermissionStatus::kAllowed); +} + +TEST(FakeBluetoothAdapter, SetPowered) { + bool powered_on; + std::function success_callback = [&powered_on]() { + powered_on = true; + }; + std::function error_callback = [&powered_on]() { + powered_on = false; + }; + FakeBluetoothAdapter fake_bluetooth_adapter; + fake_bluetooth_adapter.SetPowered(true, success_callback, error_callback); + EXPECT_TRUE(powered_on); +} + +TEST(FakeBluetoothAdapter, GetAdapterId) { + FakeBluetoothAdapter fake_bluetooth_adapter; + EXPECT_EQ(fake_bluetooth_adapter.GetAdapterId(), "nearby"); +} + +TEST(FakeBluetoothAdapter, GetAddress) { + FakeBluetoothAdapter fake_bluetooth_adapter; + fake_bluetooth_adapter.SetAddress("1a:1b:1c:1d:1e:1f"); + // Expected conversion from "1a:1b:1c:1d:1e:1f" + std::array expected_output{{26, 27, 28, 29, 30, 31}}; + EXPECT_EQ(fake_bluetooth_adapter.GetAddress(), expected_output); +} + +TEST(FakeBluetoothAdapter, AddObserver) { + FakeBluetoothAdapter fake_bluetooth_adapter; + FakeBluetoothAdapterObserver fake_observer(&fake_bluetooth_adapter); + fake_bluetooth_adapter.AddObserver(&fake_observer); + EXPECT_TRUE(fake_bluetooth_adapter.HasObserver(&fake_observer)); +} + +TEST(FakeBluetoothAdapter, RemoveObserver) { + FakeBluetoothAdapter fake_bluetooth_adapter; + + FakeBluetoothAdapterObserver fake_observer_1(&fake_bluetooth_adapter); + FakeBluetoothAdapterObserver fake_observer_2(&fake_bluetooth_adapter); + + fake_bluetooth_adapter.AddObserver(&fake_observer_1); + fake_bluetooth_adapter.AddObserver(&fake_observer_2); + + EXPECT_TRUE(fake_bluetooth_adapter.HasObserver(&fake_observer_1)); + EXPECT_TRUE(fake_bluetooth_adapter.HasObserver(&fake_observer_2)); + + fake_bluetooth_adapter.RemoveObserver(&fake_observer_1); + + EXPECT_FALSE(fake_bluetooth_adapter.HasObserver(&fake_observer_1)); + EXPECT_TRUE(fake_bluetooth_adapter.HasObserver(&fake_observer_2)); +} + +TEST(FakeBluetoothAdapter, HasObserver) { + FakeBluetoothAdapter fake_bluetooth_adapter_1; + FakeBluetoothAdapter fake_bluetooth_adapter_2; + + FakeBluetoothAdapterObserver fake_observer_1(&fake_bluetooth_adapter_1); + FakeBluetoothAdapterObserver fake_observer_2(&fake_bluetooth_adapter_2); + + fake_bluetooth_adapter_1.AddObserver(&fake_observer_1); + fake_bluetooth_adapter_2.AddObserver(&fake_observer_2); + + EXPECT_TRUE(fake_bluetooth_adapter_1.HasObserver(&fake_observer_1)); + EXPECT_FALSE(fake_bluetooth_adapter_1.HasObserver(&fake_observer_2)); + + EXPECT_TRUE(fake_bluetooth_adapter_2.HasObserver(&fake_observer_2)); + EXPECT_FALSE(fake_bluetooth_adapter_2.HasObserver(&fake_observer_1)); +} + +TEST(FakeBluetoothAdapter, AdapterPresentChanged) { + FakeBluetoothAdapter fake_bluetooth_adapter_1; + FakeBluetoothAdapter fake_bluetooth_adapter_2; + + FakeBluetoothAdapterObserver fake_observer_1a(&fake_bluetooth_adapter_1); + FakeBluetoothAdapterObserver fake_observer_1b(&fake_bluetooth_adapter_1); + FakeBluetoothAdapterObserver fake_observer_2(&fake_bluetooth_adapter_2); + + fake_bluetooth_adapter_1.AddObserver(&fake_observer_1a); + fake_bluetooth_adapter_1.AddObserver(&fake_observer_1b); + fake_bluetooth_adapter_2.AddObserver(&fake_observer_2); + + // Mocking OS adapter presence changed events (enabled -> disabled/unplugged) + fake_bluetooth_adapter_1.ReceivedAdapterPresentChangedFromOs(false); + + EXPECT_FALSE(fake_observer_1a.GetObservedPresentValue()); + EXPECT_FALSE(fake_observer_1b.GetObservedPresentValue()); + EXPECT_TRUE(fake_observer_2.GetObservedPresentValue()); +} + +TEST(FakeBluetoothAdapter, AdapterPoweredChanged) { + FakeBluetoothAdapter fake_bluetooth_adapter_1; + FakeBluetoothAdapter fake_bluetooth_adapter_2; + + FakeBluetoothAdapterObserver fake_observer_1a(&fake_bluetooth_adapter_1); + FakeBluetoothAdapterObserver fake_observer_1b(&fake_bluetooth_adapter_1); + FakeBluetoothAdapterObserver fake_observer_2(&fake_bluetooth_adapter_2); + + fake_bluetooth_adapter_1.AddObserver(&fake_observer_1a); + fake_bluetooth_adapter_1.AddObserver(&fake_observer_1b); + fake_bluetooth_adapter_2.AddObserver(&fake_observer_2); + + // Mocking OS adapter powered changed events (on -> off) + fake_bluetooth_adapter_1.ReceivedAdapterPoweredChangedFromOs(false); + + EXPECT_FALSE(fake_observer_1a.GetObservedPoweredValue()); + EXPECT_FALSE(fake_observer_1b.GetObservedPoweredValue()); + EXPECT_TRUE(fake_observer_2.GetObservedPoweredValue()); +} + +TEST(FakeBluetoothAdapter, RepeatedAdapterPresentChanged) { + FakeBluetoothAdapter fake_bluetooth_adapter; + + FakeBluetoothAdapterObserver fake_observer_1(&fake_bluetooth_adapter); + FakeBluetoothAdapterObserver fake_observer_2(&fake_bluetooth_adapter); + + fake_bluetooth_adapter.AddObserver(&fake_observer_1); + fake_bluetooth_adapter.AddObserver(&fake_observer_2); + + // Mocking first OS adapter present changed event (enabled -> + // disabled/unplugged) + fake_bluetooth_adapter.ReceivedAdapterPresentChangedFromOs(false); + + EXPECT_EQ(fake_bluetooth_adapter.GetNumPresentReceivedFromOS(), 1); + EXPECT_EQ(fake_observer_1.GetNumAdapterPresentChanged(), 1); + EXPECT_EQ(fake_observer_2.GetNumAdapterPresentChanged(), 1); + + // Mocking second OS adapter present changed event (enabled -> + // disabled/unplugged) + fake_bluetooth_adapter.ReceivedAdapterPresentChangedFromOs(false); + + // Since it is a repeated event, do not inform observers + // i.e. observers have still only updated the state change once + EXPECT_EQ(fake_bluetooth_adapter.GetNumPresentReceivedFromOS(), 2); + EXPECT_EQ(fake_observer_1.GetNumAdapterPresentChanged(), 1); + EXPECT_EQ(fake_observer_2.GetNumAdapterPresentChanged(), 1); + + EXPECT_FALSE(fake_observer_1.GetObservedPresentValue()); + EXPECT_FALSE(fake_observer_2.GetObservedPresentValue()); +} + +TEST(FakeBluetoothAdapter, RepeatedAdapterPoweredChanged) { + FakeBluetoothAdapter fake_bluetooth_adapter; + + FakeBluetoothAdapterObserver fake_observer_1(&fake_bluetooth_adapter); + FakeBluetoothAdapterObserver fake_observer_2(&fake_bluetooth_adapter); + + fake_bluetooth_adapter.AddObserver(&fake_observer_1); + fake_bluetooth_adapter.AddObserver(&fake_observer_2); + + // Mocking first OS adapter powered changed event (on -> off) + fake_bluetooth_adapter.ReceivedAdapterPoweredChangedFromOs(false); + + EXPECT_EQ(fake_bluetooth_adapter.GetNumPoweredReceivedFromOS(), 1); + EXPECT_EQ(fake_observer_1.GetNumAdapterPoweredChanged(), 1); + EXPECT_EQ(fake_observer_2.GetNumAdapterPoweredChanged(), 1); + + // Mocking second OS adapter powered changed event (on -> off) + fake_bluetooth_adapter.ReceivedAdapterPoweredChangedFromOs(false); + + // Since it is a repeated event, do not inform observers + // i.e. observers have still only updated the state change once + EXPECT_EQ(fake_bluetooth_adapter.GetNumPoweredReceivedFromOS(), 2); + EXPECT_EQ(fake_observer_1.GetNumAdapterPoweredChanged(), 1); + EXPECT_EQ(fake_observer_2.GetNumAdapterPoweredChanged(), 1); + + EXPECT_FALSE(fake_observer_1.GetObservedPoweredValue()); + EXPECT_FALSE(fake_observer_2.GetObservedPoweredValue()); +} + +} // namespace +} // namespace nearby diff --git a/sharing/internal/test/fake_connectivity_manager.h b/sharing/internal/test/fake_connectivity_manager.h new file mode 100644 index 00000000..2cbe2a94 --- /dev/null +++ b/sharing/internal/test/fake_connectivity_manager.h @@ -0,0 +1,64 @@ +// 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_CONNECTIVITY_MANAGER_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_CONNECTIVITY_MANAGER_H_ + +#include +#include +#include + +#include "absl/container/flat_hash_map.h" +#include "absl/strings/string_view.h" +#include "sharing/internal/public/connectivity_manager.h" + +namespace nearby { + +class FakeConnectivityManager : public ConnectivityManager { + public: + bool IsLanConnected() override { return is_lan_connected_; } + + ConnectionType GetConnectionType() override { return connection_type_; } + + void RegisterConnectionListener( + absl::string_view listener_name, + std::function callback) override { + listeners_.emplace(listener_name, std::move(callback)); + } + void UnregisterConnectionListener(absl::string_view listener_name) override { + listeners_.erase(listener_name); + } + + // Mocks connectivity methods. + void SetLanConnected(bool connected) { is_lan_connected_ = connected; } + + // Mocks connectivity methods. + void SetConnectionType(ConnectionType connection_type) { + connection_type_ = connection_type; + for (auto& listener : listeners_) { + listener.second(connection_type, is_lan_connected_); + } + } + int GetListenerCount() const { return listeners_.size(); } + + private: + bool is_lan_connected_ = true; + ConnectionType connection_type_ = ConnectionType::kWifi; + absl::flat_hash_map> + listeners_; +}; + +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_CONNECTIVITY_MANAGER_H_ diff --git a/sharing/internal/test/fake_connectivity_manager_test.cc b/sharing/internal/test/fake_connectivity_manager_test.cc new file mode 100644 index 00000000..5b883cad --- /dev/null +++ b/sharing/internal/test/fake_connectivity_manager_test.cc @@ -0,0 +1,71 @@ +// 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 "sharing/internal/test/fake_connectivity_manager.h" + +#include + +#include "gtest/gtest.h" +#include "sharing/internal/public/connectivity_manager.h" + +namespace nearby { +namespace { + +TEST(FakeConnectivityManager, TestIsLanConnected) { + FakeConnectivityManager connection_manager; + bool is_lan_connected = connection_manager.IsLanConnected(); + ASSERT_TRUE(is_lan_connected); + connection_manager.SetLanConnected(false); + EXPECT_FALSE(connection_manager.IsLanConnected()); +} + +TEST(FakeConnectivityManager, TestGetCurrentConnection) { + FakeConnectivityManager connection_manager; + ConnectivityManager::ConnectionType connection = + connection_manager.GetConnectionType(); + EXPECT_EQ(connection, ConnectivityManager::ConnectionType::kWifi); + connection_manager.SetConnectionType( + ConnectivityManager::ConnectionType::kEthernet); + EXPECT_EQ(connection_manager.GetConnectionType(), + ConnectivityManager::ConnectionType::kEthernet); +} + +TEST(FakeConnectivityManager, TestListener) { + FakeConnectivityManager connection_manager; + ConnectivityManager::ConnectionType connection_type = + connection_manager.GetConnectionType(); + bool is_lan_connected = false; + connection_manager.RegisterConnectionListener( + "test", + [&connection_type, &is_lan_connected]( + ConnectivityManager::ConnectionType connection, bool connected) { + connection_type = connection; + is_lan_connected = connected; + }); + EXPECT_EQ(connection_manager.GetListenerCount(), 1); + connection_manager.SetConnectionType( + ConnectivityManager::ConnectionType::kEthernet); + connection_manager.SetLanConnected(true); + EXPECT_EQ(connection_type, ConnectivityManager::ConnectionType::kEthernet); + ASSERT_TRUE(is_lan_connected); + connection_manager.UnregisterConnectionListener("test"); + EXPECT_EQ(connection_manager.GetListenerCount(), 0); + connection_manager.SetConnectionType( + ConnectivityManager::ConnectionType::kWifi); + EXPECT_EQ(connection_type, ConnectivityManager::ConnectionType::kEthernet); + EXPECT_TRUE(is_lan_connected); +} + +} // namespace +} // namespace nearby diff --git a/sharing/internal/test/fake_context.cc b/sharing/internal/test/fake_context.cc new file mode 100644 index 00000000..53887f2a --- /dev/null +++ b/sharing/internal/test/fake_context.cc @@ -0,0 +1,108 @@ +// Copyright 2021-2023 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 "sharing/internal/test/fake_context.h" + +#include + +#include +#include +#include + +#include "absl/status/status.h" +#include "absl/strings/string_view.h" +#include "internal/network/url.h" +#include "internal/platform/clock.h" +#include "internal/platform/task_runner.h" +#include "internal/platform/timer.h" +#include "internal/test/fake_clock.h" +#include "internal/test/fake_task_runner.h" +#include "internal/test/fake_timer.h" +#include "sharing/internal/api/bluetooth_adapter.h" +#include "sharing/internal/api/fast_initiation_manager.h" +#include "sharing/internal/api/shell.h" +#include "sharing/internal/api/wifi_adapter.h" +#include "sharing/internal/public/connectivity_manager.h" +#include "sharing/internal/test/fake_bluetooth_adapter.h" +#include "sharing/internal/test/fake_connectivity_manager.h" +#include "sharing/internal/test/fake_fast_initiation_manager.h" +#include "sharing/internal/test/fake_shell.h" +#include "sharing/internal/test/fake_wifi_adapter.h" + +namespace nearby { + +FakeContext::FakeContext() + : fake_clock_(std::make_unique()), + connectivity_manager_(std::make_unique()), + bluetooth_adapter_(std::make_unique()), + wifi_adapter_(std::make_unique()), + fast_initiation_manager_(std::make_unique()), + shell_(std::make_unique()), + executor_(std::make_unique( + dynamic_cast(GetClock()), 5)) {} + +Clock* FakeContext::GetClock() const { return fake_clock_.get(); } + +std::unique_ptr FakeContext::CreateTimer() { + return std::make_unique(fake_clock_.get()); +} + +void FakeContext::OpenUrl(const nearby::network::Url& url, + std::function callback) { + // OpenUrl is an interface that depends on platform API. In a mock method, it + // returns OK to avoid breaking test cases in the Nearby Sharing SDK. + std::move(callback)(absl::OkStatus()); +} + +void FakeContext::CopyText(const absl::string_view text, + std::function callback) { + // CopyText is an interface that depends on platform API. In a mock method, it + // returns OK to avoid breaking test cases in the Nearby Sharing SDK. + std::move(callback)(absl::OkStatus()); +} + +ConnectivityManager* FakeContext::GetConnectivityManager() const { + return connectivity_manager_.get(); +} + +sharing::api::BluetoothAdapter& FakeContext::GetBluetoothAdapter() const { + return *bluetooth_adapter_; +} + +sharing::api::WifiAdapter& FakeContext::GetWifiAdapter() const { + return *wifi_adapter_; +} + +api::FastInitiationManager& FakeContext::GetFastInitiationManager() const { + return *fast_initiation_manager_; +} + +std::unique_ptr FakeContext::CreateSequencedTaskRunner() const { + std::unique_ptr task_runner = + std::make_unique(dynamic_cast(GetClock()), 1); + return task_runner; +} + +std::unique_ptr FakeContext::CreateConcurrentTaskRunner( + uint32_t concurrent_count) const { + std::unique_ptr task_runner = std::make_unique( + dynamic_cast(GetClock()), concurrent_count); + return task_runner; +} + +api::Shell& FakeContext::GetShell() const { return *shell_; } + +TaskRunner* FakeContext::GetTaskRunner() { return executor_.get(); } + +} // namespace nearby diff --git a/sharing/internal/test/fake_context.h b/sharing/internal/test/fake_context.h new file mode 100644 index 00000000..305f46cd --- /dev/null +++ b/sharing/internal/test/fake_context.h @@ -0,0 +1,74 @@ +// Copyright 2021-2023 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_CONTEXT_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_CONTEXT_H_ + +#include + +#include +#include + +#include "absl/status/status.h" +#include "absl/strings/string_view.h" +#include "internal/network/url.h" +#include "internal/platform/clock.h" +#include "internal/platform/task_runner.h" +#include "internal/platform/timer.h" +#include "internal/test/fake_clock.h" +#include "sharing/internal/api/bluetooth_adapter.h" +#include "sharing/internal/api/fast_initiation_manager.h" +#include "sharing/internal/api/shell.h" +#include "sharing/internal/api/wifi_adapter.h" +#include "sharing/internal/public/connectivity_manager.h" +#include "sharing/internal/public/context.h" + +namespace nearby { + +class FakeContext : public Context { + public: + FakeContext(); + ~FakeContext() override = default; + + Clock* GetClock() const override; + std::unique_ptr CreateTimer() override; + void OpenUrl(const nearby::network::Url& url, + std::function callback) override; + ConnectivityManager* GetConnectivityManager() const override; + sharing::api::BluetoothAdapter& GetBluetoothAdapter() const override; + sharing::api::WifiAdapter& GetWifiAdapter() const override; + api::FastInitiationManager& GetFastInitiationManager() const override; + std::unique_ptr CreateSequencedTaskRunner() const override; + std::unique_ptr CreateConcurrentTaskRunner( + uint32_t concurrent_count) const override; + api::Shell& GetShell() const override; + void CopyText(absl::string_view text, + std::function callback) override; + TaskRunner* GetTaskRunner() override; + + FakeClock* fake_clock() const { return fake_clock_.get(); } + + private: + std::unique_ptr fake_clock_; + std::unique_ptr connectivity_manager_; + std::unique_ptr bluetooth_adapter_; + std::unique_ptr wifi_adapter_; + std::unique_ptr fast_initiation_manager_; + std::unique_ptr shell_; + std::unique_ptr executor_; +}; + +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_CONTEXT_H_ diff --git a/sharing/internal/test/fake_context_test.cc b/sharing/internal/test/fake_context_test.cc new file mode 100644 index 00000000..0b0c3152 --- /dev/null +++ b/sharing/internal/test/fake_context_test.cc @@ -0,0 +1,48 @@ +// Copyright 2021-2023 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 "sharing/internal/test/fake_context.h" + +#include "gtest/gtest.h" +#include "absl/synchronization/notification.h" +#include "absl/time/time.h" +#include "internal/platform/task_runner.h" + +namespace nearby { +namespace { + +TEST(FakeContext, TestAccessMockContext) { + FakeContext context; + EXPECT_NE(context.GetClock(), nullptr); + EXPECT_NE(context.CreateTimer(), nullptr); + EXPECT_NE(context.GetConnectivityManager(), nullptr); + EXPECT_NE(context.CreateSequencedTaskRunner(), nullptr); + EXPECT_NE(context.CreateConcurrentTaskRunner(5), nullptr); +} + +TEST(FakeContext, ExecuteTask) { + FakeContext context; + absl::Notification notification; + bool is_called = false; + context.GetTaskRunner()->PostTask([&]() { + is_called = true; + notification.Notify(); + }); + + EXPECT_TRUE(notification.WaitForNotificationWithTimeout(absl::Seconds(1))); + EXPECT_TRUE(is_called); +} + +} // namespace +} // namespace nearby diff --git a/sharing/internal/test/fake_fast_initiation_manager.h b/sharing/internal/test/fake_fast_initiation_manager.h new file mode 100644 index 00000000..9b58d3fc --- /dev/null +++ b/sharing/internal/test/fake_fast_initiation_manager.h @@ -0,0 +1,98 @@ +// Copyright 2022 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_FAST_INITIATION_MANAGER_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_FAST_INITIATION_MANAGER_H_ + +#include +#include + +#include "sharing/internal/api/fast_init_ble_beacon.h" +#include "sharing/internal/api/fast_initiation_manager.h" + +namespace nearby { + +class FakeFastInitiationManager : public api::FastInitiationManager { + public: + FakeFastInitiationManager() : api::FastInitiationManager() {} + void StartAdvertising(api::FastInitBleBeacon::FastInitType type, + std::function callback, + std::function + error_callback) override { + advertising_started_callback_ = std::move(callback); + advertising_error_callback_ = std::move(error_callback); + is_advertising_ = true; + } + + void StopAdvertising(std::function callback) override { + advertising_stopped_callback_ = std::move(callback); + is_advertising_ = false; + } + + void StartScanning(std::function devices_discovered_callback, + std::function devices_not_discovered_callback, + std::function + error_callback) override { + scanning_discovered_callback_ = std::move(devices_discovered_callback); + scanning_not_discovered_callback_ = + std::move(devices_not_discovered_callback); + scanning_error_callback_ = std::move(error_callback); + is_scanning_ = true; + } + + void StopScanning(std::function callback) override { + scanning_stopped_callback_ = std::move(callback); + is_scanning_ = false; + } + + bool IsAdvertising() override { return is_advertising_; } + + bool IsScanning() override { return is_scanning_; } + + // Mock methods to simulate OS advertising/scanning event callbacks + void SetAdvertisingStarted() { advertising_started_callback_(); } + + void SetAdvertisingError(api::FastInitiationManager::Error error) { + advertising_error_callback_(error); + } + + void SetAdvertisingStopped() { advertising_stopped_callback_(); } + + void SetScanningDiscovered() { scanning_discovered_callback_(); } + + void SetScanningNotDiscovered() { scanning_not_discovered_callback_(); } + + void SetScanningError(api::FastInitiationManager::Error error) { + scanning_error_callback_(error); + } + + void SetScanningStopped() { scanning_stopped_callback_(); } + + private: + bool is_advertising_ = false; + bool is_scanning_ = false; + std::function advertising_started_callback_; + std::function + advertising_error_callback_; + std::function advertising_stopped_callback_; + std::function scanning_discovered_callback_; + std::function scanning_not_discovered_callback_; + std::function + scanning_error_callback_; + std::function scanning_stopped_callback_; +}; + +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_FAST_INITIATION_MANAGER_H_ diff --git a/sharing/internal/test/fake_fast_initiation_manager_test.cc b/sharing/internal/test/fake_fast_initiation_manager_test.cc new file mode 100644 index 00000000..75cc02d4 --- /dev/null +++ b/sharing/internal/test/fake_fast_initiation_manager_test.cc @@ -0,0 +1,83 @@ +// Copyright 2022 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 "sharing/internal/test/fake_fast_initiation_manager.h" + +#include +#include + +#include "gtest/gtest.h" +#include "sharing/internal/api/fast_init_ble_beacon.h" +#include "sharing/internal/api/fast_initiation_manager.h" + +namespace nearby { +namespace { + +TEST(FakeFastInitiationManager, StartAdvertising) { + bool started = false; + std::function success_callback = [&started]() { started = true; }; + std::function error_callback = + [](api::FastInitiationManager::Error) {}; + + FakeFastInitiationManager fast_initiation_manager; + fast_initiation_manager.StartAdvertising( + api::FastInitBleBeacon::FastInitType::kNotify, success_callback, + error_callback); + fast_initiation_manager.SetAdvertisingStarted(); + + EXPECT_TRUE(started); +} + +TEST(FakeFastInitiationManager, StopAdvertising) { + bool stopped = false; + std::function success_callback = [&stopped]() { stopped = true; }; + + FakeFastInitiationManager fast_initiation_manager; + fast_initiation_manager.StopAdvertising(success_callback); + fast_initiation_manager.SetAdvertisingStopped(); + + EXPECT_TRUE(stopped); +} + +TEST(FakeFastInitiationManager, StartScanning) { + bool devices_discovered = false; + std::function devices_discovered_callback = [&devices_discovered]() { + devices_discovered = true; + }; + std::function devices_not_discovered_callback = []() {}; + std::function error_callback = + [](api::FastInitiationManager::Error) {}; + + FakeFastInitiationManager fast_initiation_manager; + fast_initiation_manager.StartScanning(devices_discovered_callback, + devices_not_discovered_callback, + error_callback); + fast_initiation_manager.SetScanningDiscovered(); + + EXPECT_TRUE(devices_discovered); +} + +TEST(FakeFastInitiationManager, StopScanning) { + bool stopped = false; + std::function success_callback = [&stopped]() { stopped = true; }; + + FakeFastInitiationManager fast_initiation_manager; + fast_initiation_manager.StopScanning(success_callback); + fast_initiation_manager.SetScanningStopped(); + + EXPECT_TRUE(stopped); +} + +} // namespace +} // namespace nearby diff --git a/sharing/internal/test/fake_network_monitor.h b/sharing/internal/test/fake_network_monitor.h new file mode 100644 index 00000000..46c21eac --- /dev/null +++ b/sharing/internal/test/fake_network_monitor.h @@ -0,0 +1,51 @@ +// Copyright 2022 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_NETWORK_MONITOR_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_NETWORK_MONITOR_H_ + +#include + +#include "sharing/internal/api/network_monitor.h" + +namespace nearby { + +class FakeNetworkMonitor : public api::NetworkMonitor { + public: + explicit FakeNetworkMonitor( + std::function callback) + : api::NetworkMonitor(callback) {} + + ~FakeNetworkMonitor() override { callback_ = nullptr; } + + bool IsLanConnected() override { return is_lan_connected_; } + + api::NetworkMonitor::ConnectionType GetCurrentConnection() override { + return api::NetworkMonitor::ConnectionType::kWifi; + } + + void SetLanConnected(bool connected) { is_lan_connected_ = connected; } + + void TestNetworkChangeToEthernet() { + callback_(api::NetworkMonitor::ConnectionType::kEthernet, + is_lan_connected_); + } + + private: + bool is_lan_connected_ = true; +}; + +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_NETWORK_MONITOR_H_ diff --git a/sharing/internal/test/fake_preference_manager.cc b/sharing/internal/test/fake_preference_manager.cc new file mode 100644 index 00000000..9f3e9966 --- /dev/null +++ b/sharing/internal/test/fake_preference_manager.cc @@ -0,0 +1,325 @@ +// Copyright 2023 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 "sharing/internal/test/fake_preference_manager.h" +#include +#include +#include +#include +#include +#include +#include + +#include "absl/strings/string_view.h" +#include "absl/time/time.h" +#include "absl/types/span.h" +#include "sharing/internal/api/private_certificate_data.h" + +namespace nearby { +using ::nearby::sharing::api::PrivateCertificateData; + +template +void FakePreferenceManager::SetValue(absl::string_view key, T value) { + if (values_.contains(key)) { + const Data& data = values_.at(key); + if (std::holds_alternative(data)) { + if (std::get(data) == value) { + return; + } + } + values_.erase(key); + } + values_.emplace(key, value); + NotifyPreferenceChanged(key); +} + +template +T FakePreferenceManager::GetValue(absl::string_view key, + const T& default_value) const { + if (values_.contains(key)) { + const Data& data = values_.at(key); + if (std::holds_alternative(data)) { + return std::get(data); + } + } + return default_value; +} + +template +void FakePreferenceManager::SetArray(absl::string_view key, + absl::Span values) { + std::vector data; + data.reserve(values.size()); + for (T value : values) { + data.push_back(value); + } + if (arrays_.contains(key)) { + if (data == arrays_.at(key)) { + return; + } + arrays_.erase(key); + } + arrays_.emplace(key, data); + NotifyPreferenceChanged(key); +} + +template +std::vector FakePreferenceManager::GetArray( + absl::string_view key, absl::Span default_value) const { + if (arrays_.contains(key)) { + const std::vector& data = arrays_.at(key); + std::vector result; + result.reserve(data.size()); + for (const Data& data : data) { + if (std::holds_alternative(data)) { + result.push_back(std::get(data)); + } + } + return result; + } + return std::vector(default_value.begin(), default_value.end()); +} + +template +void FakePreferenceManager::SetDictionaryValue( + absl::string_view key, absl::string_view dictionary_item, T value) { + auto& dictionary = dictionaries_[key]; + if (dictionary.contains(dictionary_item)) { + const Data& data = dictionary.at(dictionary_item); + if (std::holds_alternative(data)) { + if (std::get(data) == value) { + return; + } + } + dictionary.erase(dictionary_item); + } + dictionary.emplace(dictionary_item, value); + NotifyPreferenceChanged(key); +} + +template +std::optional FakePreferenceManager::GetDictionaryValue( + absl::string_view key, absl::string_view dictionary_item) const { + if (!dictionaries_.contains(key)) { + return std::nullopt; + } + const auto& dictionary = dictionaries_.at(key); + if (dictionary.contains(dictionary_item)) { + const Data& data = dictionary.at(dictionary_item); + if (std::holds_alternative(data)) { + return std::get(data); + } + } + return std::nullopt; +} + +void FakePreferenceManager::SetBoolean(absl::string_view key, bool value) { + SetValue(key, value); +} + +void FakePreferenceManager::SetInteger(absl::string_view key, int value) { + SetValue(key, value); +} + +void FakePreferenceManager::SetInt64(absl::string_view key, int64_t value) { + SetValue(key, value); +} + +void FakePreferenceManager::SetString(absl::string_view key, + absl::string_view value) { + SetValue(key, std::string(value)); +} + +void FakePreferenceManager::SetTime(absl::string_view key, absl::Time value) { + SetValue(key, absl::ToUnixNanos(value)); +} + +void FakePreferenceManager::SetBooleanArray(absl::string_view key, + absl::Span value) { + SetArray(key, value); +} + +void FakePreferenceManager::SetIntegerArray(absl::string_view key, + absl::Span value) { + SetArray(key, value); +} + +void FakePreferenceManager::SetInt64Array(absl::string_view key, + absl::Span value) { + SetArray(key, value); +} + +void FakePreferenceManager::SetStringArray( + absl::string_view key, absl::Span value) { + SetArray(key, value); +} + +void FakePreferenceManager::SetPrivateCertificateArray( + absl::string_view key, + absl::Span value) { + if (certs_.contains(key)) { + certs_.erase(key); + } + certs_.emplace( + key, std::vector(value.begin(), value.end())); +} + +void FakePreferenceManager::SetCertificateExpirationArray( + absl::string_view key, + absl::Span> value) { + if (cert_expirations_.contains(key)) { + cert_expirations_.erase(key); + } + cert_expirations_.emplace(key, std::vector>( + value.begin(), value.end())); +} + +void FakePreferenceManager::SetDictionaryBooleanValue( + absl::string_view key, absl::string_view dictionary_item, bool value) { + SetDictionaryValue(key, dictionary_item, value); +} + +void FakePreferenceManager::SetDictionaryIntegerValue( + absl::string_view key, absl::string_view dictionary_item, int value) { + SetDictionaryValue(key, dictionary_item, value); +} + +void FakePreferenceManager::SetDictionaryInt64Value( + absl::string_view key, absl::string_view dictionary_item, int64_t value) { + SetDictionaryValue(key, dictionary_item, value); +} + +void FakePreferenceManager::SetDictionaryStringValue( + absl::string_view key, absl::string_view dictionary_item, + std::string value) { + SetDictionaryValue(key, dictionary_item, value); +} + +void FakePreferenceManager::RemoveDictionaryItem( + absl::string_view key, absl::string_view dictionary_item) { + if (!dictionaries_.contains(key)) { + return; + } + auto& dictionary = dictionaries_[key]; + dictionary.erase(dictionary_item); + NotifyPreferenceChanged(key); +} + + +bool FakePreferenceManager::GetBoolean(absl::string_view key, + bool default_value) const { + return GetValue(key, default_value); +} + +int FakePreferenceManager::GetInteger(absl::string_view key, + int default_value) const { + return GetValue(key, default_value); +} + +int64_t FakePreferenceManager::GetInt64(absl::string_view key, + int64_t default_value) const { + return GetValue(key, default_value); +} + +std::string FakePreferenceManager::GetString( + absl::string_view key, const std::string& default_value) const { + return GetValue(key, default_value); +} + +absl::Time FakePreferenceManager::GetTime(absl::string_view key, + absl::Time default_value) const { + return absl::FromUnixNanos(GetValue(key, absl::ToUnixNanos(default_value))); +} + +std::vector FakePreferenceManager::GetBooleanArray( + absl::string_view key, absl::Span default_value) const { + return GetArray(key, default_value); +} + +std::vector FakePreferenceManager::GetIntegerArray( + absl::string_view key, absl::Span default_value) const { + return GetArray(key, default_value); +} + +std::vector FakePreferenceManager::GetInt64Array( + absl::string_view key, absl::Span default_value) const { + return GetArray(key, default_value); +} + +std::vector FakePreferenceManager::GetStringArray( + absl::string_view key, absl::Span default_value) const { + return GetArray(key, default_value); +} + +std::vector +FakePreferenceManager::GetPrivateCertificateArray(absl::string_view key) const { + if (certs_.contains(key)) { + return certs_.at(key); + } + return std::vector(); +} + +std::vector> +FakePreferenceManager::GetCertificateExpirationArray( + absl::string_view key) const { + if (cert_expirations_.contains(key)) { + return cert_expirations_.at(key); + } + return std::vector>(); +} + +std::optional FakePreferenceManager::GetDictionaryBooleanValue( + absl::string_view key, absl::string_view dictionary_item) const { + return GetDictionaryValue(key, dictionary_item); +} + +std::optional FakePreferenceManager::GetDictionaryIntegerValue( + absl::string_view key, absl::string_view dictionary_item) const { + return GetDictionaryValue(key, dictionary_item); +} + +std::optional FakePreferenceManager::GetDictionaryInt64Value( + absl::string_view key, absl::string_view dictionary_item) const { + return GetDictionaryValue(key, dictionary_item); +} + +std::optional FakePreferenceManager::GetDictionaryStringValue( + absl::string_view key, absl::string_view dictionary_item) const { + return GetDictionaryValue(key, dictionary_item); +} + +void FakePreferenceManager::Remove(absl::string_view key) { + values_.erase(key); + arrays_.erase(key); + dictionaries_.erase(key); + NotifyPreferenceChanged(key); +} + +void FakePreferenceManager::NotifyPreferenceChanged(absl::string_view key) { + for (const auto& observer : observers_) { + observer.second(key); + } +} + +void FakePreferenceManager::AddObserver( + absl::string_view name, + std::function observer) { + observers_.emplace(name, observer); +} + +void FakePreferenceManager::RemoveObserver(absl::string_view name) { + observers_.erase(name); +} + +} // namespace nearby diff --git a/sharing/internal/test/fake_preference_manager.h b/sharing/internal/test/fake_preference_manager.h new file mode 100644 index 00000000..709e4d27 --- /dev/null +++ b/sharing/internal/test/fake_preference_manager.h @@ -0,0 +1,153 @@ +// Copyright 2023 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_PREFERENCE_MANAGER_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_PREFERENCE_MANAGER_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "absl/container/flat_hash_map.h" +#include "absl/strings/string_view.h" +#include "absl/time/time.h" +#include "absl/types/span.h" +#include "sharing/internal/api/preference_manager.h" +#include "sharing/internal/api/private_certificate_data.h" + +namespace nearby { + +// An in memory fake PreferenceManager implementation for testing. +class FakePreferenceManager : public nearby::sharing::api::PreferenceManager { + public: + void SetBoolean(absl::string_view key, bool value) override; + void SetInteger(absl::string_view key, int value) override; + void SetInt64(absl::string_view key, int64_t value) override; + void SetString(absl::string_view key, absl::string_view value) override; + void SetTime(absl::string_view key, absl::Time value) override; + + void SetBooleanArray(absl::string_view key, + absl::Span value) override; + void SetIntegerArray(absl::string_view key, + absl::Span value) override; + void SetInt64Array(absl::string_view key, + absl::Span value) override; + void SetStringArray(absl::string_view key, + absl::Span value) override; + void SetPrivateCertificateArray( + absl::string_view key, + absl::Span value) + override; + void SetCertificateExpirationArray( + absl::string_view key, + absl::Span> value) override; + + void SetDictionaryBooleanValue(absl::string_view key, + absl::string_view dictionary_item, + bool value) override; + void SetDictionaryIntegerValue(absl::string_view key, + absl::string_view dictionary_item, + int value) override; + void SetDictionaryInt64Value(absl::string_view key, + absl::string_view dictionary_item, + int64_t value) override; + void SetDictionaryStringValue(absl::string_view key, + absl::string_view dictionary_item, + std::string value) override; + void RemoveDictionaryItem(absl::string_view key, + absl::string_view dictionary_item) override; + + bool GetBoolean(absl::string_view key, bool default_value) const override; + int GetInteger(absl::string_view key, int default_value) const override; + int64_t GetInt64(absl::string_view key, int64_t default_value) const override; + std::string GetString(absl::string_view key, + const std::string& default_value) const override; + absl::Time GetTime(absl::string_view key, + absl::Time default_value) const override; + + std::vector GetBooleanArray( + absl::string_view key, + absl::Span default_value) const override; + std::vector GetIntegerArray( + absl::string_view key, + absl::Span default_value) const override; + std::vector GetInt64Array( + absl::string_view key, + absl::Span default_value) const override; + std::vector GetStringArray( + absl::string_view key, + absl::Span default_value) const override; + std::vector + GetPrivateCertificateArray(absl::string_view key) const override; + std::vector> GetCertificateExpirationArray( + absl::string_view key) const override; + + std::optional GetDictionaryBooleanValue( + absl::string_view key, absl::string_view dictionary_item) const override; + std::optional GetDictionaryIntegerValue( + absl::string_view key, absl::string_view dictionary_item) const override; + std::optional GetDictionaryInt64Value( + absl::string_view key, absl::string_view dictionary_item) const override; + std::optional GetDictionaryStringValue( + absl::string_view key, absl::string_view dictionary_item) const override; + + void Remove(absl::string_view key) override; + + void AddObserver( + absl::string_view name, + std::function observer) override; + void RemoveObserver(absl::string_view name) override; + + private: + typedef std::variant Data; + + template void SetValue(absl::string_view key, T value); + template + T GetValue(absl::string_view key, const T& default_value) const; + template + void SetArray(absl::string_view key, absl::Span values); + template + std::vector GetArray(absl::string_view key, + absl::Span default_value) const; + template + void SetDictionaryValue(absl::string_view key, + absl::string_view dictionary_item, T value); + template + std::optional GetDictionaryValue(absl::string_view key, + absl::string_view dictionary_item) const; + + void NotifyPreferenceChanged(absl::string_view key); + + absl::flat_hash_map values_; + absl::flat_hash_map> + dictionaries_; + absl::flat_hash_map> arrays_; + absl::flat_hash_map> + certs_; + absl::flat_hash_map>> + cert_expirations_; + + absl::flat_hash_map> + observers_; +}; + +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_PREFERENCE_MANAGER_H_ diff --git a/sharing/internal/test/fake_public_certificate_db.cc b/sharing/internal/test/fake_public_certificate_db.cc new file mode 100644 index 00000000..21494484 --- /dev/null +++ b/sharing/internal/test/fake_public_certificate_db.cc @@ -0,0 +1,81 @@ +// Copyright 2022 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 "sharing/internal/test/fake_public_certificate_db.h" + +#include +#include +#include +#include + +#include "absl/container/flat_hash_map.h" +#include "absl/functional/any_invocable.h" +#include "absl/types/span.h" +#include "sharing/internal/api/public_certificate_database.h" +#include "sharing/proto/rpc_resources.pb.h" + +namespace nearby { + +using ::nearby::sharing::proto::PublicCertificate; + +void FakePublicCertificateDb::Initialize( + absl::AnyInvocable + callback) { + std::move(callback)(PublicCertificateDatabase::InitStatus::kOk); +} + +void FakePublicCertificateDb::LoadEntries( + absl::AnyInvocable>) &&> + callback) { + auto result = std::make_unique>(); + auto it = entries_.begin(); + while (it != entries_.end()) { + result->push_back(it->second); + ++it; + } + + std::move(callback)(true, std::move(result)); +} + +void FakePublicCertificateDb::AddCertificates( + absl::Span certificates, + absl::AnyInvocable callback) { + for (const auto& cert : certificates) { + if (entries_.contains(cert.secret_id())) { + entries_.erase(cert.secret_id()); + } + entries_.emplace(cert.secret_id(), cert); + } + std::move(callback)(true); +} + +void FakePublicCertificateDb::RemoveCertificatesById( + std::vector ids_to_remove, + absl::AnyInvocable callback) { + auto it = ids_to_remove.begin(); + while (it != ids_to_remove.end()) { + entries_.erase(*it); + ++it; + } + std::move(callback)(true); +} + +void FakePublicCertificateDb::Destroy( + absl::AnyInvocable callback) { + entries_.clear(); + std::move(callback)(true); +} + +} // namespace nearby diff --git a/sharing/internal/test/fake_public_certificate_db.h b/sharing/internal/test/fake_public_certificate_db.h new file mode 100644 index 00000000..e555d910 --- /dev/null +++ b/sharing/internal/test/fake_public_certificate_db.h @@ -0,0 +1,64 @@ +// Copyright 2022 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_PUBLIC_CERTIFICATE_DB_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_PUBLIC_CERTIFICATE_DB_H_ + +#include +#include +#include + +#include "absl/container/flat_hash_map.h" +#include "absl/functional/any_invocable.h" +#include "absl/types/span.h" +#include "sharing/internal/api/public_certificate_database.h" + +namespace nearby { + +class FakePublicCertificateDb + : public nearby::sharing::api::PublicCertificateDatabase { + public: + FakePublicCertificateDb() = default; + ~FakePublicCertificateDb() override = default; + + void Initialize( + absl::AnyInvocable< + void(nearby::sharing::api::PublicCertificateDatabase::InitStatus) &&> + callback) override; + void LoadEntries( + absl::AnyInvocable< + void(bool, std::unique_ptr>) &&> + callback) override; + void AddCertificates( + absl::Span certificates, + absl::AnyInvocable callback) override; + void RemoveCertificatesById( + std::vector ids_to_remove, + absl::AnyInvocable callback) override; + void Destroy(absl::AnyInvocable callback) override; + + absl::flat_hash_map + GetCertificatesMap() { + return entries_; + } + + private: + absl::flat_hash_map + entries_; +}; + +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_PUBLIC_CERTIFICATE_DB_H_ diff --git a/sharing/internal/test/fake_shell.h b/sharing/internal/test/fake_shell.h new file mode 100644 index 00000000..5c426b2e --- /dev/null +++ b/sharing/internal/test/fake_shell.h @@ -0,0 +1,60 @@ +// Copyright 2022 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_SHELL_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_SHELL_H_ + +#include // NOLINT(build/c++17) +#include +#include +#include +#include + +#include "absl/status/status.h" +#include "absl/strings/str_cat.h" +#include "sharing/internal/api/shell.h" +#include "sharing/internal/public/logging.h" + +namespace nearby { + +class FakeShell : public api::Shell { + public: + FakeShell() = default; + + // Open file by application. The mock method doesn't use the path + // parameter. The callback result is controlled by return_error_. + void Open(const std::filesystem::path& path, + std::function callback) override { + if (!std::filesystem::exists(path)) { + NL_LOG(WARNING) << "the path " << path << " is not existed."; + } + + if (return_error_) { + std::move(callback)(absl::UnknownError(absl::StrCat("error code:", 12))); + return; + } + + std::move(callback)(absl::OkStatus()); + } + + // Mock methods. + void set_return_error(bool return_error) { return_error_ = return_error; } + + private: + bool return_error_ = false; +}; + +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_SHELL_H_ diff --git a/sharing/internal/test/fake_shell_test.cc b/sharing/internal/test/fake_shell_test.cc new file mode 100644 index 00000000..820f0315 --- /dev/null +++ b/sharing/internal/test/fake_shell_test.cc @@ -0,0 +1,42 @@ +// Copyright 2022 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 "sharing/internal/test/fake_shell.h" + +#include // NOLINT(build/c++17) +#include + +#include "gtest/gtest.h" +#include "absl/status/status.h" + +namespace nearby { +namespace { + +TEST(FakeShell, Open) { + FakeShell shell; + absl::Status result; + shell.Open(std::filesystem::temp_directory_path(), + [&](absl::Status status) { result = status; }); + EXPECT_TRUE(result.ok()); +} + +TEST(FakeShell, OpenFailed) { + FakeShell shell; + shell.set_return_error(true); + absl::Status result; + shell.Open("c:\\windows", [&](absl::Status status) { result = status; }); +} + +} // namespace +} // namespace nearby diff --git a/sharing/internal/test/fake_wifi_adapter.h b/sharing/internal/test/fake_wifi_adapter.h new file mode 100644 index 00000000..51d1ee01 --- /dev/null +++ b/sharing/internal/test/fake_wifi_adapter.h @@ -0,0 +1,125 @@ +// Copyright 2023 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_WIFI_ADAPTER_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_WIFI_ADAPTER_H_ + +#include +#include +#include + +#include "absl/status/status.h" +#include "absl/strings/string_view.h" +#include "internal/base/observer_list.h" +#include "sharing/internal/api/wifi_adapter.h" + +namespace nearby { + +class FakeWifiAdapter : public sharing::api::WifiAdapter { + public: + FakeWifiAdapter() { + num_present_received_ = 0; + num_powered_received_ = 0; + } + + ~FakeWifiAdapter() override = default; + + bool IsPresent() const override { return is_present_; } + + bool IsPowered() const override { + // If the Wi-Fi adapter is not present, return false for power status. + if (!is_present_) { + return false; + } + + return is_powered_; + } + + sharing::api::WifiAdapter::PermissionStatus GetOsPermissionStatus() + const override { + return sharing::api::WifiAdapter::PermissionStatus::kAllowed; + } + + void SetPowered(bool powered, std::function success_callback, + std::function error_callback) override { + success_callback(); + } + + std::optional GetAdapterId() const override { return "nearby"; } + + void AddObserver(Observer* observer) override { + observer_list_.AddObserver(observer); + } + void RemoveObserver(Observer* observer) override { + observer_list_.RemoveObserver(observer); + } + bool HasObserver(Observer* observer) override { + return observer_list_.HasObserver(observer); + } + + void JoinNetwork(absl::string_view ssid, absl::string_view password, + std::function callback) override { + callback(absl::OkStatus()); + } + + // Mock OS Wi-Fi adapter presence state changed events + void ReceivedAdapterPresentChangedFromOs(bool present) { + num_present_received_ += 1; + + bool was_present = IsPresent(); + bool is_present = present; + + // Only trigger when state of presence changes values + if (was_present != is_present) { + is_present_ = is_present; + for (Observer* observer : observer_list_.GetObservers()) { + if (observer != nullptr) { + observer->AdapterPresentChanged(this, is_present_); + } + } + } + } + + // Mock OS Wi-Fi adapter powered state changed events + void ReceivedAdapterPoweredChangedFromOs(bool powered) { + num_powered_received_ += 1; + + bool was_powered = IsPowered(); + bool is_powered = powered; + + // Only trigger when state of power changes values + if (was_powered != is_powered) { + is_powered_ = is_powered; + for (Observer* observer : observer_list_.GetObservers()) { + if (observer != nullptr) { + observer->AdapterPoweredChanged(this, is_powered_); + } + } + } + } + + int GetNumPresentReceivedFromOS() { return num_present_received_; } + int GetNumPoweredReceivedFromOS() { return num_powered_received_; } + + private: + ObserverList observer_list_; + bool is_present_ = true; + bool is_powered_ = true; + int num_present_received_; + int num_powered_received_; +}; + +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_WIFI_ADAPTER_H_ diff --git a/sharing/internal/test/fake_wifi_adapter_observer.h b/sharing/internal/test/fake_wifi_adapter_observer.h new file mode 100644 index 00000000..c7f9aef1 --- /dev/null +++ b/sharing/internal/test/fake_wifi_adapter_observer.h @@ -0,0 +1,61 @@ +// Copyright 2023 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 THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_WIFI_ADAPTER_OBSERVER_H_ +#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_WIFI_ADAPTER_OBSERVER_H_ + +#include "sharing/internal/api/wifi_adapter.h" + +namespace nearby { + +class FakeWifiAdapterObserver : public sharing::api::WifiAdapter::Observer { + public: + explicit FakeWifiAdapterObserver(sharing::api::WifiAdapter* adapter) { + adapter_ = adapter; + num_adapter_present_changed_ = 0; + num_adapter_powered_changed_ = 0; + } + + void AdapterPresentChanged(sharing::api::WifiAdapter* adapter, + bool present) override { + if (adapter == adapter_) { + observed_present_value_ = present; + num_adapter_present_changed_ += 1; + } + } + + void AdapterPoweredChanged(nearby::sharing::api::WifiAdapter* adapter, + bool powered) override { + if (adapter == adapter_) { + observed_powered_value_ = powered; + num_adapter_powered_changed_ += 1; + } + } + bool GetObservedPresentValue() { return observed_present_value_; } + bool GetObservedPoweredValue() { return observed_powered_value_; } + + int GetNumAdapterPresentChanged() { return num_adapter_present_changed_; } + int GetNumAdapterPoweredChanged() { return num_adapter_powered_changed_; } + + private: + sharing::api::WifiAdapter* adapter_; + bool observed_present_value_ = true; + bool observed_powered_value_ = true; + int num_adapter_present_changed_; + int num_adapter_powered_changed_; +}; + +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_TEST_FAKE_WIFI_ADAPTER_OBSERVER_H_ diff --git a/sharing/internal/test/fake_wifi_adapter_test.cc b/sharing/internal/test/fake_wifi_adapter_test.cc new file mode 100644 index 00000000..770f4391 --- /dev/null +++ b/sharing/internal/test/fake_wifi_adapter_test.cc @@ -0,0 +1,162 @@ +// Copyright 2023 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 "sharing/internal/test/fake_wifi_adapter.h" + +#include +#include + +#include "gtest/gtest.h" +#include "sharing/internal/api/wifi_adapter.h" +#include "sharing/internal/test/fake_wifi_adapter_observer.h" + +namespace nearby { +namespace { + +TEST(FakeWifiAdapter, IsPresentReturnsTrueByDefault) { + FakeWifiAdapter fake_wifi_adapter; + EXPECT_TRUE(fake_wifi_adapter.IsPresent()); +} + +TEST(FakeWifiAdapter, IsPoweredReturnsTrueByDefault) { + FakeWifiAdapter fake_wifi_adapter; + EXPECT_TRUE(fake_wifi_adapter.IsPowered()); +} + +TEST(FakeWifiAdapter, GetOSPermissionStatusReturnsAllowedByDefault) { + FakeWifiAdapter fake_wifi_adapter; + EXPECT_EQ(fake_wifi_adapter.GetOsPermissionStatus(), + sharing::api::WifiAdapter::PermissionStatus::kAllowed); +} + +TEST(FakeWifiAdapter, SetPoweredRunsSuccessCallback) { + bool powered_on; + std::function success_callback = [&powered_on]() { + powered_on = true; + }; + std::function error_callback = [&powered_on]() { + powered_on = false; + }; + FakeWifiAdapter fake_wifi_adapter; + fake_wifi_adapter.SetPowered(/*powered=*/true, success_callback, + error_callback); + EXPECT_TRUE(powered_on); +} + +TEST(FakeWifiAdapter, GetAdapterIdReturnsNearbyByDefault) { + FakeWifiAdapter fake_wifi_adapter; + EXPECT_EQ(fake_wifi_adapter.GetAdapterId(), "nearby"); +} + +TEST(FakeWifiAdapter, HasObserverReturnsTrueAfterAddingObserver) { + FakeWifiAdapter fake_wifi_adapter; + FakeWifiAdapterObserver fake_observer(&fake_wifi_adapter); + fake_wifi_adapter.AddObserver(&fake_observer); + EXPECT_TRUE(fake_wifi_adapter.HasObserver(&fake_observer)); +} + +TEST(FakeWifiAdapter, HasObserverReturnsFalseAfterRemovingObserver) { + FakeWifiAdapter fake_wifi_adapter; + FakeWifiAdapterObserver fake_observer(&fake_wifi_adapter); + + fake_wifi_adapter.AddObserver(&fake_observer); + EXPECT_TRUE(fake_wifi_adapter.HasObserver(&fake_observer)); + + fake_wifi_adapter.RemoveObserver(&fake_observer); + EXPECT_FALSE(fake_wifi_adapter.HasObserver(&fake_observer)); +} + +TEST(FakeWifiAdapter, HasObserver) { + FakeWifiAdapter fake_wifi_adapter; + + FakeWifiAdapterObserver fake_observer_1(&fake_wifi_adapter); + FakeWifiAdapterObserver fake_observer_2(&fake_wifi_adapter); + + fake_wifi_adapter.AddObserver(&fake_observer_1); + + EXPECT_TRUE(fake_wifi_adapter.HasObserver(&fake_observer_1)); + EXPECT_FALSE(fake_wifi_adapter.HasObserver(&fake_observer_2)); +} + +TEST(FakeWifiAdapter, AdapterPresentChanged) { + FakeWifiAdapter fake_wifi_adapter; + FakeWifiAdapterObserver fake_observer(&fake_wifi_adapter); + fake_wifi_adapter.AddObserver(&fake_observer); + + // Mocking OS adapter presence changed events (enabled -> disabled/unplugged) + fake_wifi_adapter.ReceivedAdapterPresentChangedFromOs(/*present=*/false); + EXPECT_FALSE(fake_observer.GetObservedPresentValue()); +} + +TEST(FakeWifiAdapter, AdapterPoweredChanged) { + FakeWifiAdapter fake_wifi_adapter; + FakeWifiAdapterObserver fake_observer(&fake_wifi_adapter); + + fake_wifi_adapter.AddObserver(&fake_observer); + + // Mocking OS adapter powered changed events (on -> off) + fake_wifi_adapter.ReceivedAdapterPoweredChangedFromOs(/*powered=*/false); + EXPECT_FALSE(fake_observer.GetObservedPoweredValue()); +} + +TEST(FakeWifiAdapter, RepeatedAdapterPresentChanged) { + FakeWifiAdapter fake_wifi_adapter; + FakeWifiAdapterObserver fake_observer(&fake_wifi_adapter); + + fake_wifi_adapter.AddObserver(&fake_observer); + + // Mocking first OS adapter present changed event (enabled -> + // disabled/unplugged) + fake_wifi_adapter.ReceivedAdapterPresentChangedFromOs(/*present=*/false); + + EXPECT_EQ(fake_wifi_adapter.GetNumPresentReceivedFromOS(), 1); + EXPECT_EQ(fake_observer.GetNumAdapterPresentChanged(), 1); + + // Mocking second OS adapter present changed event (enabled -> + // disabled/unplugged) + fake_wifi_adapter.ReceivedAdapterPresentChangedFromOs(/*present=*/false); + + // Since it is a repeated event, do not inform observers + // i.e. observers have still only updated the state change once + EXPECT_EQ(fake_wifi_adapter.GetNumPresentReceivedFromOS(), 2); + EXPECT_EQ(fake_observer.GetNumAdapterPresentChanged(), 1); + + EXPECT_FALSE(fake_observer.GetObservedPresentValue()); +} + +TEST(FakeWifiAdapter, RepeatedAdapterPoweredChanged) { + FakeWifiAdapter fake_wifi_adapter; + FakeWifiAdapterObserver fake_observer(&fake_wifi_adapter); + + fake_wifi_adapter.AddObserver(&fake_observer); + + // Mocking first OS adapter powered changed event (on -> off) + fake_wifi_adapter.ReceivedAdapterPoweredChangedFromOs(/*powered=*/false); + + EXPECT_EQ(fake_wifi_adapter.GetNumPoweredReceivedFromOS(), 1); + EXPECT_EQ(fake_observer.GetNumAdapterPoweredChanged(), 1); + + // Mocking second OS adapter powered changed event (on -> off) + fake_wifi_adapter.ReceivedAdapterPoweredChangedFromOs(/*powered=*/false); + + // Since it is a repeated event, do not inform observers + // i.e. observers have still only updated the state change once + EXPECT_EQ(fake_wifi_adapter.GetNumPoweredReceivedFromOS(), 2); + EXPECT_EQ(fake_observer.GetNumAdapterPoweredChanged(), 1); + + EXPECT_FALSE(fake_observer.GetObservedPoweredValue()); +} + +} // namespace +} // namespace nearby diff --git a/sharing/scheduling/BUILD b/sharing/scheduling/BUILD new file mode 100644 index 00000000..00a381bf --- /dev/null +++ b/sharing/scheduling/BUILD @@ -0,0 +1,106 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +licenses(["notice"]) + +cc_library( + name = "format", + srcs = ["format.cc"], + hdrs = ["format.h"], + deps = [ + "@com_google_absl//absl/strings:str_format", + "@com_google_absl//absl/time", + ], +) + +cc_library( + name = "scheduling", + srcs = [ + "nearby_share_expiration_scheduler.cc", + "nearby_share_on_demand_scheduler.cc", + "nearby_share_periodic_scheduler.cc", + "nearby_share_scheduler.cc", + "nearby_share_scheduler_base.cc", + "nearby_share_scheduler_factory.cc", + "nearby_share_scheduler_fields.h", + "nearby_share_scheduler_utils.cc", + ], + hdrs = [ + "nearby_share_expiration_scheduler.h", + "nearby_share_on_demand_scheduler.h", + "nearby_share_periodic_scheduler.h", + "nearby_share_scheduler.h", + "nearby_share_scheduler_base.h", + "nearby_share_scheduler_factory.h", + "nearby_share_scheduler_utils.h", + ], + visibility = ["//visibility:public"], + deps = [ + ":format", + "//sharing/internal/api:platform", + "//sharing/internal/public:logging", + "//sharing/internal/public:types", + "@com_google_absl//absl/strings", + "@com_google_absl//absl/strings:str_format", + "@com_google_absl//absl/time", + ], +) + +cc_library( + name = "test_support", + testonly = True, + srcs = [ + "fake_nearby_share_scheduler.cc", + "fake_nearby_share_scheduler_factory.cc", + ], + hdrs = [ + "fake_nearby_share_scheduler.h", + "fake_nearby_share_scheduler_factory.h", + ], + visibility = ["//visibility:public"], + deps = [ + ":scheduling", + "//internal/platform:types", + "//sharing/internal/api:platform", + "//sharing/internal/public:logging", + "//sharing/internal/public:types", + "@com_google_absl//absl/container:flat_hash_map", + "@com_google_absl//absl/strings", + "@com_google_absl//absl/time", + ], +) + +cc_test( + name = "scheduling_test", + srcs = [ + "nearby_share_expiration_scheduler_test.cc", + "nearby_share_on_demand_scheduler_test.cc", + "nearby_share_periodic_scheduler_test.cc", + "nearby_share_scheduler_base_test.cc", + "nearby_share_scheduler_fields.h", + "nearby_share_scheduler_utils_test.cc", + ], + deps = [ + ":scheduling", + "//internal/platform/implementation/g3", # fixdeps: keep + "//internal/test", + "//sharing/internal/api:platform", + "//sharing/internal/public:types", + "//sharing/internal/test:nearby_test", + "@com_github_protobuf_matchers//protobuf-matchers", + "@com_google_absl//absl/strings", + "@com_google_absl//absl/time", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/sharing/scheduling/fake_nearby_share_scheduler.cc b/sharing/scheduling/fake_nearby_share_scheduler.cc new file mode 100644 index 00000000..8041d73a --- /dev/null +++ b/sharing/scheduling/fake_nearby_share_scheduler.cc @@ -0,0 +1,94 @@ +// 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 "sharing/scheduling/fake_nearby_share_scheduler.h" + +#include + +#include +#include +#include + +#include "absl/time/time.h" +#include "sharing/internal/public/logging.h" +#include "sharing/scheduling/nearby_share_scheduler.h" + +namespace nearby { +namespace sharing { + +FakeNearbyShareScheduler::FakeNearbyShareScheduler(OnRequestCallback callback) + : NearbyShareScheduler(std::move(callback)) {} + +FakeNearbyShareScheduler::~FakeNearbyShareScheduler() = default; + +void FakeNearbyShareScheduler::MakeImmediateRequest() { + ++num_immediate_requests_; +} + +void FakeNearbyShareScheduler::HandleResult(bool success) { + handled_results_.push_back(success); +} + +void FakeNearbyShareScheduler::Reschedule() { ++num_reschedule_calls_; } + +std::optional FakeNearbyShareScheduler::GetLastSuccessTime() const { + return last_success_time_; +} + +std::optional +FakeNearbyShareScheduler::GetTimeUntilNextRequest() const { + return time_until_next_request_; +} + +bool FakeNearbyShareScheduler::IsWaitingForResult() const { + return is_waiting_for_result_; +} + +size_t FakeNearbyShareScheduler::GetNumConsecutiveFailures() const { + return num_consecutive_failures_; +} + +void FakeNearbyShareScheduler::OnStart() { + can_invoke_request_callback_ = true; +} + +void FakeNearbyShareScheduler::OnStop() { + can_invoke_request_callback_ = false; +} + +void FakeNearbyShareScheduler::InvokeRequestCallback() { + NL_DCHECK(can_invoke_request_callback_); + NotifyOfRequest(); +} + +void FakeNearbyShareScheduler::SetLastSuccessTime( + std::optional time) { + last_success_time_ = time; +} + +void FakeNearbyShareScheduler::SetTimeUntilNextRequest( + std::optional time_delta) { + time_until_next_request_ = time_delta; +} + +void FakeNearbyShareScheduler::SetIsWaitingForResult(bool is_waiting) { + is_waiting_for_result_ = is_waiting; +} + +void FakeNearbyShareScheduler::SetNumConsecutiveFailures(size_t num_failures) { + num_consecutive_failures_ = num_failures; +} + +} // namespace sharing +} // namespace nearby diff --git a/sharing/scheduling/fake_nearby_share_scheduler.h b/sharing/scheduling/fake_nearby_share_scheduler.h new file mode 100644 index 00000000..78d5cd7d --- /dev/null +++ b/sharing/scheduling/fake_nearby_share_scheduler.h @@ -0,0 +1,76 @@ +// 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 THIRD_PARTY_NEARBY_SHARING_SCHEDULING_FAKE_NEARBY_SHARE_SCHEDULER_H_ +#define THIRD_PARTY_NEARBY_SHARING_SCHEDULING_FAKE_NEARBY_SHARE_SCHEDULER_H_ + +#include + +#include +#include + +#include "absl/time/time.h" +#include "sharing/scheduling/nearby_share_scheduler.h" + +namespace nearby { +namespace sharing { + +// A fake implementation of NearbyShareScheduler that allows the user to set all +// scheduling data. It tracks the number of immediate requests and the handled +// results. The on-request callback can be invoked using +// InvokeRequestCallback(). +class FakeNearbyShareScheduler : public NearbyShareScheduler { + public: + explicit FakeNearbyShareScheduler(OnRequestCallback callback); + ~FakeNearbyShareScheduler() override; + + // NearbyShareScheduler: + void MakeImmediateRequest() override; + void HandleResult(bool success) override; + void Reschedule() override; + std::optional GetLastSuccessTime() const override; + std::optional GetTimeUntilNextRequest() const override; + bool IsWaitingForResult() const override; + size_t GetNumConsecutiveFailures() const override; + + void SetLastSuccessTime(std::optional time); + void SetTimeUntilNextRequest(std::optional time_delta); + void SetIsWaitingForResult(bool is_waiting); + void SetNumConsecutiveFailures(size_t num_failures); + + void InvokeRequestCallback(); + + size_t num_immediate_requests() const { return num_immediate_requests_; } + size_t num_reschedule_calls() const { return num_reschedule_calls_; } + const std::vector& handled_results() const { return handled_results_; } + + private: + // NearbyShareScheduler: + void OnStart() override; + void OnStop() override; + + bool can_invoke_request_callback_ = false; + size_t num_immediate_requests_ = 0; + size_t num_reschedule_calls_ = 0; + std::vector handled_results_; + std::optional last_success_time_; + std::optional time_until_next_request_; + bool is_waiting_for_result_ = false; + size_t num_consecutive_failures_ = 0; +}; + +} // namespace sharing +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_SCHEDULING_FAKE_NEARBY_SHARE_SCHEDULER_H_ diff --git a/sharing/scheduling/fake_nearby_share_scheduler_factory.cc b/sharing/scheduling/fake_nearby_share_scheduler_factory.cc new file mode 100644 index 00000000..9f51215d --- /dev/null +++ b/sharing/scheduling/fake_nearby_share_scheduler_factory.cc @@ -0,0 +1,124 @@ +// 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 "sharing/scheduling/fake_nearby_share_scheduler_factory.h" + +#include +#include +#include + +#include "absl/container/flat_hash_map.h" +#include "absl/strings/string_view.h" +#include "absl/time/time.h" +#include "internal/platform/clock.h" +#include "sharing/internal/api/preference_manager.h" +#include "sharing/internal/public/context.h" +#include "sharing/scheduling/fake_nearby_share_scheduler.h" +#include "sharing/scheduling/nearby_share_expiration_scheduler.h" +#include "sharing/scheduling/nearby_share_scheduler.h" + +namespace nearby { +namespace sharing { + +using ::nearby::sharing::api::PreferenceManager; + +FakeNearbyShareSchedulerFactory::ExpirationInstance::ExpirationInstance( + PreferenceManager& pref_manager, const nearby::Clock* c) + : preference_manager(pref_manager), + clock(c) {} + +FakeNearbyShareSchedulerFactory::ExpirationInstance::ExpirationInstance( + ExpirationInstance&&) = default; + +FakeNearbyShareSchedulerFactory::ExpirationInstance::~ExpirationInstance() = + default; + +FakeNearbyShareSchedulerFactory::OnDemandInstance::OnDemandInstance( + PreferenceManager& pref_manager, const nearby::Clock* c) + : preference_manager(pref_manager), + clock(c) {} + +FakeNearbyShareSchedulerFactory::PeriodicInstance::PeriodicInstance( + PreferenceManager& pref_manager, const nearby::Clock* c) + : preference_manager(pref_manager), + clock(c) {} + +FakeNearbyShareSchedulerFactory::FakeNearbyShareSchedulerFactory() = default; + +FakeNearbyShareSchedulerFactory::~FakeNearbyShareSchedulerFactory() = default; + +std::unique_ptr +FakeNearbyShareSchedulerFactory::CreateExpirationSchedulerInstance( + Context* context, PreferenceManager& preference_manager, + NearbyShareExpirationScheduler::ExpirationTimeFunctor + expiration_time_functor, + bool retry_failures, bool require_connectivity, absl::string_view pref_name, + NearbyShareScheduler::OnRequestCallback on_request_callback) { + ExpirationInstance instance(preference_manager, context->GetClock()); + instance.expiration_time_functor = std::move(expiration_time_functor); + instance.retry_failures = retry_failures; + instance.require_connectivity = require_connectivity; + + auto scheduler = std::make_unique( + std::move(on_request_callback)); + instance.fake_scheduler = scheduler.get(); + + pref_name_to_expiration_instance_.erase(pref_name); + pref_name_to_expiration_instance_.emplace(pref_name, std::move(instance)); + + return scheduler; +} + +std::unique_ptr +FakeNearbyShareSchedulerFactory::CreateOnDemandSchedulerInstance( + Context* context, PreferenceManager& preference_manager, + bool retry_failures, bool require_connectivity, absl::string_view pref_name, + NearbyShareScheduler::OnRequestCallback callback) { + OnDemandInstance instance(preference_manager, context->GetClock()); + instance.retry_failures = retry_failures; + instance.require_connectivity = require_connectivity; + + auto scheduler = + std::make_unique(std::move(callback)); + instance.fake_scheduler = scheduler.get(); + + pref_name_to_on_demand_instance_.erase(pref_name); + pref_name_to_on_demand_instance_.emplace(pref_name, instance); + + return scheduler; +} + +std::unique_ptr +FakeNearbyShareSchedulerFactory::CreatePeriodicSchedulerInstance( + Context* context, PreferenceManager& preference_manager, + absl::Duration request_period, bool retry_failures, + bool require_connectivity, absl::string_view pref_name, + NearbyShareScheduler::OnRequestCallback callback) { + PeriodicInstance instance(preference_manager, context->GetClock()); + instance.request_period = request_period; + instance.retry_failures = retry_failures; + instance.require_connectivity = require_connectivity; + + auto scheduler = + std::make_unique(std::move(callback)); + instance.fake_scheduler = scheduler.get(); + + pref_name_to_periodic_instance_.erase(pref_name); + pref_name_to_periodic_instance_.emplace(pref_name, instance); + + return scheduler; +} + +} // namespace sharing +} // namespace nearby diff --git a/sharing/scheduling/fake_nearby_share_scheduler_factory.h b/sharing/scheduling/fake_nearby_share_scheduler_factory.h new file mode 100644 index 00000000..f8309598 --- /dev/null +++ b/sharing/scheduling/fake_nearby_share_scheduler_factory.h @@ -0,0 +1,133 @@ +// 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 THIRD_PARTY_NEARBY_SHARING_SCHEDULING_FAKE_NEARBY_SHARE_SCHEDULER_FACTORY_H_ +#define THIRD_PARTY_NEARBY_SHARING_SCHEDULING_FAKE_NEARBY_SHARE_SCHEDULER_FACTORY_H_ + +#include +#include + +#include "absl/container/flat_hash_map.h" +#include "absl/strings/string_view.h" +#include "absl/time/time.h" +#include "sharing/internal/api/preference_manager.h" +#include "sharing/internal/public/context.h" +#include "sharing/scheduling/fake_nearby_share_scheduler.h" +#include "sharing/scheduling/nearby_share_expiration_scheduler.h" +#include "sharing/scheduling/nearby_share_scheduler.h" +#include "sharing/scheduling/nearby_share_scheduler_factory.h" + +namespace nearby { +namespace sharing { + +// A fake NearbyShareScheduler factory that creates instances of +// FakeNearbyShareScheduler instead of expiration, on-demand, or periodic +// scheduler. It stores the factory input parameters as well as a raw pointer to +// the fake scheduler for each instance created. +class FakeNearbyShareSchedulerFactory : public NearbyShareSchedulerFactory { + public: + struct ExpirationInstance { + ExpirationInstance( + nearby::sharing::api::PreferenceManager& pref_manager, + const nearby::Clock* c); + ExpirationInstance(ExpirationInstance&&); + ~ExpirationInstance(); + + FakeNearbyShareScheduler* fake_scheduler = nullptr; + NearbyShareExpirationScheduler::ExpirationTimeFunctor + expiration_time_functor; + bool retry_failures; + bool require_connectivity; + nearby::sharing::api::PreferenceManager& preference_manager; + const nearby::Clock* const clock; + }; + + struct OnDemandInstance { + OnDemandInstance( + nearby::sharing::api::PreferenceManager& pref_manager, + const nearby::Clock* c); + FakeNearbyShareScheduler* fake_scheduler = nullptr; + bool retry_failures; + bool require_connectivity; + nearby::sharing::api::PreferenceManager& preference_manager; + const nearby::Clock* const clock; + }; + + struct PeriodicInstance { + PeriodicInstance( + nearby::sharing::api::PreferenceManager& pref_manager, + const nearby::Clock* c); + FakeNearbyShareScheduler* fake_scheduler = nullptr; + absl::Duration request_period; + bool retry_failures; + bool require_connectivity; + nearby::sharing::api::PreferenceManager& preference_manager; + const nearby::Clock* const clock; + }; + + FakeNearbyShareSchedulerFactory(); + ~FakeNearbyShareSchedulerFactory() override; + + const absl::flat_hash_map& + pref_name_to_expiration_instance() const { + return pref_name_to_expiration_instance_; + } + + const absl::flat_hash_map& + pref_name_to_on_demand_instance() const { + return pref_name_to_on_demand_instance_; + } + + const absl::flat_hash_map& + pref_name_to_periodic_instance() const { + return pref_name_to_periodic_instance_; + } + + private: + // NearbyShareSchedulerFactory: + std::unique_ptr CreateExpirationSchedulerInstance( + Context* context, + nearby::sharing::api::PreferenceManager& preference_manager, + NearbyShareExpirationScheduler::ExpirationTimeFunctor + expiration_time_functor, + bool retry_failures, bool require_connectivity, + absl::string_view pref_name, + NearbyShareScheduler::OnRequestCallback on_request_callback) override; + + std::unique_ptr CreateOnDemandSchedulerInstance( + Context* context, + nearby::sharing::api::PreferenceManager& preference_manager, + bool retry_failures, bool require_connectivity, + absl::string_view pref_name, + NearbyShareScheduler::OnRequestCallback callback) override; + + std::unique_ptr CreatePeriodicSchedulerInstance( + Context* context, + nearby::sharing::api::PreferenceManager& preference_manager, + absl::Duration request_period, bool retry_failures, + bool require_connectivity, absl::string_view pref_name, + NearbyShareScheduler::OnRequestCallback callback) override; + + absl::flat_hash_map + pref_name_to_expiration_instance_; + absl::flat_hash_map + pref_name_to_on_demand_instance_; + absl::flat_hash_map + pref_name_to_periodic_instance_; +}; + +} // namespace sharing +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_SCHEDULING_FAKE_NEARBY_SHARE_SCHEDULER_FACTORY_H_ diff --git a/sharing/scheduling/format.cc b/sharing/scheduling/format.cc new file mode 100644 index 00000000..671cbf04 --- /dev/null +++ b/sharing/scheduling/format.cc @@ -0,0 +1,35 @@ +// 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 "sharing/scheduling/format.h" + +#include + +#include "absl/strings/str_format.h" +#include "absl/time/time.h" + +namespace nearby { +namespace utils { + +std::string TimeFormatShortDateAndTimeWithTimeZone(absl::Time time) { + absl::TimeZone tz = absl::LocalTimeZone(); + return absl::FormatTime("%Y%M%D %H:%M:%S %z", time, tz); +} + +std::string TimeDurationFormatWithSeconds(absl::Duration duration) { + return absl::StrFormat("%ds", duration / absl::Seconds(1)); +} + +} // namespace utils +} // namespace nearby diff --git a/sharing/scheduling/format.h b/sharing/scheduling/format.h new file mode 100644 index 00000000..052a42f3 --- /dev/null +++ b/sharing/scheduling/format.h @@ -0,0 +1,31 @@ +// 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 THIRD_PARTY_NEARBY_SHARING_SCHEDULING_FORMAT_H_ +#define THIRD_PARTY_NEARBY_SHARING_SCHEDULING_FORMAT_H_ + +#include + +#include "absl/time/time.h" + +namespace nearby { +namespace utils { + +std::string TimeFormatShortDateAndTimeWithTimeZone(absl::Time time); +std::string TimeDurationFormatWithSeconds(absl::Duration duration); + +} // namespace utils +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_SCHEDULING_FORMAT_H_ diff --git a/sharing/scheduling/nearby_share_expiration_scheduler.cc b/sharing/scheduling/nearby_share_expiration_scheduler.cc new file mode 100644 index 00000000..ecf15720 --- /dev/null +++ b/sharing/scheduling/nearby_share_expiration_scheduler.cc @@ -0,0 +1,55 @@ +// 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 "sharing/scheduling/nearby_share_expiration_scheduler.h" + +#include +#include + +#include "absl/strings/string_view.h" +#include "absl/time/time.h" +#include "sharing/internal/api/preference_manager.h" +#include "sharing/internal/public/context.h" +#include "sharing/scheduling/nearby_share_scheduler.h" +#include "sharing/scheduling/nearby_share_scheduler_base.h" + +namespace nearby { +namespace sharing { +using ::nearby::sharing::api::PreferenceManager; + +NearbyShareExpirationScheduler::NearbyShareExpirationScheduler( + Context* context, PreferenceManager& preference_manager, + ExpirationTimeFunctor expiration_time_functor, bool retry_failures, + bool require_connectivity, absl::string_view pref_name, + OnRequestCallback on_request_callback) + : NearbyShareSchedulerBase(context, preference_manager, retry_failures, + require_connectivity, pref_name, + std::move(on_request_callback)), + expiration_time_functor_(std::move(expiration_time_functor)) {} + +NearbyShareExpirationScheduler::~NearbyShareExpirationScheduler() = default; + +std::optional +NearbyShareExpirationScheduler::TimeUntilRecurringRequest( + absl::Time now) const { + std::optional expiration_time = expiration_time_functor_(); + if (!expiration_time.has_value()) return std::nullopt; + + if (*expiration_time <= now) return absl::ZeroDuration(); + + return *expiration_time - now; +} + +} // namespace sharing +} // namespace nearby diff --git a/sharing/scheduling/nearby_share_expiration_scheduler.h b/sharing/scheduling/nearby_share_expiration_scheduler.h new file mode 100644 index 00000000..b752e976 --- /dev/null +++ b/sharing/scheduling/nearby_share_expiration_scheduler.h @@ -0,0 +1,59 @@ +// 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 THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_EXPIRATION_SCHEDULER_H_ +#define THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_EXPIRATION_SCHEDULER_H_ + +#include +#include + +#include "absl/strings/string_view.h" +#include "absl/time/time.h" +#include "sharing/internal/api/preference_manager.h" +#include "sharing/internal/public/context.h" +#include "sharing/scheduling/nearby_share_scheduler.h" +#include "sharing/scheduling/nearby_share_scheduler_base.h" + +namespace nearby { +namespace sharing { + +// A NearbyShareSchedulerBase that schedules recurring tasks based on an +// expiration time provided by the owner. +class NearbyShareExpirationScheduler : public NearbyShareSchedulerBase { + public: + using ExpirationTimeFunctor = std::function()>; + + // |expiration_time_functor|: A function provided by the owner that returns + // the next expiration time. + // See NearbyShareSchedulerBase for a description of other inputs. + NearbyShareExpirationScheduler( + Context* context, + nearby::sharing::api::PreferenceManager& preference_manager, + ExpirationTimeFunctor expiration_time_functor, bool retry_failures, + bool require_connectivity, absl::string_view pref_name, + OnRequestCallback on_request_callback); + + ~NearbyShareExpirationScheduler() override; + + protected: + std::optional TimeUntilRecurringRequest( + absl::Time now) const override; + + ExpirationTimeFunctor expiration_time_functor_; +}; + +} // namespace sharing +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_EXPIRATION_SCHEDULER_H_ diff --git a/sharing/scheduling/nearby_share_expiration_scheduler_test.cc b/sharing/scheduling/nearby_share_expiration_scheduler_test.cc new file mode 100644 index 00000000..9409d6fb --- /dev/null +++ b/sharing/scheduling/nearby_share_expiration_scheduler_test.cc @@ -0,0 +1,105 @@ +// 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 "sharing/scheduling/nearby_share_expiration_scheduler.h" + +#include +#include + +#include "gtest/gtest.h" +#include "absl/time/time.h" +#include "internal/test/fake_clock.h" +#include "sharing/internal/test/fake_context.h" +#include "sharing/internal/test/fake_preference_manager.h" +#include "sharing/scheduling/nearby_share_scheduler.h" + +namespace nearby { +namespace sharing { +namespace { + +const char kTestPrefName[] = "test_pref_name"; +constexpr absl::Duration kTestInitialNow = absl::Hours(2400); +constexpr absl::Duration kTestExpirationTimeFromInitialNow = absl::Minutes(123); + +class NearbyShareExpirationSchedulerTest : public ::testing::Test { + protected: + NearbyShareExpirationSchedulerTest() = default; + ~NearbyShareExpirationSchedulerTest() override = default; + + void SetUp() override { + FastForward(kTestInitialNow); + expiration_time_ = Now() + kTestExpirationTimeFromInitialNow; + + preference_manager_.Remove(kTestPrefName); + + scheduler_ = std::make_unique( + &fake_context_, preference_manager_, callback_, + /*retry_failures=*/true, /*require_connectivity=*/true, kTestPrefName, + nullptr); + } + + absl::Time Now() const { return fake_context_.GetClock()->Now(); } + + // Fast-forwards mock time by |delta| and fires relevant timers. + void FastForward(absl::Duration delta) { + fake_context_.fake_clock()->FastForward(delta); + } + + std::optional expiration_time_; + NearbyShareScheduler* scheduler() { return scheduler_.get(); } + + private: + nearby::FakePreferenceManager preference_manager_; + nearby::FakeContext fake_context_; + std::unique_ptr scheduler_ = nullptr; + NearbyShareExpirationScheduler::ExpirationTimeFunctor callback_ = [&]() { + return expiration_time_; + }; +}; + +TEST_F(NearbyShareExpirationSchedulerTest, ExpirationRequest) { + scheduler()->Start(); + + // Wait 5 minutes to make sure the time to the next request only depends on + // the expiration time and the current time. + FastForward(absl::Minutes(5)); + + EXPECT_EQ(scheduler()->GetTimeUntilNextRequest(), *expiration_time_ - Now()); +} + +TEST_F(NearbyShareExpirationSchedulerTest, Reschedule) { + scheduler()->Start(); + FastForward(absl::Minutes(5)); + + absl::Duration initial_expected_time_until_next_request = + *expiration_time_ - Now(); + EXPECT_EQ(scheduler()->GetTimeUntilNextRequest(), + initial_expected_time_until_next_request); + + // The expiration time suddenly changes. + expiration_time_ = *expiration_time_ + absl::Hours(48); + scheduler()->Reschedule(); + EXPECT_EQ(scheduler()->GetTimeUntilNextRequest(), + initial_expected_time_until_next_request + absl::Hours(48)); +} + +TEST_F(NearbyShareExpirationSchedulerTest, NullExpirationTime) { + expiration_time_.reset(); + scheduler()->Start(); + EXPECT_EQ(scheduler()->GetTimeUntilNextRequest(), std::nullopt); +} + +} // namespace +} // namespace sharing +} // namespace nearby diff --git a/sharing/scheduling/nearby_share_on_demand_scheduler.cc b/sharing/scheduling/nearby_share_on_demand_scheduler.cc new file mode 100644 index 00000000..bb17c93e --- /dev/null +++ b/sharing/scheduling/nearby_share_on_demand_scheduler.cc @@ -0,0 +1,47 @@ +// 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 "sharing/scheduling/nearby_share_on_demand_scheduler.h" + +#include +#include + +#include "absl/strings/string_view.h" +#include "absl/time/time.h" +#include "sharing/internal/api/preference_manager.h" +#include "sharing/internal/public/context.h" +#include "sharing/scheduling/nearby_share_scheduler.h" +#include "sharing/scheduling/nearby_share_scheduler_base.h" + +namespace nearby { +namespace sharing { +using ::nearby::sharing::api::PreferenceManager; + +NearbyShareOnDemandScheduler::NearbyShareOnDemandScheduler( + Context* context, PreferenceManager& preference_manager, + bool retry_failures, bool require_connectivity, absl::string_view pref_name, + OnRequestCallback callback) + : NearbyShareSchedulerBase(context, preference_manager, retry_failures, + require_connectivity, pref_name, + std::move(callback)) {} + +NearbyShareOnDemandScheduler::~NearbyShareOnDemandScheduler() = default; + +std::optional +NearbyShareOnDemandScheduler::TimeUntilRecurringRequest(absl::Time now) const { + return std::nullopt; +} + +} // namespace sharing +} // namespace nearby diff --git a/sharing/scheduling/nearby_share_on_demand_scheduler.h b/sharing/scheduling/nearby_share_on_demand_scheduler.h new file mode 100644 index 00000000..ee5a3645 --- /dev/null +++ b/sharing/scheduling/nearby_share_on_demand_scheduler.h @@ -0,0 +1,51 @@ +// 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 THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_ON_DEMAND_SCHEDULER_H_ +#define THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_ON_DEMAND_SCHEDULER_H_ + +#include + +#include "absl/strings/string_view.h" +#include "absl/time/time.h" +#include "sharing/internal/api/preference_manager.h" +#include "sharing/internal/public/context.h" +#include "sharing/scheduling/nearby_share_scheduler.h" +#include "sharing/scheduling/nearby_share_scheduler_base.h" + +namespace nearby { +namespace sharing { + +// A NearbyShareSchedulerBase that does not schedule recurring tasks. +class NearbyShareOnDemandScheduler : public NearbyShareSchedulerBase { + public: + // See NearbyShareSchedulerBase for a description of inputs. + NearbyShareOnDemandScheduler( + Context* context, + nearby::sharing::api::PreferenceManager& preference_manager, + bool retry_failures, bool require_connectivity, + absl::string_view pref_name, OnRequestCallback callback); + + ~NearbyShareOnDemandScheduler() override; + + private: + // Return absl::nullopt so as not to schedule recurring requests. + std::optional TimeUntilRecurringRequest( + absl::Time now) const override; +}; + +} // namespace sharing +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_ON_DEMAND_SCHEDULER_H_ diff --git a/sharing/scheduling/nearby_share_on_demand_scheduler_test.cc b/sharing/scheduling/nearby_share_on_demand_scheduler_test.cc new file mode 100644 index 00000000..93c0a21a --- /dev/null +++ b/sharing/scheduling/nearby_share_on_demand_scheduler_test.cc @@ -0,0 +1,59 @@ +// 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 "sharing/scheduling/nearby_share_on_demand_scheduler.h" + +#include + +#include "gtest/gtest.h" +#include "sharing/internal/test/fake_context.h" +#include "sharing/internal/test/fake_preference_manager.h" +#include "sharing/scheduling/nearby_share_scheduler.h" + +namespace nearby { +namespace sharing { +namespace { + +const char kTestPrefName[] = "test_pref_name"; + +class NearbyShareOnDemandSchedulerTest : public ::testing::Test { + protected: + NearbyShareOnDemandSchedulerTest() = default; + ~NearbyShareOnDemandSchedulerTest() override = default; + + void SetUp() override { + preference_manager_.Remove(kTestPrefName); + + scheduler_ = std::make_unique( + &fake_context_, preference_manager_, + /*retry_failures=*/true, /*require_connectivity=*/true, kTestPrefName, + nullptr); + } + + NearbyShareScheduler* scheduler() { return scheduler_.get(); } + + private: + nearby::FakePreferenceManager preference_manager_; + FakeContext fake_context_; + std::unique_ptr scheduler_; +}; + +TEST_F(NearbyShareOnDemandSchedulerTest, NoRecurringRequest) { + scheduler()->Start(); + EXPECT_FALSE(scheduler()->GetTimeUntilNextRequest()); +} + +} // namespace +} // namespace sharing +} // namespace nearby diff --git a/sharing/scheduling/nearby_share_periodic_scheduler.cc b/sharing/scheduling/nearby_share_periodic_scheduler.cc new file mode 100644 index 00000000..a32e229e --- /dev/null +++ b/sharing/scheduling/nearby_share_periodic_scheduler.cc @@ -0,0 +1,58 @@ +// 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 "sharing/scheduling/nearby_share_periodic_scheduler.h" + +#include +#include +#include + +#include "absl/strings/string_view.h" +#include "absl/time/time.h" +#include "sharing/internal/api/preference_manager.h" +#include "sharing/internal/public/context.h" +#include "sharing/scheduling/nearby_share_scheduler.h" +#include "sharing/scheduling/nearby_share_scheduler_base.h" + +namespace nearby { +namespace sharing { +using ::nearby::sharing::api::PreferenceManager; + +NearbySharePeriodicScheduler::NearbySharePeriodicScheduler( + Context* context, PreferenceManager& preference_manager, + absl::Duration request_period, bool retry_failures, + bool require_connectivity, absl::string_view pref_name, + OnRequestCallback callback) + : NearbyShareSchedulerBase(context, preference_manager, retry_failures, + require_connectivity, pref_name, + std::move(callback)), + request_period_(request_period) {} + +NearbySharePeriodicScheduler::~NearbySharePeriodicScheduler() = default; + +std::optional +NearbySharePeriodicScheduler::TimeUntilRecurringRequest(absl::Time now) const { + std::optional last_success_time = GetLastSuccessTime(); + + // Immediately run a first-time request. + if (!last_success_time.has_value()) return absl::ZeroDuration(); + + absl::Duration time_elapsed_since_last_success = now - *last_success_time; + + return std::max(absl::ZeroDuration(), + request_period_ - time_elapsed_since_last_success); +} + +} // namespace sharing +} // namespace nearby diff --git a/sharing/scheduling/nearby_share_periodic_scheduler.h b/sharing/scheduling/nearby_share_periodic_scheduler.h new file mode 100644 index 00000000..82d3b465 --- /dev/null +++ b/sharing/scheduling/nearby_share_periodic_scheduler.h @@ -0,0 +1,59 @@ +// 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 THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_PERIODIC_SCHEDULER_H_ +#define THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_PERIODIC_SCHEDULER_H_ + +#include + +#include "absl/strings/string_view.h" +#include "absl/time/time.h" +#include "sharing/internal/api/preference_manager.h" +#include "sharing/internal/public/context.h" +#include "sharing/scheduling/nearby_share_scheduler.h" +#include "sharing/scheduling/nearby_share_scheduler_base.h" + +namespace nearby { +namespace sharing { + +// A NearbyShareSchedulerBase that schedules periodic tasks at fixed intervals. +// Immediate requests and/or failure retries can interrupt this pattern. The +// periodic task is always updated to run a fixed delay after the last +// successful request. +class NearbySharePeriodicScheduler : public NearbyShareSchedulerBase { + public: + // |request_period|: The fixed delay between periodic requests. + // See NearbyShareSchedulerBase for a description of other inputs. + NearbySharePeriodicScheduler( + Context* context, + nearby::sharing::api::PreferenceManager& preference_manager, + absl::Duration request_period, bool retry_failures, + bool require_connectivity, absl::string_view pref_name, + OnRequestCallback callback); + + ~NearbySharePeriodicScheduler() override; + + private: + // Returns the time until the next periodic request using the time since + // the last success. Immediately runs a first-time periodic request. + std::optional TimeUntilRecurringRequest( + absl::Time now) const override; + + absl::Duration request_period_; +}; + +} // namespace sharing +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_PERIODIC_SCHEDULER_H_ diff --git a/sharing/scheduling/nearby_share_periodic_scheduler_test.cc b/sharing/scheduling/nearby_share_periodic_scheduler_test.cc new file mode 100644 index 00000000..58514b9d --- /dev/null +++ b/sharing/scheduling/nearby_share_periodic_scheduler_test.cc @@ -0,0 +1,86 @@ +// 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 "sharing/scheduling/nearby_share_periodic_scheduler.h" + +#include +#include + +#include "gtest/gtest.h" +#include "absl/time/time.h" +#include "internal/test/fake_clock.h" +#include "sharing/internal/test/fake_context.h" +#include "sharing/internal/test/fake_preference_manager.h" +#include "sharing/scheduling/nearby_share_scheduler.h" + +namespace nearby { +namespace sharing { +namespace { + +const char kTestPrefName[] = "test_pref_name"; +constexpr absl::Duration kTestRequestPeriod = absl::Minutes(123); + +class NearbySharePeriodicSchedulerTest : public ::testing::Test { + protected: + NearbySharePeriodicSchedulerTest() = default; + ~NearbySharePeriodicSchedulerTest() override = default; + + void SetUp() override { + preference_manager_.Remove(kTestPrefName); + + scheduler_ = std::make_unique( + &fake_context_, preference_manager_, kTestRequestPeriod, + /*retry_failures=*/true, + /*require_connectivity=*/true, kTestPrefName, nullptr); + } + + absl::Time Now() const { return fake_context_.GetClock()->Now(); } + + // Fast-forwards mock time by |delta| and fires relevant timers. + void FastForward(absl::Duration delta) { + fake_context_.fake_clock()->FastForward(delta); + } + + NearbyShareScheduler* scheduler() { return scheduler_.get(); } + + private: + nearby::FakePreferenceManager preference_manager_; + FakeContext fake_context_; + std::unique_ptr scheduler_; +}; + +TEST_F(NearbySharePeriodicSchedulerTest, PeriodicRequest) { + // Set Now() to something nontrivial. + FastForward(absl::Hours(2400)); + + // Immediately runs a first-time periodic request. + scheduler()->Start(); + std::optional time_until_next_request = + scheduler()->GetTimeUntilNextRequest(); + EXPECT_EQ(scheduler()->GetTimeUntilNextRequest(), absl::ZeroDuration()); + FastForward(*time_until_next_request); + scheduler()->HandleResult(/*success=*/true); + EXPECT_EQ(scheduler()->GetLastSuccessTime(), Now()); + + // Wait 1 minute since the last success. + absl::Duration elapsed_time = absl::Minutes(1); + FastForward(elapsed_time); + + EXPECT_EQ(scheduler()->GetTimeUntilNextRequest(), + kTestRequestPeriod - elapsed_time); +} + +} // namespace +} // namespace sharing +} // namespace nearby diff --git a/sharing/scheduling/nearby_share_scheduler.cc b/sharing/scheduling/nearby_share_scheduler.cc new file mode 100644 index 00000000..5932feef --- /dev/null +++ b/sharing/scheduling/nearby_share_scheduler.cc @@ -0,0 +1,45 @@ +// 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 "sharing/scheduling/nearby_share_scheduler.h" + +#include +#include + +namespace nearby { +namespace sharing { + +NearbyShareScheduler::NearbyShareScheduler(OnRequestCallback callback) + : callback_(std::move(callback)) {} + +NearbyShareScheduler::~NearbyShareScheduler() = default; + +void NearbyShareScheduler::Start() { + is_running_ = true; + OnStart(); +} + +void NearbyShareScheduler::Stop() { + is_running_ = false; + OnStop(); +} + +void NearbyShareScheduler::NotifyOfRequest() { + if (callback_ != nullptr) { + callback_(); + } +} + +} // namespace sharing +} // namespace nearby diff --git a/sharing/scheduling/nearby_share_scheduler.h b/sharing/scheduling/nearby_share_scheduler.h new file mode 100644 index 00000000..e86b6458 --- /dev/null +++ b/sharing/scheduling/nearby_share_scheduler.h @@ -0,0 +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 THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_SCHEDULER_H_ +#define THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_SCHEDULER_H_ + +#include + +#include +#include + +#include "absl/time/time.h" + +namespace nearby { +namespace sharing { + +// Schedules tasks and alerts the owner when a request is ready. Scheduling +// begins after Start() is called, and scheduling is stopped via Stop(). +// +// An immediate request can be made, bypassing any current scheduling, via +// MakeImmediateRequest(). When a request attempt has completed--successfully +// or not--the owner should invoke HandleResult() so the scheduler can process +// the attempt outcomes and schedule future attempts if necessary. +class NearbyShareScheduler { + public: + using OnRequestCallback = std::function; + + explicit NearbyShareScheduler(OnRequestCallback callback); + virtual ~NearbyShareScheduler(); + + void Start(); + void Stop(); + bool is_running() const { return is_running_; } + + // Make a request that runs as soon as possible. + virtual void MakeImmediateRequest() = 0; + + // Processes the result of the previous request. Method to be called by the + // owner when the request is finished. The timer for the next request is + // automatically scheduled. + virtual void HandleResult(bool success) = 0; + + // Recomputes the time until the next request, using GetTimeUntilNextRequest() + // as the source of truth. This method is essentially idempotent. NOTE: This + // method should rarely need to be called. + virtual void Reschedule() = 0; + + // Returns the time of the last known successful request. If no request has + // succeeded, absl::nullopt is returned. + virtual std::optional GetLastSuccessTime() const = 0; + + // Returns the time until the next scheduled request. Returns std::nullopt if + // there is no request scheduled. + virtual std::optional GetTimeUntilNextRequest() const = 0; + + // Returns true after the |callback_| has been alerted of a request but before + // HandleResult() is invoked. + virtual bool IsWaitingForResult() const = 0; + + // The number of times the current request type has failed. + // Once the request succeeds or a fresh request is made--for example, + // via a manual request--this counter is reset. + virtual size_t GetNumConsecutiveFailures() const = 0; + + protected: + virtual void OnStart() = 0; + virtual void OnStop() = 0; + + // Invokes |callback_|, alerting the owner that a request is ready. + void NotifyOfRequest(); + + private: + bool is_running_ = false; + OnRequestCallback callback_; +}; + +} // namespace sharing +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_SCHEDULER_H_ diff --git a/sharing/scheduling/nearby_share_scheduler_base.cc b/sharing/scheduling/nearby_share_scheduler_base.cc new file mode 100644 index 00000000..656dbf79 --- /dev/null +++ b/sharing/scheduling/nearby_share_scheduler_base.cc @@ -0,0 +1,340 @@ +// 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 "sharing/scheduling/nearby_share_scheduler_base.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "absl/strings/string_view.h" +#include "absl/strings/substitute.h" +#include "absl/time/time.h" +#include "sharing/internal/api/preference_manager.h" +#include "sharing/internal/public/connectivity_manager.h" +#include "sharing/internal/public/context.h" +#include "sharing/internal/public/logging.h" +#include "sharing/scheduling/format.h" +#include "sharing/scheduling/nearby_share_scheduler.h" +#include "sharing/scheduling/nearby_share_scheduler_fields.h" + +namespace nearby { +namespace sharing { +namespace { + +using ::nearby::sharing::api::PreferenceManager; + +constexpr absl::Duration kZeroTimeDelta = absl::ZeroDuration(); +constexpr absl::Duration kBaseRetryDelay = absl::Seconds(5); +constexpr absl::Duration kMaxRetryDelay = absl::Hours(1); + +} // namespace + +NearbyShareSchedulerBase::NearbyShareSchedulerBase( + Context* context, PreferenceManager& preference_manager, + bool retry_failures, bool require_connectivity, absl::string_view pref_name, + OnRequestCallback callback) + : NearbyShareScheduler(std::move(callback)), + connectivity_manager_(context->GetConnectivityManager()), + preference_manager_(preference_manager), + clock_(context->GetClock()), + retry_failures_(retry_failures), + require_connectivity_(require_connectivity), + pref_name_(pref_name) { + timer_ = context->CreateTimer(); + connection_listener_name_ = absl::Substitute( + "scheduler-$0-$1", pref_name_, absl::ToUnixNanos(absl::UnixEpoch())); + + InitializePersistedRequest(); + is_initialized_ = true; + + if (require_connectivity_) { + connectivity_manager_->RegisterConnectionListener( + connection_listener_name_, + [this](nearby::ConnectivityManager::ConnectionType connection_type, + bool is_lan_connected) { + OnConnectionChanged(connection_type); + }); + } +} + +NearbyShareSchedulerBase::~NearbyShareSchedulerBase() { + if (require_connectivity_) { + connectivity_manager_->UnregisterConnectionListener( + connection_listener_name_); + } +} + +void NearbyShareSchedulerBase::MakeImmediateRequest() { + timer_->Stop(); + SetHasPendingImmediateRequest(true); + Reschedule(); +} + +void NearbyShareSchedulerBase::HandleResult(bool success) { + absl::Time now = clock_->Now(); + SetLastAttemptTime(now); + + NL_LOG(INFO) << "Nearby Share scheduler \"" << pref_name_ + << "\" latest attempt " << (success ? "succeeded" : "failed"); + + if (success) { + SetLastSuccessTime(now); + SetNumConsecutiveFailures(0); + } else { + SetNumConsecutiveFailures(GetNumConsecutiveFailures() + 1); + } + + SetIsWaitingForResult(false); + Reschedule(); + PrintSchedulerState(); +} + +void NearbyShareSchedulerBase::Reschedule() { + if (!is_running()) return; + + timer_->Stop(); + + std::optional delay = GetTimeUntilNextRequest(); + if (!delay.has_value()) return; + + int64_t delay_milliseconds = (*delay) / absl::Milliseconds(1); + + timer_->Start(delay_milliseconds, delay_milliseconds, + [this]() { OnTimerFired(); }); +} + +std::optional NearbyShareSchedulerBase::GetLastSuccessTime() const { + std::optional pref_value = + preference_manager_.GetDictionaryInt64Value( + pref_name_, SchedulerFields::kLastSuccessTimeKeyName); + if (!pref_value.has_value()) { + return std::nullopt; + } + return absl::FromUnixNanos(pref_value.value()); +} + +std::optional +NearbyShareSchedulerBase::GetTimeUntilNextRequest() const { + if (!is_running() || IsWaitingForResult()) return std::nullopt; + + if (HasPendingImmediateRequest()) return kZeroTimeDelta; + + absl::Time now = clock_->Now(); + + // Recover from failures using exponential backoff strategy if necessary. + std::optional time_until_retry = TimeUntilRetry(now); + if (time_until_retry) return time_until_retry; + + // Schedule the periodic request if applicable. + return TimeUntilRecurringRequest(now); +} + +bool NearbyShareSchedulerBase::IsWaitingForResult() const { + std::optional pref_value = + preference_manager_.GetDictionaryBooleanValue( + pref_name_, SchedulerFields::kIsWaitingForResultKeyName); + + bool is_waiting = false; + if (pref_value.has_value()) { + is_waiting = pref_value.value(); + } + + if (is_waiting) { + return true; + } + + // The scheduler must be initialized if it is not initialized or has failed. + // This will speed up the data sync when there are issues. + if (!is_initialized_) { + if (GetNumConsecutiveFailures() > 0) { + NL_LOG(WARNING) << ": Run the scheduler " << pref_name_ + << " immediately due to having failed runs."; + return true; + } + } + + return false; +} + +size_t NearbyShareSchedulerBase::GetNumConsecutiveFailures() const { + std::optional pref_value = + preference_manager_.GetDictionaryInt64Value( + pref_name_, SchedulerFields::kNumConsecutiveFailuresKeyName); + + if (!pref_value.has_value()) { + return 0; + } + return pref_value.value(); +} + +void NearbyShareSchedulerBase::OnStart() { + Reschedule(); + NL_LOG(INFO) << "Starting Nearby Share scheduler \"" << pref_name_ << "\""; + PrintSchedulerState(); +} + +void NearbyShareSchedulerBase::OnStop() { timer_->Stop(); } + +void NearbyShareSchedulerBase::OnConnectionChanged( + nearby::ConnectivityManager::ConnectionType connection_type) { + if (connection_type == nearby::ConnectivityManager::ConnectionType::kNone) + return; + + Reschedule(); +} + +std::optional NearbyShareSchedulerBase::GetLastAttemptTime() const { + std::optional pref_value = + preference_manager_.GetDictionaryInt64Value( + pref_name_, SchedulerFields::kLastAttemptTimeKeyName); + if (!pref_value.has_value()) { + return std::nullopt; + } + return absl::FromUnixNanos(pref_value.value()); +} + +bool NearbyShareSchedulerBase::HasPendingImmediateRequest() const { + std::optional pref_value = + preference_manager_.GetDictionaryBooleanValue( + pref_name_, SchedulerFields::kHasPendingImmediateRequestKeyName); + if (!pref_value.has_value()) { + return false; + } + return pref_value.value(); +} + +void NearbyShareSchedulerBase::SetLastAttemptTime( + absl::Time last_attempt_time) { + preference_manager_.SetDictionaryInt64Value( + pref_name_, SchedulerFields::kLastAttemptTimeKeyName, + absl::ToUnixNanos(last_attempt_time)); +} + +void NearbyShareSchedulerBase::SetLastSuccessTime( + absl::Time last_success_time) { + preference_manager_.SetDictionaryInt64Value( + pref_name_, SchedulerFields::kLastSuccessTimeKeyName, + absl::ToUnixNanos(last_success_time)); +} + +void NearbyShareSchedulerBase::SetNumConsecutiveFailures(size_t num_failures) { + preference_manager_.SetDictionaryInt64Value( + pref_name_, SchedulerFields::kNumConsecutiveFailuresKeyName, + num_failures); +} + +void NearbyShareSchedulerBase::SetHasPendingImmediateRequest( + bool has_pending_immediate_request) { + preference_manager_.SetDictionaryBooleanValue( + pref_name_, SchedulerFields::kHasPendingImmediateRequestKeyName, + has_pending_immediate_request); +} + +void NearbyShareSchedulerBase::SetIsWaitingForResult( + bool is_waiting_for_result) { + preference_manager_.SetDictionaryBooleanValue( + pref_name_, SchedulerFields::kIsWaitingForResultKeyName, + is_waiting_for_result); +} + +void NearbyShareSchedulerBase::InitializePersistedRequest() { + if (IsWaitingForResult()) { + SetHasPendingImmediateRequest(true); + SetIsWaitingForResult(false); + } +} + +std::optional NearbyShareSchedulerBase::TimeUntilRetry( + absl::Time now) const { + if (!retry_failures_) return std::nullopt; + + size_t num_failures = GetNumConsecutiveFailures(); + if (num_failures == 0) return std::nullopt; + + // The exponential back off is + // + // base * 2^(num_failures - 1) + // + // up to a fixed maximum retry delay. + absl::Duration delay = + std::min(kMaxRetryDelay, kBaseRetryDelay * (1 << (num_failures - 1))); + + absl::Duration time_elapsed_since_last_attempt = now - *GetLastAttemptTime(); + + return std::max(kZeroTimeDelta, delay - time_elapsed_since_last_attempt); +} + +void NearbyShareSchedulerBase::OnTimerFired() { + NL_DCHECK(is_running()); + if (require_connectivity_ && + (connectivity_manager_->GetConnectionType() == + nearby::ConnectivityManager::ConnectionType::kNone)) { + return; + } + + SetIsWaitingForResult(true); + SetHasPendingImmediateRequest(false); + NotifyOfRequest(); +} + +void NearbyShareSchedulerBase::PrintSchedulerState() const { + std::optional last_attempt_time = GetLastAttemptTime(); + std::optional last_success_time = GetLastSuccessTime(); + std::optional time_until_next_request = + GetTimeUntilNextRequest(); + + std::stringstream ss; + ss << "State of Nearby Share scheduler \"" << pref_name_ << "\":" + << "\n Last attempt time: "; + if (last_attempt_time) { + ss << nearby::utils::TimeFormatShortDateAndTimeWithTimeZone( + *last_attempt_time); + } else { + ss << "Never"; + } + + ss << "\n Last success time: "; + if (last_success_time) { + ss << nearby::utils::TimeFormatShortDateAndTimeWithTimeZone( + *last_success_time); + } else { + ss << "Never"; + } + + ss << "\n Time until next request: "; + if (time_until_next_request) { + std::u16string next_request_delay; + ss << nearby::utils::TimeDurationFormatWithSeconds( + *time_until_next_request); + } else { + ss << "Never"; + } + + ss << "\n Is waiting for result? " << (IsWaitingForResult() ? "Yes" : "No"); + ss << "\n Pending immediate request? " + << (HasPendingImmediateRequest() ? "Yes" : "No"); + ss << "\n Num consecutive failures: " << GetNumConsecutiveFailures(); + + NL_VLOG(1) << ss.str(); +} + +} // namespace sharing +} // namespace nearby diff --git a/sharing/scheduling/nearby_share_scheduler_base.h b/sharing/scheduling/nearby_share_scheduler_base.h new file mode 100644 index 00000000..21e57312 --- /dev/null +++ b/sharing/scheduling/nearby_share_scheduler_base.h @@ -0,0 +1,130 @@ +// 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 THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_SCHEDULER_BASE_H_ +#define THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_SCHEDULER_BASE_H_ + +#include + +#include +#include +#include + +#include "absl/strings/string_view.h" +#include "absl/time/time.h" +#include "sharing/internal/api/preference_manager.h" +#include "sharing/internal/public/connectivity_manager.h" +#include "sharing/internal/public/context.h" +#include "sharing/scheduling/nearby_share_scheduler.h" + +namespace nearby { +namespace sharing { + +// A base NearbyShareScheduler implementation that persists scheduling data. +// Requests made before scheduling has started, while another attempt is in +// progress, or while offline are cached and rescheduled as soon as possible. +// Likewise, when the scheduler is stopped or destroyed, scheduling data is +// persisted and restored when the scheduler is restarted or recreated, +// respectively. +// +// If automatic failure retry is enabled, all failed attempts follow an +// exponential backoff retry strategy. +// +// The scheduler waits until the device is online before notifying the owner if +// network connectivity is required. +// +// Derived classes must override TimeUntilRecurringRequest() to establish the +// desired recurring request behavior of the scheduler. +class NearbyShareSchedulerBase : public NearbyShareScheduler { + public: + ~NearbyShareSchedulerBase() override; + + protected: + // |context|: Nearby context, holding nearby common components. + // |retry_failures|: Whether or not automatically retry failures using + // exponential backoff strategy. + // |require_connectivity|: If true, the scheduler will not alert the owner of + // a request until network connectivity is established. + // |pref_name|: The dictionary pref name used to persist scheduling data. Make + // sure to register this pref name before creating the scheduler. + // |callback|: The function invoked to alert the owner that a request is due. + NearbyShareSchedulerBase( + Context* context, + nearby::sharing::api::PreferenceManager& preference_manager, + bool retry_failures, bool require_connectivity, + absl::string_view pref_name, OnRequestCallback callback); + + // The time to wait until the next regularly recurring request. + virtual std::optional TimeUntilRecurringRequest( + absl::Time now) const = 0; + + // NearbyShareScheduler: + void MakeImmediateRequest() override; + void HandleResult(bool success) override; + void Reschedule() override; + std::optional GetLastSuccessTime() const override; + std::optional GetTimeUntilNextRequest() const override; + bool IsWaitingForResult() const override; + size_t GetNumConsecutiveFailures() const override; + void OnStart() override; + void OnStop() override; + + void OnConnectionChanged( + nearby::ConnectivityManager::ConnectionType connection_type); + + std::optional GetLastAttemptTime() const; + bool HasPendingImmediateRequest() const; + + // Set and persist scheduling data in prefs. + void SetLastAttemptTime(absl::Time last_attempt_time); + void SetLastSuccessTime(absl::Time last_success_time); + void SetNumConsecutiveFailures(size_t num_failures); + void SetHasPendingImmediateRequest(bool has_pending_immediate_request); + void SetIsWaitingForResult(bool is_waiting_for_result); + + // On startup, set a pending immediate request if the pref service indicates + // that there was an in-progress request or a pending immediate request at the + // time of shutdown. + void InitializePersistedRequest(); + + // The amount of time to wait until the next automatic failure retry. Returns + // std::nullopt if there is no failure to retry or if failure retry is not + // enabled for the scheduler. + std::optional TimeUntilRetry(absl::Time now) const; + + // Notifies the owner that a request is ready. Early returns if not online and + // the scheduler requires connectivity; the attempt is rescheduled when + // connectivity is restored. + void OnTimerFired(); + + void PrintSchedulerState() const; + + private: + nearby::ConnectivityManager* const connectivity_manager_; + nearby::sharing::api::PreferenceManager& preference_manager_; + const nearby::Clock* const clock_; + + const bool retry_failures_; + const bool require_connectivity_; + const std::string pref_name_; + bool is_initialized_ = false; + std::string connection_listener_name_; + + std::unique_ptr timer_; +}; + +} // namespace sharing +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_SCHEDULER_BASE_H_ diff --git a/sharing/scheduling/nearby_share_scheduler_base_test.cc b/sharing/scheduling/nearby_share_scheduler_base_test.cc new file mode 100644 index 00000000..c5f50cfb --- /dev/null +++ b/sharing/scheduling/nearby_share_scheduler_base_test.cc @@ -0,0 +1,409 @@ +// 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 "sharing/scheduling/nearby_share_scheduler_base.h" + +#include + +#include +#include +#include +#include + +#include "gtest/gtest.h" +#include "absl/strings/string_view.h" +#include "absl/time/time.h" +#include "internal/test/fake_clock.h" +#include "sharing/internal/test/fake_context.h" +#include "sharing/internal/test/fake_preference_manager.h" +#include "sharing/scheduling/nearby_share_scheduler.h" + +namespace nearby { +namespace sharing { +namespace { + +using ::nearby::sharing::api::PreferenceManager; + +const char kTestPrefName[] = "test_pref_name"; + +constexpr absl::Duration kZeroTimeDuration = absl::ZeroDuration(); +constexpr absl::Duration kBaseRetryDuration = absl::Seconds(5); +constexpr absl::Duration kMaxRetryDuration = absl::Hours(1); + +constexpr absl::Duration kTestTimeUntilRecurringRequest = absl::Minutes(120); + +class NearbyShareSchedulerBaseForTest : public NearbyShareSchedulerBase { + public: + NearbyShareSchedulerBaseForTest( + Context* context, + PreferenceManager& preference_manager, + std::optional time_until_recurring_request, + bool retry_failures, bool require_connectivity, + absl::string_view pref_name, OnRequestCallback callback) + : NearbyShareSchedulerBase(context, preference_manager, retry_failures, + require_connectivity, pref_name, + std::move(callback)), + time_until_recurring_request_(time_until_recurring_request) {} + + ~NearbyShareSchedulerBaseForTest() override = default; + + private: + std::optional TimeUntilRecurringRequest( + absl::Time now) const override { + return time_until_recurring_request_; + } + + std::optional time_until_recurring_request_; +}; + +class NearbyShareSchedulerBaseTest : public ::testing::Test { + protected: + NearbyShareSchedulerBaseTest() = default; + + ~NearbyShareSchedulerBaseTest() override = default; + + void SetUp() override { + preference_manager_.Remove(kTestPrefName); + } + + void CreateScheduler( + bool retry_failures, bool require_connectivity, + std::optional time_until_recurring_request = + kTestTimeUntilRecurringRequest) { + scheduler_ = std::make_unique( + &fake_context_, preference_manager_, time_until_recurring_request, + retry_failures, require_connectivity, kTestPrefName, callback_); + } + + void DestroyScheduler() { scheduler_.reset(); } + + void StartScheduling() { + scheduler_->Start(); + EXPECT_TRUE(scheduler_->is_running()); + } + + void StopScheduling() { + scheduler_->Stop(); + EXPECT_FALSE(scheduler_->is_running()); + } + + // Fast-forwards mock time by |delta| and fires relevant timers. + void FastForward(absl::Duration delta) { + fake_context_.fake_clock()->FastForward(delta); + } + + void RunPendingRequest() { + EXPECT_FALSE(scheduler_->IsWaitingForResult()); + std::optional time_until_next_request = + scheduler_->GetTimeUntilNextRequest(); + ASSERT_TRUE(time_until_next_request); + FastForward(*time_until_next_request); + } + + void FinishPendingRequest(bool success) { + EXPECT_TRUE(scheduler_->IsWaitingForResult()); + EXPECT_FALSE(scheduler_->GetTimeUntilNextRequest().has_value()); + size_t num_failures = scheduler_->GetNumConsecutiveFailures(); + std::optional last_success_time = + scheduler_->GetLastSuccessTime(); + scheduler_->HandleResult(success); + EXPECT_FALSE(scheduler_->IsWaitingForResult()); + EXPECT_EQ(scheduler_->GetNumConsecutiveFailures(), + success ? 0 : num_failures + 1); + EXPECT_EQ( + scheduler_->GetLastSuccessTime(), + success ? std::make_optional(Now()) : last_success_time); + } + + absl::Time Now() const { + return fake_context_.GetClock()->Now(); + } + + size_t on_request_call_count() const { return on_request_call_count_; } + NearbyShareScheduler* scheduler() { return scheduler_.get(); } + + private: + nearby::FakePreferenceManager preference_manager_; + nearby::FakeContext fake_context_; + size_t on_request_call_count_ = 0; + std::unique_ptr scheduler_; + NearbyShareScheduler::OnRequestCallback callback_ = [&]() { + ++on_request_call_count_; + }; +}; + +TEST_F(NearbyShareSchedulerBaseTest, ImmediateRequest) { + CreateScheduler(/*retry_failures=*/true, /*require_connectivity=*/true); + StartScheduling(); + scheduler()->MakeImmediateRequest(); + EXPECT_EQ(scheduler()->GetTimeUntilNextRequest(), kZeroTimeDuration); + ASSERT_NO_FATAL_FAILURE(RunPendingRequest()); + EXPECT_EQ(on_request_call_count(), 1u); + FinishPendingRequest(/*success=*/true); +} + +TEST_F(NearbyShareSchedulerBaseTest, RecurringRequest) { + CreateScheduler(/*retry_failures=*/true, /*require_connectivity=*/true); + StartScheduling(); + EXPECT_EQ(scheduler()->GetTimeUntilNextRequest(), + kTestTimeUntilRecurringRequest); + + ASSERT_NO_FATAL_FAILURE(RunPendingRequest()); + FinishPendingRequest(/*success=*/true); + EXPECT_EQ(scheduler()->GetTimeUntilNextRequest(), + kTestTimeUntilRecurringRequest); +} + +TEST_F(NearbyShareSchedulerBaseTest, NoRecurringRequest) { + // The flavor of the schedule does not schedule recurring requests. + CreateScheduler(/*retry_failures=*/true, /*require_connectivity=*/true, + /*time_until_recurring_request=*/std::nullopt); + StartScheduling(); + EXPECT_FALSE(scheduler()->GetTimeUntilNextRequest()); + + scheduler()->MakeImmediateRequest(); + ASSERT_NO_FATAL_FAILURE(RunPendingRequest()); + FinishPendingRequest(/*success=*/true); + + EXPECT_FALSE(scheduler()->GetTimeUntilNextRequest()); +} + +TEST_F(NearbyShareSchedulerBaseTest, SchedulingNotStarted) { + CreateScheduler(/*retry_failures=*/true, /*require_connectivity=*/true); + EXPECT_FALSE(scheduler()->is_running()); + EXPECT_FALSE(scheduler()->GetTimeUntilNextRequest()); + EXPECT_FALSE(scheduler()->IsWaitingForResult()); + + // Request remains pending until scheduling starts. + scheduler()->MakeImmediateRequest(); + EXPECT_FALSE(scheduler()->is_running()); + EXPECT_FALSE(scheduler()->GetTimeUntilNextRequest()); + EXPECT_FALSE(scheduler()->IsWaitingForResult()); + StartScheduling(); + EXPECT_EQ(scheduler()->GetTimeUntilNextRequest(), kZeroTimeDuration); + EXPECT_FALSE(scheduler()->IsWaitingForResult()); +} + +TEST_F(NearbyShareSchedulerBaseTest, DoNotRetryFailures) { + CreateScheduler(/*retry_failures=*/false, /*require_connectivity=*/true); + StartScheduling(); + + // Run recurring request. + ASSERT_NO_FATAL_FAILURE(RunPendingRequest()); + EXPECT_EQ(on_request_call_count(), 1u); + FinishPendingRequest(/*success=*/false); + EXPECT_EQ(scheduler()->GetNumConsecutiveFailures(), 1u); + + // Failure is not automatically retried; the recurring request is re-scheduled + // instead. + EXPECT_EQ(kTestTimeUntilRecurringRequest, + scheduler()->GetTimeUntilNextRequest()); + + ASSERT_NO_FATAL_FAILURE(RunPendingRequest()); + EXPECT_EQ(on_request_call_count(), 2u); + FinishPendingRequest(/*success=*/false); + EXPECT_EQ(scheduler()->GetNumConsecutiveFailures(), 2u); +} + +TEST_F(NearbyShareSchedulerBaseTest, FailureRetry) { + CreateScheduler(/*retry_failures=*/true, /*require_connectivity=*/true); + StartScheduling(); + scheduler()->MakeImmediateRequest(); + + size_t num_failures = 0; + size_t expected_backoff_factor = 1; + do { + EXPECT_EQ(scheduler()->GetNumConsecutiveFailures(), num_failures); + ASSERT_NO_FATAL_FAILURE(RunPendingRequest()); + EXPECT_EQ(on_request_call_count(), num_failures + 1); + FinishPendingRequest(/*success=*/false); + EXPECT_EQ(scheduler()->GetTimeUntilNextRequest(), + std::min(kMaxRetryDuration, + kBaseRetryDuration * expected_backoff_factor)); + expected_backoff_factor *= 2; + ++num_failures; + } while (*scheduler()->GetTimeUntilNextRequest() != kMaxRetryDuration); + + ASSERT_NO_FATAL_FAILURE(RunPendingRequest()); + EXPECT_EQ(on_request_call_count(), num_failures + 1); + FinishPendingRequest(/*success=*/true); +} + +TEST_F(NearbyShareSchedulerBaseTest, + FailureRetry_InterruptWithImmediateAttempt) { + CreateScheduler(/*retry_failures=*/true, /*require_connectivity=*/true); + StartScheduling(); + scheduler()->MakeImmediateRequest(); + + size_t num_failures = 0; + size_t expected_backoff_factor = 1; + do { + EXPECT_EQ(scheduler()->GetNumConsecutiveFailures(), num_failures); + ASSERT_NO_FATAL_FAILURE(RunPendingRequest()); + EXPECT_EQ(on_request_call_count(), num_failures + 1); + FinishPendingRequest(/*success=*/false); + EXPECT_EQ(std::min(kMaxRetryDuration, + kBaseRetryDuration * expected_backoff_factor), + scheduler()->GetTimeUntilNextRequest()); + expected_backoff_factor *= 2; + ++num_failures; + } while (num_failures < 3); + + // Interrupt retry schedule with immediate request. On failure, it continues + // the retry strategy using the next backoff. + EXPECT_EQ(scheduler()->GetNumConsecutiveFailures(), num_failures); + scheduler()->MakeImmediateRequest(); + EXPECT_EQ(scheduler()->GetTimeUntilNextRequest(), kZeroTimeDuration); + ASSERT_NO_FATAL_FAILURE(RunPendingRequest()); + EXPECT_EQ(on_request_call_count(), num_failures + 1); + FinishPendingRequest(/*success=*/false); + EXPECT_EQ(scheduler()->GetTimeUntilNextRequest(), + std::min(kMaxRetryDuration, + kBaseRetryDuration * expected_backoff_factor)); + EXPECT_EQ(scheduler()->GetNumConsecutiveFailures(), num_failures + 1); +} + +TEST_F(NearbyShareSchedulerBaseTest, StopScheduling_BeforeTimerFires) { + CreateScheduler(/*retry_failures=*/true, /*require_connectivity=*/true); + scheduler()->MakeImmediateRequest(); + + StartScheduling(); + EXPECT_EQ(scheduler()->GetTimeUntilNextRequest(), kZeroTimeDuration); + + StopScheduling(); + EXPECT_FALSE(scheduler()->GetTimeUntilNextRequest()); + + // Timer is still fired but owner is not notified. + FastForward(kZeroTimeDuration); + EXPECT_FALSE(scheduler()->IsWaitingForResult()); + EXPECT_FALSE(scheduler()->GetTimeUntilNextRequest()); + + // Scheduling restarts and pending task is rescheduled. + StartScheduling(); + ASSERT_NO_FATAL_FAILURE(RunPendingRequest()); + EXPECT_EQ(on_request_call_count(), 1u); + FinishPendingRequest(/*success=*/true); +} + +TEST_F(NearbyShareSchedulerBaseTest, StopScheduling_BeforeResultIsHandled) { + CreateScheduler(/*retry_failures=*/true, /*require_connectivity=*/true); + scheduler()->MakeImmediateRequest(); + + StartScheduling(); + ASSERT_NO_FATAL_FAILURE(RunPendingRequest()); + EXPECT_EQ(on_request_call_count(), 1u); + + StopScheduling(); + EXPECT_TRUE(scheduler()->IsWaitingForResult()); + + // Although scheduling is stopped, the result can still be handled. No further + // requests will be scheduled though. + FinishPendingRequest(/*success=*/true); + EXPECT_FALSE(scheduler()->GetTimeUntilNextRequest()); +} + +TEST_F(NearbyShareSchedulerBaseTest, RestoreRequest_InProgress) { + CreateScheduler(/*retry_failures=*/true, /*require_connectivity=*/true); + scheduler()->MakeImmediateRequest(); + StartScheduling(); + ASSERT_NO_FATAL_FAILURE(RunPendingRequest()); + EXPECT_EQ(on_request_call_count(), 1u); + EXPECT_TRUE(scheduler()->IsWaitingForResult()); + DestroyScheduler(); + + // On startup, set a pending immediate request because there was an + // in-progress request at the time of shutdown. + CreateScheduler(/*retry_failures=*/true, /*require_connectivity=*/true); + StartScheduling(); + EXPECT_EQ(scheduler()->GetTimeUntilNextRequest(), kZeroTimeDuration); + EXPECT_FALSE(scheduler()->IsWaitingForResult()); + ASSERT_NO_FATAL_FAILURE(RunPendingRequest()); + EXPECT_EQ(on_request_call_count(), 2u); + FinishPendingRequest(/*success=*/true); +} + +TEST_F(NearbyShareSchedulerBaseTest, RestoreRequest_Pending_Immediate) { + CreateScheduler(/*retry_failures=*/true, /*require_connectivity=*/true); + scheduler()->MakeImmediateRequest(); + StartScheduling(); + EXPECT_EQ(scheduler()->GetTimeUntilNextRequest(), kZeroTimeDuration); + DestroyScheduler(); + + // On startup, set a pending immediate request because there was a pending + // immediate request at the time of shutdown. + CreateScheduler(/*retry_failures=*/true, /*require_connectivity=*/true); + StartScheduling(); + EXPECT_EQ(scheduler()->GetTimeUntilNextRequest(), kZeroTimeDuration); + EXPECT_FALSE(scheduler()->IsWaitingForResult()); + ASSERT_NO_FATAL_FAILURE(RunPendingRequest()); + EXPECT_EQ(on_request_call_count(), 1u); + FinishPendingRequest(/*success=*/true); +} + +TEST_F(NearbyShareSchedulerBaseTest, RestoreRequest_Pending_FailureRetry) { + CreateScheduler(/*retry_failures=*/true, /*require_connectivity=*/true); + scheduler()->MakeImmediateRequest(); + StartScheduling(); + + // Fail three times then destroy scheduler. + for (size_t num_failures = 0; num_failures < 3; ++num_failures) { + ASSERT_NO_FATAL_FAILURE(RunPendingRequest()); + EXPECT_EQ(on_request_call_count(), num_failures + 1); + FinishPendingRequest(/*success=*/false); + } + absl::Duration initial_time_until_next_request = + *scheduler()->GetTimeUntilNextRequest(); + EXPECT_EQ(initial_time_until_next_request, 4 * kBaseRetryDuration); + DestroyScheduler(); + + // 1s elapses while there is no scheduler. When the scheduler is recreated, + // the retry request is rescheduled, accounting for the elapsed time. + absl::Duration elapsed_time = absl::Seconds(1); + FastForward(elapsed_time); + CreateScheduler(/*retry_failures=*/true, /*require_connectivity=*/true); + StartScheduling(); + EXPECT_FALSE(scheduler()->IsWaitingForResult()); + EXPECT_EQ(scheduler()->GetTimeUntilNextRequest(), absl::Seconds(0)); + EXPECT_EQ(scheduler()->GetNumConsecutiveFailures(), 3u); + ASSERT_NO_FATAL_FAILURE(RunPendingRequest()); + EXPECT_EQ(on_request_call_count(), 4u); + FinishPendingRequest(/*success=*/true); +} + +TEST_F(NearbyShareSchedulerBaseTest, RestoreSchedulingData) { + // Succeed immediately, then fail once before destroying the scheduler. + absl::Time expected_last_success_time = Now() + absl::Seconds(100); + FastForward(expected_last_success_time - Now()); + CreateScheduler(/*retry_failures=*/true, /*require_connectivity=*/true); + scheduler()->MakeImmediateRequest(); + StartScheduling(); + ASSERT_NO_FATAL_FAILURE(RunPendingRequest()); + EXPECT_EQ(on_request_call_count(), 1u); + FinishPendingRequest(/*success=*/true); + scheduler()->MakeImmediateRequest(); + ASSERT_NO_FATAL_FAILURE(RunPendingRequest()); + EXPECT_EQ(on_request_call_count(), 2u); + FinishPendingRequest(/*success=*/false); + DestroyScheduler(); + + CreateScheduler(/*retry_failures=*/true, /*require_connectivity=*/true); + StartScheduling(); + EXPECT_EQ(scheduler()->GetLastSuccessTime(), expected_last_success_time); + EXPECT_EQ(scheduler()->GetTimeUntilNextRequest(), absl::Seconds(0)); + EXPECT_EQ(scheduler()->GetNumConsecutiveFailures(), 1u); +} + +} // namespace +} // namespace sharing +} // namespace nearby diff --git a/sharing/scheduling/nearby_share_scheduler_factory.cc b/sharing/scheduling/nearby_share_scheduler_factory.cc new file mode 100644 index 00000000..4d1bc576 --- /dev/null +++ b/sharing/scheduling/nearby_share_scheduler_factory.cc @@ -0,0 +1,102 @@ +// 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 "sharing/scheduling/nearby_share_scheduler_factory.h" + +#include +#include + +#include "absl/strings/string_view.h" +#include "absl/time/time.h" +#include "sharing/internal/api/preference_manager.h" +#include "sharing/internal/public/context.h" +#include "sharing/scheduling/nearby_share_expiration_scheduler.h" +#include "sharing/scheduling/nearby_share_on_demand_scheduler.h" +#include "sharing/scheduling/nearby_share_periodic_scheduler.h" +#include "sharing/scheduling/nearby_share_scheduler.h" + +namespace nearby { +namespace sharing { +using ::nearby::sharing::api::PreferenceManager; + +// static +NearbyShareSchedulerFactory* NearbyShareSchedulerFactory::test_factory_ = + nullptr; + +// static +std::unique_ptr +NearbyShareSchedulerFactory::CreateExpirationScheduler( + Context* context, PreferenceManager& preference_manager, + NearbyShareExpirationScheduler::ExpirationTimeFunctor + expiration_time_functor, + bool retry_failures, bool require_connectivity, absl::string_view pref_name, + NearbyShareScheduler::OnRequestCallback on_request_callback) { + if (test_factory_) { + return test_factory_->CreateExpirationSchedulerInstance( + context, preference_manager, std::move(expiration_time_functor), + retry_failures, require_connectivity, pref_name, + std::move(on_request_callback)); + } + + return std::make_unique( + context, preference_manager, std::move(expiration_time_functor), + retry_failures, require_connectivity, pref_name, + std::move(on_request_callback)); +} + +// static +std::unique_ptr +NearbyShareSchedulerFactory::CreateOnDemandScheduler( + Context* context, PreferenceManager& preference_manager, + bool retry_failures, bool require_connectivity, absl::string_view pref_name, + NearbyShareScheduler::OnRequestCallback callback) { + if (test_factory_) { + return test_factory_->CreateOnDemandSchedulerInstance( + context, preference_manager, retry_failures, require_connectivity, + pref_name, std::move(callback)); + } + + return std::make_unique( + context, preference_manager, retry_failures, require_connectivity, + pref_name, std::move(callback)); +} + +// static +std::unique_ptr +NearbyShareSchedulerFactory::CreatePeriodicScheduler( + Context* context, PreferenceManager& preference_manager, + absl::Duration request_period, bool retry_failures, + bool require_connectivity, absl::string_view pref_name, + NearbyShareScheduler::OnRequestCallback callback) { + if (test_factory_) { + return test_factory_->CreatePeriodicSchedulerInstance( + context, preference_manager, request_period, retry_failures, + require_connectivity, pref_name, std::move(callback)); + } + + return std::make_unique( + context, preference_manager, request_period, retry_failures, + require_connectivity, pref_name, std::move(callback)); +} + +// static +void NearbyShareSchedulerFactory::SetFactoryForTesting( + NearbyShareSchedulerFactory* test_factory) { + test_factory_ = test_factory; +} + +NearbyShareSchedulerFactory::~NearbyShareSchedulerFactory() = default; + +} // namespace sharing +} // namespace nearby diff --git a/sharing/scheduling/nearby_share_scheduler_factory.h b/sharing/scheduling/nearby_share_scheduler_factory.h new file mode 100644 index 00000000..bff24d36 --- /dev/null +++ b/sharing/scheduling/nearby_share_scheduler_factory.h @@ -0,0 +1,96 @@ +// 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 THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_SCHEDULER_FACTORY_H_ +#define THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_SCHEDULER_FACTORY_H_ + +#include + +#include "absl/strings/string_view.h" +#include "absl/time/time.h" +#include "sharing/internal/api/preference_manager.h" +#include "sharing/internal/public/context.h" +#include "sharing/scheduling/nearby_share_expiration_scheduler.h" +#include "sharing/scheduling/nearby_share_scheduler.h" + +namespace nearby { +namespace sharing { + +// class PrefService; + +// Used to create instances of NearbyShareExpirationScheduler, +// NearbyShareOnDemandScheduler, and NearbySharePeriodicScheduler. A fake +// factory can also be set for testing purposes. +class NearbyShareSchedulerFactory { + public: + static std::unique_ptr CreateExpirationScheduler( + Context* context, + nearby::sharing::api::PreferenceManager& preference_manager, + NearbyShareExpirationScheduler::ExpirationTimeFunctor + expiration_time_functor, + bool retry_failures, bool require_connectivity, + absl::string_view pref_name, + NearbyShareScheduler::OnRequestCallback on_request_callback); + + static std::unique_ptr CreateOnDemandScheduler( + Context* context, + nearby::sharing::api::PreferenceManager& preference_manager, + bool retry_failures, bool require_connectivity, + absl::string_view pref_name, + NearbyShareScheduler::OnRequestCallback callback); + + static std::unique_ptr CreatePeriodicScheduler( + Context* context, + nearby::sharing::api::PreferenceManager& preference_manager, + absl::Duration request_period, bool retry_failures, + bool require_connectivity, absl::string_view pref_name, + NearbyShareScheduler::OnRequestCallback callback); + + static void SetFactoryForTesting(NearbyShareSchedulerFactory* test_factory); + + protected: + virtual ~NearbyShareSchedulerFactory(); + + virtual std::unique_ptr + CreateExpirationSchedulerInstance( + Context* context, + nearby::sharing::api::PreferenceManager& preference_manager, + NearbyShareExpirationScheduler::ExpirationTimeFunctor + expiration_time_functor, + bool retry_failures, bool require_connectivity, + absl::string_view pref_name, + NearbyShareScheduler::OnRequestCallback on_request_callback) = 0; + + virtual std::unique_ptr CreateOnDemandSchedulerInstance( + Context* context, + nearby::sharing::api::PreferenceManager& preference_manager, + bool retry_failures, bool require_connectivity, + absl::string_view pref_name, + NearbyShareScheduler::OnRequestCallback callback) = 0; + + virtual std::unique_ptr CreatePeriodicSchedulerInstance( + Context* context, + nearby::sharing::api::PreferenceManager& preference_manager, + absl::Duration request_period, bool retry_failures, + bool require_connectivity, absl::string_view pref_name, + NearbyShareScheduler::OnRequestCallback callback) = 0; + + private: + static NearbyShareSchedulerFactory* test_factory_; +}; + +} // namespace sharing +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_SCHEDULER_FACTORY_H_ diff --git a/sharing/scheduling/nearby_share_scheduler_fields.h b/sharing/scheduling/nearby_share_scheduler_fields.h new file mode 100644 index 00000000..c05d47ae --- /dev/null +++ b/sharing/scheduling/nearby_share_scheduler_fields.h @@ -0,0 +1,34 @@ +// Copyright 2023 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 THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_SCHEDULER_FIELDS_H_ +#define THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_SCHEDULER_FIELDS_H_ + +#include "absl/strings/string_view.h" + +namespace nearby::sharing { + +// Field names used in scheduler preference storage. +class SchedulerFields { + public: + static constexpr absl::string_view kLastAttemptTimeKeyName = "a"; + static constexpr absl::string_view kLastSuccessTimeKeyName = "s"; + static constexpr absl::string_view kNumConsecutiveFailuresKeyName = "f"; + static constexpr absl::string_view kHasPendingImmediateRequestKeyName = "p"; + static constexpr absl::string_view kIsWaitingForResultKeyName = "w"; +}; + +} // namespace nearby::sharing + +#endif // THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_SCHEDULER_FIELDS_H_ diff --git a/sharing/scheduling/nearby_share_scheduler_utils.cc b/sharing/scheduling/nearby_share_scheduler_utils.cc new file mode 100644 index 00000000..a8a5489f --- /dev/null +++ b/sharing/scheduling/nearby_share_scheduler_utils.cc @@ -0,0 +1,85 @@ +// Copyright 2023 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 "sharing/scheduling/nearby_share_scheduler_utils.h" + +#include +#include +#include +#include +#include +#include + +#include "absl/strings/str_cat.h" +#include "absl/strings/str_format.h" +#include "absl/strings/string_view.h" +#include "absl/time/time.h" +#include "sharing/internal/api/preference_manager.h" +#include "sharing/scheduling/nearby_share_scheduler_fields.h" + +namespace nearby::sharing { + +using ::nearby::sharing::api::PreferenceManager; + +std::string ConvertToReadableSchedule(PreferenceManager& preference_manager, + absl::string_view schedule_preference) { + std::string result = "{"; + std::optional attempt_time = + preference_manager.GetDictionaryInt64Value( + schedule_preference, SchedulerFields::kLastAttemptTimeKeyName); + if (attempt_time.has_value()) { + std::time_t local_t = + absl::ToTimeT(absl::FromUnixNanos(attempt_time.value())); + std::tm* local_time = std::localtime(&local_t); + std::stringstream buffer; + buffer << std::put_time(local_time, "%Y-%m-%d %H:%M:%S"); + absl::StrAppendFormat(&result, "attempt_time:%s, ", buffer.str()); + } + std::optional success_time = + preference_manager.GetDictionaryInt64Value( + schedule_preference, SchedulerFields::kLastSuccessTimeKeyName); + if (success_time.has_value()) { + std::time_t local_t = + absl::ToTimeT(absl::FromUnixNanos(success_time.value())); + std::tm* local_time = std::localtime(&local_t); + std::stringstream buffer; + buffer << std::put_time(local_time, "%Y-%m-%d %H:%M:%S"); + absl::StrAppendFormat(&result, "success_time:%s, ", buffer.str()); + } + std::optional failed_count = + preference_manager.GetDictionaryInt64Value( + schedule_preference, SchedulerFields::kNumConsecutiveFailuresKeyName); + if (failed_count.has_value()) { + absl::StrAppendFormat(&result, "failed_count:%d, ", failed_count.value()); + } + std::optional has_pending = + preference_manager.GetDictionaryBooleanValue( + schedule_preference, + SchedulerFields::kHasPendingImmediateRequestKeyName); + if (has_pending.has_value()) { + absl::StrAppendFormat(&result, "has_pending_request:%s, ", + has_pending.value() ? "true" : "false"); + } + std::optional is_waiting = preference_manager.GetDictionaryBooleanValue( + schedule_preference, SchedulerFields::kIsWaitingForResultKeyName); + if (is_waiting.has_value()) { + absl::StrAppendFormat(&result, "is_waiting_for_result:%s", + is_waiting.value() ? "true" : "false"); + } + + absl::StrAppend(&result, "}"); + return result; +} + +} // namespace nearby::sharing diff --git a/sharing/scheduling/nearby_share_scheduler_utils.h b/sharing/scheduling/nearby_share_scheduler_utils.h new file mode 100644 index 00000000..645fde0e --- /dev/null +++ b/sharing/scheduling/nearby_share_scheduler_utils.h @@ -0,0 +1,32 @@ +// Copyright 2023 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 THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_SCHEDULER_UTILS_H_ +#define THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_SCHEDULER_UTILS_H_ + +#include + +#include "absl/strings/string_view.h" +#include "sharing/internal/api/preference_manager.h" + +namespace nearby::sharing { + +// Converts the schedule preference to a readable string. +std::string ConvertToReadableSchedule( + nearby::sharing::api::PreferenceManager& preference_manager, + absl::string_view schedule_preference); + +} // namespace nearby::sharing + +#endif // THIRD_PARTY_NEARBY_SHARING_SCHEDULING_NEARBY_SHARE_SCHEDULER_UTILS_H_ diff --git a/sharing/scheduling/nearby_share_scheduler_utils_test.cc b/sharing/scheduling/nearby_share_scheduler_utils_test.cc new file mode 100644 index 00000000..5fa95551 --- /dev/null +++ b/sharing/scheduling/nearby_share_scheduler_utils_test.cc @@ -0,0 +1,118 @@ +// Copyright 2023 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 "sharing/scheduling/nearby_share_scheduler_utils.h" + +#include +#include +#include + +#include "gmock/gmock.h" +#include "protobuf-matchers/protocol-buffer-matchers.h" +#include "gtest/gtest.h" +#include "absl/strings/string_view.h" +#include "sharing/internal/api/preference_manager.h" +#include "sharing/internal/test/fake_preference_manager.h" +#include "sharing/scheduling/nearby_share_scheduler_fields.h" + +namespace nearby::sharing { + +using ::nearby::sharing::api::PreferenceManager; +using ::testing::Eq; + +class NearbyShareSchedulerUtilsTest : public ::testing::Test { + protected: + NearbyShareSchedulerUtilsTest() = default; + ~NearbyShareSchedulerUtilsTest() override = default; + + void CreateSchedule(absl::string_view pref_name, + std::optional attempt_time, + std::optional success_time, + std::optional failed_count, + std::optional has_pending, + std::optional is_waiting) { + if (attempt_time.has_value()) { + preference_manager_.SetDictionaryInt64Value( + pref_name, SchedulerFields::kLastAttemptTimeKeyName, + attempt_time.value()); + } + if (success_time.has_value()) { + preference_manager_.SetDictionaryInt64Value( + pref_name, SchedulerFields::kLastSuccessTimeKeyName, + success_time.value()); + } + if (failed_count.has_value()) { + preference_manager_.SetDictionaryInt64Value( + pref_name, SchedulerFields::kNumConsecutiveFailuresKeyName, + failed_count.value()); + } + if (has_pending.has_value()) { + preference_manager_.SetDictionaryBooleanValue( + pref_name, SchedulerFields::kHasPendingImmediateRequestKeyName, + has_pending.value()); + } + if (is_waiting.has_value()) { + preference_manager_.SetDictionaryBooleanValue( + pref_name, SchedulerFields::kIsWaitingForResultKeyName, + is_waiting.value()); + } + } + + PreferenceManager& preference_manager() { return preference_manager_; } + + private: + nearby::FakePreferenceManager preference_manager_; +}; + +TEST_F(NearbyShareSchedulerUtilsTest, ConvertToReadableScheduleSucceeds) { + absl::string_view test_pref = "test_pref"; + preference_manager().Remove(test_pref); + CreateSchedule(test_pref, /*attempt_time=*/123456L, /*success_time=*/345678L, + /*failed_count=*/123, /*has_pending=*/true, + /*is_waiting=*/false); + + std::string debug_str = + ConvertToReadableSchedule(preference_manager(), test_pref); + + EXPECT_THAT(debug_str, Eq("{attempt_time:1969-12-31 16:00:00, " + "success_time:1969-12-31 16:00:00, " + "failed_count:123, has_pending_request:true, " + "is_waiting_for_result:false}")); +} + +TEST_F(NearbyShareSchedulerUtilsTest, ConvertToReadableScheduleEmpty) { + absl::string_view test_pref = "test_pref"; + preference_manager().Remove(test_pref); + + std::string debug_str = + ConvertToReadableSchedule(preference_manager(), test_pref); + + EXPECT_THAT(debug_str, Eq("{}")); +} + +TEST_F(NearbyShareSchedulerUtilsTest, ConvertToReadableScheduleMissingFields) { + absl::string_view test_pref = "test_pref"; + preference_manager().Remove(test_pref); + CreateSchedule(test_pref, /*attempt_time=*/std::nullopt, + /*success_time=*/std::nullopt, + /*failed_count=*/345, /*has_pending=*/std::nullopt, + /*is_waiting=*/true); + + std::string debug_str = + ConvertToReadableSchedule(preference_manager(), test_pref); + + EXPECT_THAT(debug_str, Eq("{failed_count:345, is_waiting_for_result:true}")); +} + +} // namespace nearby::sharing From cd4963b0f9c68775372d91dc422c01d703122345 Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Tue, 9 Jan 2024 11:05:02 -0800 Subject: [PATCH 095/683] Added write timeout for Wi-Fi LAN socket PiperOrigin-RevId: 596987503 --- .../implementation/windows/wifi_lan_socket.cc | 36 ++----------------- 1 file changed, 2 insertions(+), 34 deletions(-) diff --git a/internal/platform/implementation/windows/wifi_lan_socket.cc b/internal/platform/implementation/windows/wifi_lan_socket.cc index 7ab1c4b8..20c71471 100644 --- a/internal/platform/implementation/windows/wifi_lan_socket.cc +++ b/internal/platform/implementation/windows/wifi_lan_socket.cc @@ -1,4 +1,4 @@ -// Copyright 2021-2023 Google LLC +// 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. @@ -12,28 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include - -#include // NOLINT(build/c++11) #include #include #include -#include "internal/platform/byte_array.h" -#include "internal/platform/exception.h" -#include "internal/platform/implementation/windows/generated/winrt/Windows.Foundation.h" #include "internal/platform/implementation/windows/wifi_lan.h" -#include "internal/platform/input_stream.h" #include "internal/platform/logging.h" -#include "internal/platform/output_stream.h" namespace nearby { namespace windows { -namespace { -using ::winrt::Windows::Foundation::TimeSpan; - -constexpr int kWriteTimeoutInSeconds = 10; -} // namespace WifiLanSocket::WifiLanSocket(StreamSocket socket) { stream_soket_ = socket; @@ -161,26 +148,7 @@ Exception WifiLanSocket::SocketOutputStream::Write(const ByteArray& data) { Buffer buffer = Buffer(data.size()); std::memcpy(buffer.data(), data.data(), data.size()); buffer.Length(data.size()); - uint32_t wrote_bytes = 0; - auto write_async = output_stream_.WriteAsync(buffer); - - switch (write_async.wait_for( - TimeSpan(std::chrono::seconds(kWriteTimeoutInSeconds)))) { - case winrt::Windows::Foundation::AsyncStatus::Completed: - wrote_bytes = write_async.GetResults(); - break; - case winrt::Windows::Foundation::AsyncStatus::Started: - NEARBY_LOGS(ERROR) << __func__ - << ": Failed to write socket data due to timeout."; - write_async.Cancel(); - return {Exception::kIo}; - default: - NEARBY_LOGS(ERROR) - << __func__ - << ": Failed to write socket data due to unknown reasons."; - return {Exception::kIo}; - } - + uint32_t wrote_bytes = output_stream_.WriteAsync(buffer).get(); if (wrote_bytes != data.size()) { NEARBY_LOGS(WARNING) << "Only wrote partial of data:[" << wrote_bytes << "/" << data.size() << "]."; From 41d2d6fc4cfa764bc69338e340531aaf94e85c8d Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Tue, 9 Jan 2024 12:03:55 -0800 Subject: [PATCH 096/683] Add sharing/fast_initiation to github. PiperOrigin-RevId: 597004964 --- .github/workflows/validate.yaml | 2 +- sharing/fast_initiation/BUILD | 69 ++++ .../fake_nearby_fast_initiation.cc | 202 ++++++++++++ .../fake_nearby_fast_initiation.h | 128 ++++++++ .../fake_nearby_fast_initiation_observer.h | 46 +++ .../fast_initiation/nearby_fast_initiation.h | 101 ++++++ .../nearby_fast_initiation_impl.cc | 299 ++++++++++++++++++ .../nearby_fast_initiation_impl.h | 86 +++++ .../nearby_fast_initiation_impl_test.cc | 240 ++++++++++++++ 9 files changed, 1172 insertions(+), 1 deletion(-) create mode 100644 sharing/fast_initiation/BUILD create mode 100644 sharing/fast_initiation/fake_nearby_fast_initiation.cc create mode 100644 sharing/fast_initiation/fake_nearby_fast_initiation.h create mode 100644 sharing/fast_initiation/fake_nearby_fast_initiation_observer.h create mode 100644 sharing/fast_initiation/nearby_fast_initiation.h create mode 100644 sharing/fast_initiation/nearby_fast_initiation_impl.cc create mode 100644 sharing/fast_initiation/nearby_fast_initiation_impl.h create mode 100644 sharing/fast_initiation/nearby_fast_initiation_impl_test.cc diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index 334c01a7..e0e41c86 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -38,7 +38,7 @@ jobs: - name: Build Presence run: CC=clang CXX=clang++ bazel build --features=-layering_check //presence --spawn_strategy=standalone - name: Build Sharing - run: CC=clang CXX=clang++ bazel build --features=-layering_check //sharing/proto:all //sharing/internal/public:nearby_context //sharing/common:all //sharing/scheduling:scheduling --spawn_strategy=standalone + run: CC=clang CXX=clang++ bazel build --features=-layering_check //sharing/proto:all //sharing/internal/public:nearby_context //sharing/common:all //sharing/scheduling:scheduling //sharing/fast_initiation:nearby_fast_initiation --spawn_strategy=standalone build-rust-linux: name: Build Rust on Linux diff --git a/sharing/fast_initiation/BUILD b/sharing/fast_initiation/BUILD new file mode 100644 index 00000000..3f67af3c --- /dev/null +++ b/sharing/fast_initiation/BUILD @@ -0,0 +1,69 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +licenses(["notice"]) + +cc_library( + name = "nearby_fast_initiation", + srcs = [ + "nearby_fast_initiation_impl.cc", + ], + hdrs = [ + "nearby_fast_initiation.h", + "nearby_fast_initiation_impl.h", + ], + visibility = ["//visibility:public"], + deps = [ + "//internal/base", + "//sharing/internal/api:platform", + "//sharing/internal/public:logging", + "//sharing/internal/public:types", + ], +) + +cc_library( + name = "test_support", + testonly = True, + srcs = [ + "fake_nearby_fast_initiation.cc", + ], + hdrs = [ + "fake_nearby_fast_initiation.h", + "fake_nearby_fast_initiation_observer.h", + ], + visibility = ["//visibility:public"], + deps = [ + ":nearby_fast_initiation", + "//internal/base", + "//sharing/internal/public:logging", + "//sharing/internal/public:types", + "@com_google_absl//absl/memory", + ], +) + +cc_test( + name = "nearby_fast_initiation_test", + srcs = [ + "nearby_fast_initiation_impl_test.cc", + ], + deps = [ + ":nearby_fast_initiation", + ":test_support", + "//internal/platform/implementation/g3", # fixdeps: keep + "//sharing/internal/api:platform", + "//sharing/internal/test:nearby_test", + "@com_github_protobuf_matchers//protobuf-matchers", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/sharing/fast_initiation/fake_nearby_fast_initiation.cc b/sharing/fast_initiation/fake_nearby_fast_initiation.cc new file mode 100644 index 00000000..0c54a7c8 --- /dev/null +++ b/sharing/fast_initiation/fake_nearby_fast_initiation.cc @@ -0,0 +1,202 @@ +// Copyright 2022 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 "sharing/fast_initiation/fake_nearby_fast_initiation.h" + +#include +#include +#include + +#include "absl/memory/memory.h" +#include "sharing/fast_initiation/nearby_fast_initiation.h" +#include "sharing/internal/public/context.h" +#include "sharing/internal/public/logging.h" + +namespace nearby { +namespace sharing { + +void FakeNearbyFastInitiation::Factory::SetStartScanningError( + bool is_start_scanning_error) { + is_start_scanning_error_ = is_start_scanning_error; +} + +void FakeNearbyFastInitiation::Factory::SetStartAdvertisingError( + bool is_start_advertising_error) { + is_start_advertising_error_ = is_start_advertising_error; +} + +void FakeNearbyFastInitiation::Factory::SetLowEnergySupported( + bool is_low_energy_supported) { + is_low_energy_supported_ = is_low_energy_supported; +} + +void FakeNearbyFastInitiation::Factory::SetScanOffloadSupported( + bool is_scan_offload_supported) { + is_scan_offload_supported_ = is_scan_offload_supported; +} + +void FakeNearbyFastInitiation::Factory::SetAdvertisementOffloadSupported( + bool is_advertisement_offload_supported) { + is_advertisement_offload_supported_ = is_advertisement_offload_supported; +} + +FakeNearbyFastInitiation* +FakeNearbyFastInitiation::Factory::GetNearbyFastInitiation() { + return fake_nearby_fast_initiation_; +} + +std::unique_ptr +FakeNearbyFastInitiation::Factory::CreateInstance(Context* context) { + fake_nearby_fast_initiation_ = new FakeNearbyFastInitiation(context); + fake_nearby_fast_initiation_->SetStartScanningError(is_start_scanning_error_); + fake_nearby_fast_initiation_->SetStartAdvertisingError( + is_start_advertising_error_); + fake_nearby_fast_initiation_->SetLowEnergySupported(is_low_energy_supported_); + fake_nearby_fast_initiation_->SetScanOffloadSupported( + is_scan_offload_supported_); + fake_nearby_fast_initiation_->SetAdvertisementOffloadSupported( + is_advertisement_offload_supported_); + return absl::WrapUnique(fake_nearby_fast_initiation_); +} + +FakeNearbyFastInitiation::FakeNearbyFastInitiation(Context* context) + : context_(context) { + NL_DCHECK(context_); +} + +bool FakeNearbyFastInitiation::IsLowEnergySupported() { + return is_low_energy_supported_; +} + +bool FakeNearbyFastInitiation::IsScanOffloadSupported() { + return is_scan_offload_supported_; +} + +bool FakeNearbyFastInitiation::IsAdvertisementOffloadSupported() { + return is_advertisement_offload_supported_; +} + +void FakeNearbyFastInitiation::StartScanning( + std::function devices_discovered_callback, + std::function devices_not_discovered_callback, + std::function error_callback) { + ++start_scanning_call_count_; + if (is_start_scanning_error_) { + error_callback(); + return; + } + + is_scanning_ = true; + scanning_devices_discovered_callback_ = + std::move(devices_discovered_callback); + scanning_devices_not_discovered_callback_ = + std::move(devices_not_discovered_callback); +} + +void FakeNearbyFastInitiation::StopScanning(std::function callback) { + ++stop_scanning_call_count_; + is_scanning_ = false; + callback(); +} + +void FakeNearbyFastInitiation::StartAdvertising( + FastInitType type, std::function callback, + std::function error_callback) { + ++start_advertising_call_count_; + if (is_start_advertising_error_) { + error_callback(); + } else { + is_advertising_ = true; + callback(); + } +} + +void FakeNearbyFastInitiation::StopAdvertising(std::function callback) { + ++stop_advertising_call_count_; + is_advertising_ = false; + callback(); +} + +void FakeNearbyFastInitiation::AddObserver(Observer* observer) { + observer_list_.AddObserver(observer); +} +void FakeNearbyFastInitiation::RemoveObserver(Observer* observer) { + observer_list_.RemoveObserver(observer); +} +bool FakeNearbyFastInitiation::HasObserver(Observer* observer) { + return observer_list_.HasObserver(observer); +} + +// Fake methods +void FakeNearbyFastInitiation::SetStartScanningError( + bool is_start_scanning_error) { + is_start_scanning_error_ = is_start_scanning_error; + for (Observer* observer : observer_list_.GetObservers()) { + if (observer != nullptr) { + observer->HardwareErrorReported(this); + } + } +} + +void FakeNearbyFastInitiation::SetStartAdvertisingError( + bool is_start_advertising_error) { + is_start_advertising_error_ = is_start_advertising_error; + for (Observer* observer : observer_list_.GetObservers()) { + if (observer != nullptr) { + observer->HardwareErrorReported(this); + } + } +} + +void FakeNearbyFastInitiation::SetLowEnergySupported( + bool is_low_energy_supported) { + is_low_energy_supported_ = is_low_energy_supported; +} + +void FakeNearbyFastInitiation::SetScanOffloadSupported( + bool is_scan_offload_supported) { + is_scan_offload_supported_ = is_scan_offload_supported; +} + +void FakeNearbyFastInitiation::SetAdvertisementOffloadSupported( + bool is_advertisement_offload_supported) { + is_advertisement_offload_supported_ = is_advertisement_offload_supported; +} + +int FakeNearbyFastInitiation::StartScanningCount() const { + return start_scanning_call_count_; +} + +int FakeNearbyFastInitiation::StopScanningCount() const { + return stop_scanning_call_count_; +} + +int FakeNearbyFastInitiation::StartAdvertisingCount() const { + return start_advertising_call_count_; +} + +int FakeNearbyFastInitiation::StopAdvertisingCount() const { + return stop_advertising_call_count_; +} + +void FakeNearbyFastInitiation::FireDevicesDetected() { + scanning_devices_discovered_callback_(); +} + +void FakeNearbyFastInitiation::FireDevicesNotDetected() { + scanning_devices_not_discovered_callback_(); +} + +} // namespace sharing +} // namespace nearby diff --git a/sharing/fast_initiation/fake_nearby_fast_initiation.h b/sharing/fast_initiation/fake_nearby_fast_initiation.h new file mode 100644 index 00000000..719342ba --- /dev/null +++ b/sharing/fast_initiation/fake_nearby_fast_initiation.h @@ -0,0 +1,128 @@ +// Copyright 2022 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 THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_FAKE_NEARBY_FAST_INITIATION_H_ +#define THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_FAKE_NEARBY_FAST_INITIATION_H_ + +#include +#include + +#include "internal/base/observer_list.h" +#include "sharing/fast_initiation/nearby_fast_initiation.h" +#include "sharing/fast_initiation/nearby_fast_initiation_impl.h" +#include "sharing/internal/public/context.h" + +namespace nearby { +namespace sharing { + +// FakeNearbyFastInitiation is a fake implementation of NearbyFastInitiation. +// In the implementation, developers can simulate different output by calling +// faked methods, such as setting offload supports on scanning or advertising. +class FakeNearbyFastInitiation : public NearbyFastInitiation { + public: + class Factory : public NearbyFastInitiationImpl::Factory { + public: + Factory() = default; + ~Factory() override = default; + + void SetStartScanningError(bool is_start_scanning_error); + + void SetStartAdvertisingError(bool is_start_advertising_error); + + void SetLowEnergySupported(bool is_low_energy_supported); + + void SetScanOffloadSupported(bool is_scan_offload_supported); + + void SetAdvertisementOffloadSupported( + bool is_advertisement_offload_supported); + + FakeNearbyFastInitiation* GetNearbyFastInitiation(); + + private: + std::unique_ptr CreateInstance( + Context* context) override; + + bool is_start_scanning_error_ = false; + bool is_start_advertising_error_ = false; + bool is_low_energy_supported_ = true; + bool is_scan_offload_supported_ = true; + bool is_advertisement_offload_supported_ = true; + FakeNearbyFastInitiation* fake_nearby_fast_initiation_ = nullptr; + }; + + explicit FakeNearbyFastInitiation(Context* context); + ~FakeNearbyFastInitiation() override = default; + + bool IsLowEnergySupported() override; + bool IsScanOffloadSupported() override; + bool IsAdvertisementOffloadSupported() override; + + void StartScanning(std::function devices_discovered_callback, + std::function devices_not_discovered_callback, + std::function error_callback) override; + + void StopScanning(std::function callback) override; + + void StartAdvertising(FastInitType type, std::function callback, + std::function error_callback) override; + + void StopAdvertising(std::function callback) override; + + bool IsScanning() const override { return is_scanning_; } + bool IsAdvertising() const override { return is_advertising_; } + + void AddObserver(Observer* observer) override; + void RemoveObserver(Observer* observer) override; + bool HasObserver(Observer* observer) override; + + // Fake methods + void SetStartScanningError(bool is_start_scanning_error); + void SetStartAdvertisingError(bool is_start_advertising_error); + void SetLowEnergySupported(bool is_low_energy_supported); + void SetScanOffloadSupported(bool is_scan_offload_supported); + void SetAdvertisementOffloadSupported( + bool is_advertisement_offload_supported); + + int StartScanningCount() const; + int StopScanningCount() const; + int StartAdvertisingCount() const; + int StopAdvertisingCount() const; + + void FireDevicesDetected(); + void FireDevicesNotDetected(); + + private: + Context* context_; + bool is_scanning_ = false; + bool is_advertising_ = false; + bool is_start_scanning_error_ = false; + bool is_start_advertising_error_ = false; + bool is_low_energy_supported_ = true; + bool is_scan_offload_supported_ = true; + bool is_advertisement_offload_supported_ = true; + int start_scanning_call_count_ = 0; + int stop_scanning_call_count_ = 0; + int start_advertising_call_count_ = 0; + int stop_advertising_call_count_ = 0; + + std::function scanning_devices_discovered_callback_ = nullptr; + std::function scanning_devices_not_discovered_callback_ = nullptr; + + ObserverList observer_list_; +}; + +} // namespace sharing +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_FAKE_NEARBY_FAST_INITIATION_H_ diff --git a/sharing/fast_initiation/fake_nearby_fast_initiation_observer.h b/sharing/fast_initiation/fake_nearby_fast_initiation_observer.h new file mode 100644 index 00000000..22658998 --- /dev/null +++ b/sharing/fast_initiation/fake_nearby_fast_initiation_observer.h @@ -0,0 +1,46 @@ +// Copyright 2024 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 THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_FAKE_NEARBY_FAST_INITIATION_OBSERVER_H_ +#define THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_FAKE_NEARBY_FAST_INITIATION_OBSERVER_H_ + +#include "sharing/fast_initiation/nearby_fast_initiation.h" + +namespace nearby { +namespace sharing { + +class FakeNearbyFastInitiationObserver : public NearbyFastInitiation::Observer { + public: + explicit FakeNearbyFastInitiationObserver( + NearbyFastInitiation* fast_init_manager) { + fast_init_manager_ = fast_init_manager; + num_hardware_error_reported_ = 0; + } + + void HardwareErrorReported(NearbyFastInitiation* fast_init_manager) override { + if (fast_init_manager_ == fast_init_manager) { + num_hardware_error_reported_ += 1; + } + } + + int GetNumHardwareErrorReported() { return num_hardware_error_reported_; } + + private: + NearbyFastInitiation* fast_init_manager_; + int num_hardware_error_reported_; +}; + +} // namespace sharing +} // namespace nearby +#endif // THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_FAKE_NEARBY_FAST_INITIATION_OBSERVER_H_ diff --git a/sharing/fast_initiation/nearby_fast_initiation.h b/sharing/fast_initiation/nearby_fast_initiation.h new file mode 100644 index 00000000..6b4e9d31 --- /dev/null +++ b/sharing/fast_initiation/nearby_fast_initiation.h @@ -0,0 +1,101 @@ +// Copyright 2022 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 THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_NEARBY_FAST_INITIATION_H_ +#define THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_NEARBY_FAST_INITIATION_H_ + +#include + +#include + +namespace nearby { +namespace sharing { + +class NearbyFastInitiation { + public: + enum class Version { kV1 = 0 }; + + // Fast initialization type impacts on the metadata information in payload of + // advertising. + // kNotify = The sender is in the foreground, actively trying to send a file + // to another device. Receivers in the room should be alerted that they may + // need to enter Everyone mode to receive the file. + // kSilent = The phone is passively looking for nearby receivers, but the user + // has not explicitly tried to enter Nearby Share to send the file. The phone + // may cache the receivers nearby so that discovery is faster, or it may + // present these users on ambient surfaces + enum class FastInitType : uint8_t { + kNotify = 0, + kSilent = 1, + }; + + class Observer { + public: + virtual ~Observer() = default; + + // Called when hardware error reported that requires PC restart + virtual void HardwareErrorReported(NearbyFastInitiation* fast_init) {} + }; + + virtual ~NearbyFastInitiation() = default; + + virtual bool IsLowEnergySupported() = 0; + virtual bool IsScanOffloadSupported() = 0; + virtual bool IsAdvertisementOffloadSupported() = 0; + + // Scans nearby devices using BLE. + // |devices_discovered_callback| is called when discovered devices from + // 0 to more. |devices_not_discovered_callback| is called when discovered + // devices become to 0 from more than one. |error_callback| is called + // when error happened. + virtual void StartScanning( + std::function devices_discovered_callback, + std::function devices_not_discovered_callback, + std::function error_callback) = 0; + + // Stops Fast Initialization scanning. |callback| is called + // when scanning is stopped. + virtual void StopScanning(std::function callback) = 0; + + // Begins broadcasting Fast Initiation advertisement. |callback| is called + // when advertising is started. |error_callback| is called if start + // advertising with errors. + // Note: FastInitType is currently hardcoded to kNotify under the hood. To + // support changing the FastInitType after initialization, additional APIs + // need to be added/refactored to Context to reinitialize/reset the + // FastInitiationManager with the desired type. + virtual void StartAdvertising(FastInitType type, + std::function callback, + std::function error_callback) = 0; + + // Stop broadcasting Fast Initiation advertisements. |callback| + // is called when advertising is stopped. + virtual void StopAdvertising(std::function callback) = 0; + + // Check the scanning status. + virtual bool IsScanning() const = 0; + + // Check the advertising status. + virtual bool IsAdvertising() const = 0; + + // Adds and removes observers for hardware error events. + virtual void AddObserver(Observer* observer) = 0; + virtual void RemoveObserver(Observer* observer) = 0; + virtual bool HasObserver(Observer* observer) = 0; +}; + +} // namespace sharing +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_NEARBY_FAST_INITIATION_H_ diff --git a/sharing/fast_initiation/nearby_fast_initiation_impl.cc b/sharing/fast_initiation/nearby_fast_initiation_impl.cc new file mode 100644 index 00000000..59c4f020 --- /dev/null +++ b/sharing/fast_initiation/nearby_fast_initiation_impl.cc @@ -0,0 +1,299 @@ +// Copyright 2022 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 "sharing/fast_initiation/nearby_fast_initiation_impl.h" + +#include +#include +#include +#include + +#include "sharing/fast_initiation/nearby_fast_initiation.h" +#include "sharing/internal/api/bluetooth_adapter.h" +#include "sharing/internal/api/fast_init_ble_beacon.h" +#include "sharing/internal/api/fast_initiation_manager.h" +#include "sharing/internal/public/context.h" +#include "sharing/internal/public/logging.h" + +namespace nearby { +namespace sharing { +using ::nearby::api::FastInitiationManager; + +NearbyFastInitiationImpl::Factory* + NearbyFastInitiationImpl::Factory::test_factory_ = nullptr; + +std::unique_ptr NearbyFastInitiationImpl::Factory::Create( + Context* context) { + NL_DCHECK(context); + if (test_factory_) { + return test_factory_->CreateInstance(context); + } + + return std::make_unique(context); +} + +void NearbyFastInitiationImpl::Factory::SetFactoryForTesting( + Factory* test_factory) { + test_factory_ = test_factory; +} + +NearbyFastInitiationImpl::NearbyFastInitiationImpl(Context* context) + : context_(context) { + NL_DCHECK(context); +} + +bool NearbyFastInitiationImpl::IsLowEnergySupported() { + return context_->GetBluetoothAdapter().IsLowEnergySupported(); +} + +bool NearbyFastInitiationImpl::IsScanOffloadSupported() { + return context_->GetBluetoothAdapter().IsScanOffloadSupported(); +} + +bool NearbyFastInitiationImpl::IsAdvertisementOffloadSupported() { + return context_->GetBluetoothAdapter().IsAdvertisementOffloadSupported(); +} + +bool NearbyFastInitiationImpl::IsScanning() const { + return context_->GetFastInitiationManager().IsScanning(); +} + +bool NearbyFastInitiationImpl::IsAdvertising() const { + return context_->GetFastInitiationManager().IsAdvertising(); +} + +void NearbyFastInitiationImpl::StartScanning( + std::function devices_discovered_callback, + std::function devices_not_discovered_callback, + std::function error_callback) { + if (IsScanning()) { + NL_LOG(WARNING) << __func__ + << ": FastInit BLE scanning was started already."; + error_callback(); + return; + } + + context_->GetFastInitiationManager().StartScanning( + std::move(devices_discovered_callback), + std::move(devices_not_discovered_callback), + [&, error_callback = + std::move(error_callback)](FastInitiationManager::Error error) { + ScanningErrorCodeCallbackHandler(error); + error_callback(); + }); +} + +void NearbyFastInitiationImpl::StopScanning(std::function callback) { + if (!IsScanning()) { + NL_LOG(WARNING) << __func__ << ": FastInit BLE scanning is not running."; + callback(); + return; + } + context_->GetFastInitiationManager().StopScanning( + [&, callback = std::move(callback)]() { callback(); }); +} + +void NearbyFastInitiationImpl::StartAdvertising( + FastInitType type, std::function callback, + std::function error_callback) { + if (IsAdvertising()) { + NL_LOG(WARNING) << __func__ + << ": FastInit BLE advertising was started already."; + error_callback(); + return; + } + + context_->GetFastInitiationManager().StartAdvertising( + ::nearby::api::FastInitBleBeacon::FastInitType(type), + [&, callback = std::move(callback)]() { callback(); }, + [&, error_callback = + std::move(error_callback)](FastInitiationManager::Error error) { + AdvertisingErrorCodeCallbackHandler(error); + error_callback(); + }); +} + +void NearbyFastInitiationImpl::StopAdvertising(std::function callback) { + if (!IsAdvertising()) { + NL_LOG(WARNING) << __func__ << ": FastInit BLE advertising is not running."; + callback(); + return; + } + + context_->GetFastInitiationManager().StopAdvertising( + [&, callback = std::move(callback)]() { callback(); }); +} + +void NearbyFastInitiationImpl::ScanningErrorCodeCallbackHandler( + FastInitiationManager::Error error) { + switch (error) { + case FastInitiationManager::Error::kBluetoothRadioUnavailable: + for (Observer* observer : observer_list_.GetObservers()) { + if (observer != nullptr) { + observer->HardwareErrorReported(this); + } + } + NL_LOG(ERROR) << __func__ + << ": FastInit BLE scanning failed due to bluetooth radio " + "unavailable."; + break; + case FastInitiationManager::Error::kResourceInUse: + for (Observer* observer : observer_list_.GetObservers()) { + if (observer != nullptr) { + observer->HardwareErrorReported(this); + } + } + NL_LOG(ERROR) + << __func__ + << ": FastInit BLE scanning failed due to bluetooth resources are " + "in use/at full capacity."; + break; + case FastInitiationManager::Error::kDisabledByPolicy: + NL_LOG(ERROR) + << __func__ + << ": FastInit BLE scanning failed due to being disabled by policy."; + break; + case FastInitiationManager::Error::kDisabledByUser: + NL_LOG(ERROR) + << __func__ + << ": FastInit BLE scanning failed due to being disabled by user."; + break; + case FastInitiationManager::Error::kHardwareNotSupported: + for (Observer* observer : observer_list_.GetObservers()) { + if (observer != nullptr) { + observer->HardwareErrorReported(this); + } + } + NL_LOG(ERROR) + << __func__ + << ": FastInit BLE scanning failed due to hardware not supported."; + break; + case FastInitiationManager::Error::kTransportNotSupported: + for (Observer* observer : observer_list_.GetObservers()) { + if (observer != nullptr) { + observer->HardwareErrorReported(this); + } + } + NL_LOG(ERROR) + << __func__ + << ": FastInit BLE scanning failed due to transport not supported."; + break; + case FastInitiationManager::Error::kConsentRequired: + NL_LOG(ERROR) + << __func__ + << ": FastInit BLE scanning failed due to consent required."; + break; + case FastInitiationManager::Error::kUnknown: + for (Observer* observer : observer_list_.GetObservers()) { + if (observer != nullptr) { + observer->HardwareErrorReported(this); + } + } + NL_LOG(ERROR) << __func__ + << ": FastInit BLE scanning failed due to unknown reasons."; + break; + default: + break; + } +} + +void NearbyFastInitiationImpl::AdvertisingErrorCodeCallbackHandler( + FastInitiationManager::Error error) { + switch (error) { + case FastInitiationManager::Error::kBluetoothRadioUnavailable: + for (Observer* observer : observer_list_.GetObservers()) { + if (observer != nullptr) { + observer->HardwareErrorReported(this); + } + } + NL_LOG(ERROR) + << __func__ + << ": FastInit BLE advertising failed due to bluetooth radio " + "unavailable."; + break; + case FastInitiationManager::Error::kResourceInUse: + for (Observer* observer : observer_list_.GetObservers()) { + if (observer != nullptr) { + observer->HardwareErrorReported(this); + } + } + NL_LOG(ERROR) + << __func__ + << ": FastInit BLE advertising failed due to bluetooth resources are " + "in use/at full capacity."; + break; + case FastInitiationManager::Error::kDisabledByPolicy: + NL_LOG(ERROR) << __func__ + << ": FastInit BLE advertising failed due to being " + "disabled by policy."; + break; + case FastInitiationManager::Error::kDisabledByUser: + NL_LOG(ERROR) + << __func__ + << ": FastInit BLE advertising failed due to being disabled by user."; + break; + case FastInitiationManager::Error::kHardwareNotSupported: + for (Observer* observer : observer_list_.GetObservers()) { + if (observer != nullptr) { + observer->HardwareErrorReported(this); + } + } + NL_LOG(ERROR) + << __func__ + << ": FastInit BLE advertising failed due to hardware not supported."; + break; + case FastInitiationManager::Error::kTransportNotSupported: + for (Observer* observer : observer_list_.GetObservers()) { + if (observer != nullptr) { + observer->HardwareErrorReported(this); + } + } + NL_LOG(ERROR) << __func__ + << ": FastInit BLE advertising failed due to transport not " + "supported."; + break; + case FastInitiationManager::Error::kConsentRequired: + NL_LOG(ERROR) + << __func__ + << ": FastInit BLE advertising failed due to consent required."; + break; + case FastInitiationManager::Error::kUnknown: + for (Observer* observer : observer_list_.GetObservers()) { + if (observer != nullptr) { + observer->HardwareErrorReported(this); + } + } + NL_LOG(ERROR) + << __func__ + << ": FastInit BLE advertising failed due to unknown reasons."; + break; + default: + break; + } +} + +void NearbyFastInitiationImpl::AddObserver(Observer* observer) { + observer_list_.AddObserver(observer); + NL_LOG(INFO) << __func__ << ": Fast Initiation observer added."; +} +void NearbyFastInitiationImpl::RemoveObserver(Observer* observer) { + observer_list_.RemoveObserver(observer); + NL_LOG(INFO) << __func__ << ": Fast Initiation observer removed."; +} +bool NearbyFastInitiationImpl::HasObserver(Observer* observer) { + return observer_list_.HasObserver(observer); +} + +} // namespace sharing +} // namespace nearby diff --git a/sharing/fast_initiation/nearby_fast_initiation_impl.h b/sharing/fast_initiation/nearby_fast_initiation_impl.h new file mode 100644 index 00000000..4a21447b --- /dev/null +++ b/sharing/fast_initiation/nearby_fast_initiation_impl.h @@ -0,0 +1,86 @@ +// Copyright 2022 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 THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_NEARBY_FAST_INITIATION_IMPL_H_ +#define THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_NEARBY_FAST_INITIATION_IMPL_H_ + +#include +#include + +#include "internal/base/observer_list.h" +#include "sharing/fast_initiation/nearby_fast_initiation.h" +#include "sharing/internal/api/fast_initiation_manager.h" +#include "sharing/internal/public/context.h" + +namespace nearby { +namespace sharing { + +class NearbyFastInitiationImpl : public NearbyFastInitiation { + public: + class Factory { + public: + static std::unique_ptr Create(Context* context); + static void SetFactoryForTesting(Factory* test_factory); + + protected: + virtual ~Factory() = default; + virtual std::unique_ptr CreateInstance( + Context* context) = 0; + + private: + static Factory* test_factory_; + }; + + explicit NearbyFastInitiationImpl(Context* context); + + bool IsLowEnergySupported() override; + bool IsScanOffloadSupported() override; + bool IsAdvertisementOffloadSupported() override; + + void StartScanning(std::function devices_discovered_callback, + std::function devices_not_discovered_callback, + std::function error_callback) override; + + void StopScanning(std::function callback) override; + + void StartAdvertising(FastInitType type, std::function callback, + std::function error_callback) override; + + void StopAdvertising(std::function callback) override; + + bool IsScanning() const override; + + bool IsAdvertising() const override; + + void AddObserver(Observer* observer) override; + void RemoveObserver(Observer* observer) override; + bool HasObserver(Observer* observer) override; + + private: + // Handle the scanning error codes and print out to logs + void ScanningErrorCodeCallbackHandler( + nearby::api::FastInitiationManager::Error error); + + // Handle the advertising error codes and print out to logs + void AdvertisingErrorCodeCallbackHandler( + nearby::api::FastInitiationManager::Error error); + + Context* const context_; + ObserverList observer_list_; +}; + +} // namespace sharing +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_NEARBY_FAST_INITIATION_IMPL_H_ diff --git a/sharing/fast_initiation/nearby_fast_initiation_impl_test.cc b/sharing/fast_initiation/nearby_fast_initiation_impl_test.cc new file mode 100644 index 00000000..0f14f7d2 --- /dev/null +++ b/sharing/fast_initiation/nearby_fast_initiation_impl_test.cc @@ -0,0 +1,240 @@ +// Copyright 2022 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 "sharing/fast_initiation/nearby_fast_initiation_impl.h" + +#include +#include +#include + +#include "gtest/gtest.h" +#include "sharing/fast_initiation/fake_nearby_fast_initiation_observer.h" +#include "sharing/fast_initiation/nearby_fast_initiation.h" +#include "sharing/internal/api/fast_initiation_manager.h" +#include "sharing/internal/test/fake_context.h" +#include "sharing/internal/test/fake_fast_initiation_manager.h" + +namespace nearby { +namespace sharing { +namespace { + +TEST(NearbyFastInitiationImpl, IsLowEnergySupported) { + auto fake_context = std::make_unique(); + NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get()); + EXPECT_TRUE(nearby_fast_initiation_impl.IsLowEnergySupported()); +} + +TEST(NearbyFastInitiationImpl, IsScanOffloadSupported) { + auto fake_context = std::make_unique(); + NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get()); + EXPECT_TRUE(nearby_fast_initiation_impl.IsScanOffloadSupported()); +} + +TEST(NearbyFastInitiationImpl, IsAdvertisementOffloadSupported) { + auto fake_context = std::make_unique(); + NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get()); + EXPECT_TRUE(nearby_fast_initiation_impl.IsAdvertisementOffloadSupported()); +} + +TEST(NearbyFastInitiationImpl, HasObserverReturnsFalseAfterRemovingObserver) { + auto fake_context = std::make_unique(); + NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get()); + FakeNearbyFastInitiationObserver fake_observer(&nearby_fast_initiation_impl); + + nearby_fast_initiation_impl.AddObserver(&fake_observer); + EXPECT_TRUE(nearby_fast_initiation_impl.HasObserver(&fake_observer)); + + nearby_fast_initiation_impl.RemoveObserver(&fake_observer); + EXPECT_FALSE(nearby_fast_initiation_impl.HasObserver(&fake_observer)); +} + +TEST(NearbyFastInitiationImpl, HasObserver) { + auto fake_context = std::make_unique(); + NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get()); + FakeNearbyFastInitiationObserver fake_observer(&nearby_fast_initiation_impl); + + FakeNearbyFastInitiationObserver fake_observer_1( + &nearby_fast_initiation_impl); + FakeNearbyFastInitiationObserver fake_observer_2( + &nearby_fast_initiation_impl); + + nearby_fast_initiation_impl.AddObserver(&fake_observer_1); + + EXPECT_TRUE(nearby_fast_initiation_impl.HasObserver(&fake_observer_1)); + EXPECT_FALSE(nearby_fast_initiation_impl.HasObserver(&fake_observer_2)); +} + +TEST(NearbyFastInitiationImpl, StartAdvertising) { + bool success_callback_called = false; + std::function success_callback = [&]() { + success_callback_called = true; + }; + std::function error_callback = []() {}; + + auto fake_context = std::make_unique(); + NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get()); + nearby_fast_initiation_impl.StartAdvertising( + NearbyFastInitiation::FastInitType::kNotify, success_callback, + error_callback); + FakeFastInitiationManager& fake_fast_initiation_manager = + dynamic_cast( + fake_context->GetFastInitiationManager()); + fake_fast_initiation_manager.SetAdvertisingStarted(); + EXPECT_TRUE(success_callback_called); +} + +TEST(NearbyFastInitiationImpl, StartAdvertisingAndGetHardwareError) { + bool error_callback_called = false; + std::function success_callback = []() {}; + std::function error_callback = [&]() { + error_callback_called = true; + }; + + auto fake_context = std::make_unique(); + NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get()); + + FakeNearbyFastInitiationObserver fake_observer(&nearby_fast_initiation_impl); + + nearby_fast_initiation_impl.AddObserver(&fake_observer); + + nearby_fast_initiation_impl.StartAdvertising( + NearbyFastInitiation::FastInitType::kNotify, success_callback, + error_callback); + + FakeFastInitiationManager& fake_fast_initiation_manager = + dynamic_cast( + fake_context->GetFastInitiationManager()); + + // Mocking OS hardware error event on Windows + fake_fast_initiation_manager.SetAdvertisingError( + nearby::api::FastInitiationManager::Error::kBluetoothRadioUnavailable); + + EXPECT_TRUE(error_callback_called); + EXPECT_EQ(fake_observer.GetNumHardwareErrorReported(), 1); +} + +TEST(NearbyFastInitiationImpl, StopAdvertisingNotStart) { + bool success_callback_called = false; + std::function success_callback = [&]() { + success_callback_called = true; + }; + + auto fake_context = std::make_unique(); + NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get()); + nearby_fast_initiation_impl.StopAdvertising(success_callback); + EXPECT_TRUE(success_callback_called); +} + +TEST(NearbyFastInitiationImpl, StopStartedAdvertising) { + bool start_callback_called = false; + bool stop_callback_called = false; + auto fake_context = std::make_unique(); + FakeFastInitiationManager& fake_fast_initiation_manager = + dynamic_cast( + fake_context->GetFastInitiationManager()); + + NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get()); + nearby_fast_initiation_impl.StartAdvertising( + NearbyFastInitiation::FastInitType::kNotify, + [&]() { start_callback_called = true; }, [&]() {}); + fake_fast_initiation_manager.SetAdvertisingStarted(); + EXPECT_TRUE(start_callback_called); + EXPECT_TRUE(nearby_fast_initiation_impl.IsAdvertising()); + nearby_fast_initiation_impl.StopAdvertising( + [&]() { stop_callback_called = true; }); + + fake_fast_initiation_manager.SetAdvertisingStopped(); + EXPECT_TRUE(stop_callback_called); +} + +TEST(NearbyFastInitiationImpl, StartScanningSucceed) { + bool devices_discovered = false; + std::function devices_discovered_callback = [&devices_discovered]() { + devices_discovered = true; + }; + std::function devices_not_discovered_callback = []() {}; + std::function error_callback = []() {}; + + auto fake_context = std::make_unique(); + NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get()); + nearby_fast_initiation_impl.StartScanning(devices_discovered_callback, + devices_not_discovered_callback, + error_callback); + FakeFastInitiationManager& fake_fast_initiation_manager = + dynamic_cast( + fake_context->GetFastInitiationManager()); + fake_fast_initiation_manager.SetScanningDiscovered(); + EXPECT_TRUE(devices_discovered); +} + +TEST(NearbyFastInitiationImpl, StartScanningAndGetHardwareError) { + bool error_callback_called = false; + std::function devices_discovered_callback = []() {}; + std::function devices_not_discovered_callback = []() {}; + std::function error_callback = [&]() { + error_callback_called = true; + }; + + auto fake_context = std::make_unique(); + NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get()); + + FakeNearbyFastInitiationObserver fake_observer(&nearby_fast_initiation_impl); + + nearby_fast_initiation_impl.AddObserver(&fake_observer); + + nearby_fast_initiation_impl.StartScanning(devices_discovered_callback, + devices_not_discovered_callback, + error_callback); + + FakeFastInitiationManager& fake_fast_initiation_manager = + dynamic_cast( + fake_context->GetFastInitiationManager()); + + // Mocking OS hardware error event on Windows + fake_fast_initiation_manager.SetScanningError( + nearby::api::FastInitiationManager::Error::kBluetoothRadioUnavailable); + + EXPECT_TRUE(error_callback_called); + EXPECT_EQ(fake_observer.GetNumHardwareErrorReported(), 1); +} + +TEST(NearbyFastInitiationImpl, StopScanningNotStart) { + bool stop_callback_called = false; + std::function success_callback = [&]() { + stop_callback_called = true; + }; + + auto fake_context = std::make_unique(); + NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get()); + nearby_fast_initiation_impl.StopScanning(success_callback); + EXPECT_TRUE(stop_callback_called); +} + +TEST(NearbyFastInitiationImpl, StopStartedScanning) { + bool stop_callback_called = false; + auto fake_context = std::make_unique(); + NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get()); + FakeFastInitiationManager& fake_fast_initiation_manager = + dynamic_cast( + fake_context->GetFastInitiationManager()); + nearby_fast_initiation_impl.StartScanning([]() {}, []() {}, []() {}); + nearby_fast_initiation_impl.StopScanning( + [&]() { stop_callback_called = true; }); + fake_fast_initiation_manager.SetScanningStopped(); + EXPECT_TRUE(stop_callback_called); +} + +} // namespace +} // namespace sharing +} // namespace nearby From c2ade33c9c23faeea8f4f33352755d3049998fc9 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Tue, 9 Jan 2024 13:45:13 -0800 Subject: [PATCH 097/683] No public changes. PiperOrigin-RevId: 597033150 --- connections/implementation/analytics/BUILD | 2 +- .../implementation/analytics/analytics_recorder_test.cc | 2 +- connections/implementation/mediums/webrtc/BUILD | 2 +- .../implementation/mediums/webrtc/signaling_frames_test.cc | 2 +- connections/implementation/message_lite.h | 2 +- fastpair/analytics/BUILD | 4 ++-- fastpair/analytics/analytics_recorder.cc | 2 +- fastpair/analytics/analytics_recorder.h | 2 +- fastpair/analytics/analytics_recorder_test.cc | 2 +- internal/analytics/BUILD | 2 +- internal/data/BUILD | 2 +- internal/data/leveldb_data_set.h | 2 +- internal/proto/analytics/BUILD | 2 +- 13 files changed, 14 insertions(+), 14 deletions(-) diff --git a/connections/implementation/analytics/BUILD b/connections/implementation/analytics/BUILD index 022bb0cd..059aa381 100644 --- a/connections/implementation/analytics/BUILD +++ b/connections/implementation/analytics/BUILD @@ -65,9 +65,9 @@ cc_test( "//internal/proto/analytics:connections_log_cc_proto", "//net/proto2/contrib/parse_proto:parse_text_proto", "//proto:connections_enums_cc_proto", - "//third_party/protobuf:protobuf_lite", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/time", "@com_google_googletest//:gtest_main", + "@com_google_protobuf//:protobuf_lite", ], ) diff --git a/connections/implementation/analytics/analytics_recorder_test.cc b/connections/implementation/analytics/analytics_recorder_test.cc index c1d5fb39..1cde99f2 100644 --- a/connections/implementation/analytics/analytics_recorder_test.cc +++ b/connections/implementation/analytics/analytics_recorder_test.cc @@ -34,7 +34,7 @@ #include "internal/platform/exception.h" #include "internal/proto/analytics/connections_log.proto.h" #include "proto/connections_enums.proto.h" -#include "third_party/protobuf/message_lite.h" +#include "google/protobuf/message_lite.h" namespace nearby { namespace analytics { diff --git a/connections/implementation/mediums/webrtc/BUILD b/connections/implementation/mediums/webrtc/BUILD index 1928212b..d00491c9 100644 --- a/connections/implementation/mediums/webrtc/BUILD +++ b/connections/implementation/mediums/webrtc/BUILD @@ -92,12 +92,12 @@ cc_test( "//internal/platform:test_util", "//internal/platform:types", "//internal/platform/implementation/g3", # buildcleaner: keep + "//third_party/protobuf", "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", "//third_party/webrtc/files/stable/webrtc/api:rtc_error", "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/time", "@com_google_googletest//:gtest_main", - "@com_google_protobuf//:protobuf", ], ) diff --git a/connections/implementation/mediums/webrtc/signaling_frames_test.cc b/connections/implementation/mediums/webrtc/signaling_frames_test.cc index a1bb674d..7e11b09a 100644 --- a/connections/implementation/mediums/webrtc/signaling_frames_test.cc +++ b/connections/implementation/mediums/webrtc/signaling_frames_test.cc @@ -16,11 +16,11 @@ #include -#include "google/protobuf/text_format.h" #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" #include "connections/implementation/mediums/webrtc_peer_id.h" +#include "google/protobuf/text_format.h" namespace nearby { namespace connections { diff --git a/connections/implementation/message_lite.h b/connections/implementation/message_lite.h index 5ce9d91e..39635702 100644 --- a/connections/implementation/message_lite.h +++ b/connections/implementation/message_lite.h @@ -15,6 +15,6 @@ #ifndef CORE_INTERNAL_MESSAGE_LITE_H_ #define CORE_INTERNAL_MESSAGE_LITE_H_ -#include "google/protobuf/message_lite.h" +#include "google/protobuf/message_lite.h" // IWYU pragma: export #endif // CORE_INTERNAL_MESSAGE_LITE_H_ diff --git a/fastpair/analytics/BUILD b/fastpair/analytics/BUILD index d1f7f1cf..797b9d7f 100644 --- a/fastpair/analytics/BUILD +++ b/fastpair/analytics/BUILD @@ -29,7 +29,7 @@ cc_library( "//internal/analytics:event_logger", "//internal/proto/analytics:fast_pair_log_cc_proto", "//proto:fast_pair_enums_cc_proto", - "//third_party/protobuf:protobuf_lite", + "@com_google_protobuf//:protobuf_lite", ], ) @@ -41,8 +41,8 @@ cc_test( "//internal/analytics:event_logger", "//internal/proto/analytics:fast_pair_log_cc_proto", "//proto:fast_pair_enums_cc_proto", - "//third_party/protobuf:protobuf_lite", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_googletest//:gtest_main", + "@com_google_protobuf//:protobuf_lite", ], ) diff --git a/fastpair/analytics/analytics_recorder.cc b/fastpair/analytics/analytics_recorder.cc index dfdeabb9..87977029 100644 --- a/fastpair/analytics/analytics_recorder.cc +++ b/fastpair/analytics/analytics_recorder.cc @@ -19,7 +19,7 @@ #include "internal/analytics/event_logger.h" #include "internal/proto/analytics/fast_pair_log.proto.h" #include "proto/fast_pair_enums.proto.h" -#include "third_party/protobuf/message_lite.h" +#include "google/protobuf/message_lite.h" namespace nearby { namespace fastpair { diff --git a/fastpair/analytics/analytics_recorder.h b/fastpair/analytics/analytics_recorder.h index dc8d7b92..fc575f49 100644 --- a/fastpair/analytics/analytics_recorder.h +++ b/fastpair/analytics/analytics_recorder.h @@ -20,7 +20,7 @@ #include "internal/analytics/event_logger.h" #include "internal/proto/analytics/fast_pair_log.proto.h" #include "proto/fast_pair_enums.proto.h" -#include "third_party/protobuf/message_lite.h" +#include "google/protobuf/message_lite.h" namespace nearby { namespace fastpair { diff --git a/fastpair/analytics/analytics_recorder_test.cc b/fastpair/analytics/analytics_recorder_test.cc index 4eb68d40..baa6eb24 100644 --- a/fastpair/analytics/analytics_recorder_test.cc +++ b/fastpair/analytics/analytics_recorder_test.cc @@ -22,7 +22,7 @@ #include "internal/analytics/event_logger.h" #include "internal/proto/analytics/fast_pair_log.proto.h" #include "proto/fast_pair_enums.proto.h" -#include "third_party/protobuf/message_lite.h" +#include "google/protobuf/message_lite.h" namespace nearby { namespace fastpair { diff --git a/internal/analytics/BUILD b/internal/analytics/BUILD index bc15387e..6e831f13 100644 --- a/internal/analytics/BUILD +++ b/internal/analytics/BUILD @@ -26,5 +26,5 @@ cc_library( "//location/nearby/cpp/sharing:__subpackages__", "//sharing:__subpackages__", ], - deps = ["@com_google_protobuf//:protobuf"], + deps = ["@com_google_protobuf//:protobuf_lite"], ) diff --git a/internal/data/BUILD b/internal/data/BUILD index a8342387..2ff9e133 100644 --- a/internal/data/BUILD +++ b/internal/data/BUILD @@ -17,11 +17,11 @@ cc_library( "//third_party/leveldb:db", "//third_party/leveldb:table", "//third_party/leveldb:util", - "//third_party/protobuf:protobuf_lite", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/strings", "@com_google_absl//absl/synchronization", + "@com_google_protobuf//:protobuf_lite", ], ) diff --git a/internal/data/leveldb_data_set.h b/internal/data/leveldb_data_set.h index 5ad4648c..5a27efef 100644 --- a/internal/data/leveldb_data_set.h +++ b/internal/data/leveldb_data_set.h @@ -30,7 +30,7 @@ #include "third_party/leveldb/include/status.h" #include "internal/data/data_set.h" #include "internal/platform/logging.h" -#include "third_party/protobuf/message_lite.h" +#include "google/protobuf/message_lite.h" namespace nearby { namespace data { diff --git a/internal/proto/analytics/BUILD b/internal/proto/analytics/BUILD index 904d2182..fcd46ccb 100644 --- a/internal/proto/analytics/BUILD +++ b/internal/proto/analytics/BUILD @@ -67,8 +67,8 @@ cc_test( "//internal/platform:types", "//internal/platform/implementation/g3", # build_cleaner: keep "//proto:connections_enums_cc_proto", + "//third_party/protobuf", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_googletest//:gtest_main", - "@com_google_protobuf//:protobuf", ], ) From e1f7044f288b8743da2f0ed3478839bdab4d0e95 Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Wed, 10 Jan 2024 09:03:56 -0800 Subject: [PATCH 098/683] Fixed the bug to get file size PiperOrigin-RevId: 597266370 --- internal/platform/implementation/windows/file.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/internal/platform/implementation/windows/file.cc b/internal/platform/implementation/windows/file.cc index 0ce81ed7..4102602d 100644 --- a/internal/platform/implementation/windows/file.cc +++ b/internal/platform/implementation/windows/file.cc @@ -42,6 +42,13 @@ IOFile::IOFile(const absl::string_view file_path, size_t size) file_.open(wide_path, std::ios::binary | std::ios::in | std::ios::ate); total_size_ = file_.tellg(); + if (total_size_ == -1) { + // Unsure why it consistently returns -1 when the file size exceeds 2GB. If + // obtaining the file size through tellg fails, use the size provided + // in the parameters. + total_size_ = size; + } + file_.seekg(0); } From 1190721f3e51422aa33aa6bb4919aa425a08179b Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Wed, 10 Jan 2024 13:20:25 -0800 Subject: [PATCH 099/683] Add sharing/proto/analytics to github. PiperOrigin-RevId: 597338174 --- sharing/proto/analytics/BUILD | 42 + .../proto/analytics/nearby_sharing_log.proto | 827 ++++++++++++++++++ 2 files changed, 869 insertions(+) create mode 100644 sharing/proto/analytics/BUILD create mode 100644 sharing/proto/analytics/nearby_sharing_log.proto diff --git a/sharing/proto/analytics/BUILD b/sharing/proto/analytics/BUILD new file mode 100644 index 00000000..edb82fc8 --- /dev/null +++ b/sharing/proto/analytics/BUILD @@ -0,0 +1,42 @@ +# Copyright 2022 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. + +load("@rules_cc//cc:defs.bzl", "cc_proto_library") + +licenses(["notice"]) + +package(default_visibility = ["//visibility:public"]) + +proto_library( + name = "sharing_log_proto", + srcs = [ + "nearby_sharing_log.proto", + ], + compatible_with = ["//buildenv/target:non_prod"], + deps = [ + "//google/protobuf:duration", + "//proto:sharing_enums_proto", + ], +) + +cc_proto_library( + name = "sharing_log_cc_proto", + compatible_with = ["//buildenv/target:non_prod"], + deps = [":sharing_log_proto"], +) + +java_lite_proto_library( + name = "sharing_log_java_proto_lite", + deps = [":sharing_log_proto"], +) diff --git a/sharing/proto/analytics/nearby_sharing_log.proto b/sharing/proto/analytics/nearby_sharing_log.proto new file mode 100644 index 00000000..f59c4716 --- /dev/null +++ b/sharing/proto/analytics/nearby_sharing_log.proto @@ -0,0 +1,827 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto2"; + +package nearby.sharing.analytics.proto; + +import "google/protobuf/duration.proto"; + +// import "storage/datapol/annotations/proto/semantic_annotations.proto"; +import "third_party/nearby/proto/sharing_enums.proto"; + +// "wireless/android/privacy/annotations/proto/collection_basis_annotations.proto"; + +option optimize_for = LITE_RUNTIME; +option java_package = "nearby.sharing.analytics.proto"; +option java_outer_classname = "SharingLogProto"; +option objc_class_prefix = "GNCP"; + +// Top-level log proto for all NearbySharing logging. +// Each log contains a key (event_type), value (a verb-noun event) pair. +// Next Tag: 76 +// LINT.IfChange +message SharingLog { + /* collection_basis = { + use_cases: UC_SERVICE_OR_API_MEASURING_USER_ENGAGEMENT + } */ + + reserved 71; // Deprecated TransferUIEvent. + + optional location.nearby.proto.sharing.EventType event_type = 1; + + optional UnknownEvent unknown_event = 2; + + optional AcceptAgreements accept_agreements = 3; + + optional EnableNearbySharing enable_nearby_sharing = 4; + + optional SetVisibility set_visibility = 5; + + optional DescribeAttachments describe_attachments = 6; + + optional ScanForShareTargetsStart scan_for_share_targets_start = 7; + + optional ScanForShareTargetsEnd scan_for_share_targets_end = 8; + + optional AdvertiseDevicePresenceStart advertise_device_presence_start = 9; + + optional AdvertiseDevicePresenceEnd advertise_device_presence_end = 10; + + optional SendFastInitialization send_initialization = 11; + + optional ReceiveFastInitialization receive_initialization = 12; + + optional DiscoverShareTarget discover_share_target = 13; + + optional SendIntroduction send_introduction = 14; + + optional ReceiveIntroduction receive_introduction = 15; + + optional RespondToIntroduction respond_introduction = 16; + + optional SendAttachmentsStart send_attachments_start = 17; + + optional SendAttachmentsEnd send_attachments_end = 18; + + optional ReceiveAttachmentsStart receive_attachments_start = 19; + + optional ReceiveAttachmentsEnd receive_attachments_end = 20; + + optional CancelSendingAttachments cancel_sending_attachments = 21; + + optional CancelReceivingAttachments cancel_receiving_attachments = 22; + + optional OpenReceivedAttachments open_received_attachments = 23; + + optional LaunchActivity launch_activity = 24; + + optional AddContact add_contact = 25; + + optional RemoveContact remove_contact = 26; + + optional location.nearby.proto.sharing.LogSource log_source = 27; + + optional FastShareServerResponse fast_share_server_response = 28; + + optional SendStart send_start = 29; + + optional AcceptFastInitialization accept_fast_initialization = 30; + + optional SetDataUsage set_data_usage = 31; + + // The version of Nearby Sharing. E.g. "v1.0.2". + optional string version = 32 /* type = ST_SOFTWARE_ID */; + + optional location.nearby.proto.sharing.EventCategory event_category = 33; + + optional DismissFastInitialization dismiss_fast_initialization = 34; + + optional CancelConnection cancel_connection = 35; + + optional DismissPrivacyNotification dismiss_privacy_notification = 36; + + // Tap privacy notification to update visibility setting. + // http://shortn/_LMJHzPFZM0 + optional TapPrivacyNotification tap_privacy_notification = 37; + + optional TapHelp tap_help = 38; + + optional TapFeedback tap_feedback = 39; + + optional AddQuickSettingsTile add_quick_settings_tile = 40; + + optional RemoveQuickSettingsTile remove_quick_settings_tile = 41; + + optional LaunchPhoneConsent launch_phone_consent = 42; + + optional TapQuickSettingsTile tap_quick_settings_tile = 43; + + optional InstallAPKStatus install_apk_status = 44; + + optional VerifyAPKStatus verify_apk_status = 45; + + optional LaunchConsent launch_consent = 46; + + optional ProcessReceivedAttachmentsEnd process_received_attachments_end = 47; + + optional ToggleShowNotification toggle_show_notification = 48; + + optional SetDeviceName set_device_name = 49; + + // This is a temporary logging field for FilesGo migration phase based on + // device geolocation. Example values are "Phase 1", "Phase 2", etc. + // Reference: http://shortn/_BkSTmDjzWc + optional string files_migration_phase = 50; + + optional DeclineAgreements decline_agreements = 51; + + optional RequestSettingPermissions request_setting_permissions = 52; + + optional DeviceSettings device_settings = 53; + + optional EstablishConnection establish_connection = 54; + + optional AutoDismissFastInitialization auto_dismiss_fast_initialization = 55; + + optional EventMetadata event_metadata = 56; + + // Used only for Nearby Share Windows app now, e.g. "1.0.408". Deprecated and + // move it to the AppInfo below. + optional string app_version = 57 + /* type = ST_SOFTWARE_ID */[deprecated = true]; + + // Used only for Nearby Share Windows app now + optional AppCrash app_crash = 58; + + // Used only for Nearby Share android app now + optional TapQuickSettingsFileShare tap_quick_settings_file_share = 59; + + // Used only for Nearby Share Windows app now. + // TODO(b/260732897): To deprecate, and will be replaced by + // NearbyClientLog.AppInfo. + optional AppInfo app_info = 60; + + // Used only for Nearby Share android app now + optional DisplayPrivacyNotification display_privacy_notification = 61; + + // Used only for Nearby Share android app now + optional DisplayPhoneConsent display_phone_consent = 62; + + // Used only for Nearby Share Windows app now. + optional PreferencesUsage preferences_usage = 63; + + // Used only for Nearby Share android app now. + optional DefaultOptIn default_opt_in = 64; + + optional SetupWizard setup_wizard = 65; + + // Used only for Nearby Share android app now. + optional TapQrCode tap_qr_code = 66; + + optional QrCodeLinkShown qr_code_link_shown = 67; + + optional ParsingFailedEndpointId parsing_failed_endpoint_id = 68; + + optional FastInitDiscoverDevice fast_init_discover_device = 69; + + optional SendDesktopNotification send_desktop_notification = 70; + + optional SendDesktopTransferEvent send_desktop_transfer_event = 72; + + optional SetAccount set_account = 73; + + optional DecryptCertificateFailure decrypt_certificate_failure = 74; + + // Used only for Nearby Share android app now. + optional ShowAllowPermissionAutoAccess show_allow_permission_auto_access = 75; + + // Used only for Nearby Share Windows app now. + message AppInfo { + // e.g. "1.0.408" + optional string app_version = 1 /* type = ST_SOFTWARE_ID */; + // e.g. en. In Windows app, it's from the registry value. + optional string app_language = 2 + /* type = ST_DEMOGRAPHIC_INFO */; + optional string update_track = + 3; // e.g. "developer". In Windows app, it's from the registry value. + } + + message DeviceSettings { + // Device visibility setting at Nearby Share settings page, e.g. Contacts. + optional location.nearby.proto.sharing.Visibility visibility = 1; + // Device data usage preference at Nearby Share settings page, e.g.Wi-Fi + // only, Data, etc. + optional location.nearby.proto.sharing.DataUsage data_usage = 2; + // Device name length + optional int32 device_name_size = 3; + // Whether device allows show notification when devices are sharing nearby. + optional bool is_show_notification_enabled = 4; + // True if the BlueTooth setting is enabled + optional bool is_bt_enabled = 5; + // True if the location setting is enabled + optional bool is_location_enabled = 6; + // True if the wifi setting is enabled + optional bool is_wifi_enabled = 7; + } + + // Used only for Nearby Share Windows app now. Here is the screenshot about + // where preferences are set: + // https://screenshot.googleplex.com/6HFrEfKCPxuSiYz. + message PreferencesUsage { + optional location.nearby.proto.sharing.PreferencesAction action = 1; + optional location.nearby.proto.sharing.PreferencesActionStatus + action_status = 2; + optional location.nearby.proto.sharing.PreferencesAction prev_sub_action = + 3; + optional location.nearby.proto.sharing.PreferencesAction next_sub_action = + 4; + } + + // EventType: UNKNOWN_EVENT_TYPE + message UnknownEvent {} + + // EventType: ESTABLISH_CONNECTION + message EstablishConnection { + // The result status of the attempt to establish a connection. + optional location.nearby.proto.sharing.EstablishConnectionStatus status = 1; + + optional int64 session_id = 2 /* type = ST_SESSION_ID */; + // For group share, 1-based number for transfer position. + optional int32 transfer_position = 3; + // For group share. + optional int32 concurrent_connections = 4; + // For calculating latency. + optional int64 duration_millis = 5; + optional ShareTargetInfo share_target_info = 6; + optional string referrer_name = 7; + optional bool qr_code_flow = 8; + // True if the connection established from receiver + optional bool is_incoming_connection = 9; + } + + // EventType: ACCEPT_AGREEMENTS + message AcceptAgreements {} + + // EventType: DECLINE_AGREEMENTS + message DeclineAgreements {} + + // EventType: ENABLE_NEARBY_SHARING + message EnableNearbySharing { + optional location.nearby.proto.sharing.NearbySharingStatus status = 1; + optional bool has_opted_in = 2; + } + + // EventType: SET_ACCOUNT + // Activity Name: SETUP_ACTIVITY or SETTINGS_ACTIVITY + message SetAccount { + optional location.nearby.proto.sharing.ActivityName activity_name = 1; + } + + // EventType: SET_VISIBILITY + message SetVisibility { + // The new visibility that the device is set to. + optional location.nearby.proto.sharing.Visibility visibility = 1; + + // The current visibility of the device. + optional location.nearby.proto.sharing.Visibility source_visibility = 2; + + // The duration in millis of this visibility setting. + optional int64 duration_millis = 3; + + optional location.nearby.proto.sharing.ActivityName source_activity_name = 4 + /* type = ST_NOT_REQUIRED */; + } + + // EventType: SET_DATA_USAGE + message SetDataUsage { + // The current data usage preference of the device. + optional location.nearby.proto.sharing.DataUsage original_preference = 1; + + // The new data usage preference that the device is set to. + optional location.nearby.proto.sharing.DataUsage preference = 2; + } + + // EventType: SCAN_FOR_SHARE_TARGETS_START + message ScanForShareTargetsStart { + // A randomly generated number to be used to join the start and end of a + // session (mostly used to compute the duration of the session, e.g. how + // long does it take for attachments to be shared/sent via the Nearby + // Connections api). A same number is used twice for the start and + // end of a session. It is not designed to be associated to user or device, + // and can only be used to join the start and end of a particular session. + // Each session itself does not contain user or device information, and is + // not designed to be joined with other sessions/events of the same user to + // reconstruct particular user's activity pattern. + optional int64 session_id = 1 /* type = ST_SESSION_ID */; + optional location.nearby.proto.sharing.SessionStatus status = 2; + optional location.nearby.proto.sharing.ScanType scan_type = 3; + optional int64 flow_id = 4 /* type = ST_SESSION_ID */; + optional string referrer_name = 5; + } + + // EventType: SCAN_FOR_SHARE_TARGETS_END + message ScanForShareTargetsEnd { + optional int64 session_id = 1 /* type = ST_SESSION_ID */; + } + + // EventType: ADVERTISE_DEVICE_PRESENCE_START + message AdvertiseDevicePresenceStart { + // No longer needed for advertisement. + optional int64 session_id = 1 + /* type = ST_SESSION_ID */[deprecated = true]; + optional location.nearby.proto.sharing.Visibility visibility = 2; + optional location.nearby.proto.sharing.SessionStatus status = 3; + optional location.nearby.proto.sharing.DataUsage data_usage = 4; + // No longer needed for advertisement, replace this with + // SET_NAME_DEVICE. + optional int32 device_name_size = 5 [deprecated = true]; + optional string referrer_name = 6; + optional location.nearby.proto.sharing.AdvertisingMode advertising_mode = 7; + optional bool qr_code_flow = 8; + } + + // EventType: ADVERTISE_DEVICE_PRESENCE_END + message AdvertiseDevicePresenceEnd { + // No longer needed for advertisement. + optional int64 session_id = 1 + /* type = ST_SESSION_ID */[deprecated = true]; + } + + // EventType: SEND_FAST_INITIALIZATION + message SendFastInitialization {} + + // EventType: RECEIVE_FAST_INITIALIZATION + message ReceiveFastInitialization { + // The time elapse from the beginning of screen unlock to the time + // when the FastInitialization is received. + optional int64 time_elapse_since_screen_unlock_millis = 1; + // True if the notification is enabled + optional bool notifications_enabled = 2; + // True if the notification is being filtered when being shown + optional bool notifications_filtered = 3; + } + + // EventType: DISMISS_FAST_INITIALIZATION + message DismissFastInitialization {} + + // EventType: AUTO_DISMISS_FAST_INITIALIZATION + message AutoDismissFastInitialization {} + + // TODO(b/302987763): We need to deprecate flow_id and session_id in each + // event once these two fields in metadata are released to prod and + // pipelines are updated to read them. + message EventMetadata { + optional location.nearby.proto.sharing.SharingUseCase use_case = 1; + // The opt-in status before the user enters the first opt-in screen in each + // time file share or it is always “true” if the user has opted in before. + optional bool initial_opt_in = 2; + // The opt-in status after the user leaves the first opt-in screen in each + // time file share or it is always “true” if the user has opted in before. + optional bool opt_in = 3; + // The Nearby Share enable status before the user enters the first + // opt-in screen in each time file share. + optional bool initial_enable_status = 4; + // The same id means it is in the same sharing file flow of sender side. + // Ex: when sender share file to 2 receivers, the flow_id in sender side is + // the same for all the discovery/connection/transfer events. + optional int64 flow_id = 5 /* type = ST_SESSION_ID */; + // A randomly generated number to be used to join the start and end of a + // session (mostly used to compute the duration of the session, e.g. how + // long does it take for attachments to be shared/sent via the Nearby + // Connections api). A same number is used twice for the start and + // end of a session. It is not designed to be associated to user or device, + // and can only be used to join the start and end of a particular session. + // Each session itself does not contain user or device information, and is + // not designed to be joined with other sessions/events of the same user to + // reconstruct particular user's activity pattern. + optional int64 session_id = 6 /* type = ST_SESSION_ID */; + } + + // TODO(fdi): may consider adding a field about decipherability later. + // EventType: DISCOVER_SHARE_TARGET + message DiscoverShareTarget { + optional ShareTargetInfo share_target_info = 1; + // The time elapse from the beginning of an scanning session to the time + // when the share target is discovered. + optional google.protobuf.Duration duration_since_scanning = 2; + optional int64 session_id = 3 /* type = ST_SESSION_ID */; + optional int64 flow_id = 4 /* type = ST_SESSION_ID */; + optional string referrer_name = 5; + // The time elapse from the share sheet activity starts (foreground + // send surface) to the time when the share target is discovered. + // Only uses foreground send surfaces, since this is when users + // directly engage with NS to send. + optional int64 latency_since_activity_start_millis = 6 [default = -1]; + optional location.nearby.proto.sharing.ScanType scan_type = 7; + } + + // EventType: PARSING_FAILED_ENDPOINT_ID + message ParsingFailedEndpointId { + optional string endpoint_id = 1 /* type = ST_SESSION_ID */; + // The time elapse from the beginning of an scanning session to the time + // when the share target is discovered. + optional google.protobuf.Duration duration_since_scanning = 2; + optional int64 session_id = 3 /* type = ST_SESSION_ID */; + optional int64 flow_id = 4 /* type = ST_SESSION_ID */; + optional string referrer_name = 5 + /* type = ST_REFERER_URL */; + // The time elapse from the share sheet activity starts to the time + // when the share target is discovered. + optional int64 latency_since_activity_start_millis = 6 [default = -1]; + optional location.nearby.proto.sharing.ScanType scan_type = 7; + // The time elapse from the beginning of sync to download the certificates + // to the time when the scanning fails in parsing. + optional google.protobuf.Duration duration_since_last_sync = 8; + optional location.nearby.proto.sharing.ParsingFailedType + parsing_failed_type = 9; + optional location.nearby.proto.sharing.DiscoveryMode discovery_mode = 10; + } + + // EventType: DESCRIBE_ATTACHMENTS + message DescribeAttachments { + optional AttachmentsInfo attachments_info = 1; + } + + // TODO(fdi): may want to add duration_from_scanning_millis later. + // EventType: SEND_INTRODUCTION + message SendIntroduction { + optional ShareTargetInfo share_target_info = 1; + optional int64 session_id = 2 /* type = ST_SESSION_ID */; + // 1-based number for transfer position. + optional int32 transfer_position = 3; + optional int32 concurrent_connections = 4; + } + + // EventType: RECEIVE_INTRODUCTION + message ReceiveIntroduction { + optional int64 session_id = 1 /* type = ST_SESSION_ID */; + optional ShareTargetInfo share_target_info = 2; + optional string referrer_name = 3; + } + + // TODO(fdi): may add AttachmentInfo, or ShareTargetInfo later. + // EventType: RESPOND_TO_INTRODUCTION + message RespondToIntroduction { + optional location.nearby.proto.sharing.ResponseToIntroduction action = 1; + optional int64 session_id = 2 /* type = ST_SESSION_ID */; + optional bool qr_code_flow = 3; + } + + // EventType: SEND_ATTACHMENTS_START + message SendAttachmentsStart { + optional int64 session_id = 1 /* type = ST_SESSION_ID */; + optional AttachmentsInfo attachments_info = 2; + // 1-based number for transfer position. + optional int32 transfer_position = 3; + optional int32 concurrent_connections = 4; + optional bool qr_code_flow = 5; + } + + // EventType: SEND_ATTACHMENTS_END + message SendAttachmentsEnd { + optional int64 session_id = 1 /* type = ST_SESSION_ID */; + optional int64 sent_bytes = 2; + optional location.nearby.proto.sharing.AttachmentTransmissionStatus status = + 3; + // 1-based number for transfer position. + optional int32 transfer_position = 4; + optional int32 concurrent_connections = 5; + optional AttachmentsInfo attachments_info = 6; + // the duration from transfer start to transfer is finished. + optional int64 duration_millis = 7; + optional ShareTargetInfo share_target_info = 8; + optional string referrer_name = 9; + // connection status from nearby connections layer + optional location.nearby.proto.sharing.ConnectionLayerStatus + connection_layer_status = 10; + } + + // EventType: RECEIVE_ATTACHMENTS_START + message ReceiveAttachmentsStart { + optional int64 session_id = 1 /* type = ST_SESSION_ID */; + optional AttachmentsInfo attachments_info = 2; + optional ShareTargetInfo share_target_info = 3; + } + + // EventType: RECEIVE_ATTACHMENTS_END + message ReceiveAttachmentsEnd { + optional int64 session_id = 1 /* type = ST_SESSION_ID */; + optional int64 received_bytes = 2; + optional location.nearby.proto.sharing.AttachmentTransmissionStatus status = + 3; + optional string referrer_name = 4; + optional ShareTargetInfo share_target_info = 5; + } + + // EventType: CANCEL_CONNECTION + message CancelConnection { + optional int64 session_id = 1 /* type = ST_SESSION_ID */; + // 1-based number for transfer position. 1 if log is from receiver side. + optional int32 transfer_position = 2; + optional int32 concurrent_connections = 3; + } + + // EventType: CANCEL_SENDING_ATTACHMENTS + message CancelSendingAttachments {} + + // EventType: CANCEL_RECEIVING_ATTACHMENTS + message CancelReceivingAttachments {} + + // EventType: PROCESS_RECEIVED_ATTACHMENTS_END + message ProcessReceivedAttachmentsEnd { + optional int64 session_id = 1 /* type = ST_SESSION_ID */; + optional location.nearby.proto.sharing.ProcessReceivedAttachmentsStatus + status = 2; + } + + // EventType: OPEN_RECEIVED_ATTACHMENTS + message OpenReceivedAttachments { + optional AttachmentsInfo attachments_info = 3; + optional int64 session_id = 4 /* type = ST_SESSION_ID */; + } + + // EventType: LAUNCH_SETUP_ACTIVITY + message LaunchSetupActivity {} + + // EventType: ADD_CONTACT + message AddContact { + optional bool was_phone_added = 1; + optional bool was_email_added = 2; + } + + // EventType: REMOVE_CONTACT + message RemoveContact { + optional bool was_phone_removed = 1; + optional bool was_email_removed = 2; + } + + // EventType: FAST_SHARE_SERVER_RESPONSE + message FastShareServerResponse { + optional location.nearby.proto.sharing.ServerResponseState status = 1; + optional location.nearby.proto.sharing.ServerActionName name = 2; + optional int64 latency_millis = 3; + optional location.nearby.proto.sharing.SyncPurpose purpose = 4; + optional location.nearby.proto.sharing.ClientRole requester = 5; + optional location.nearby.proto.sharing.DeviceType device_type = 6; + } + + // EventType: SEND_START + message SendStart { + optional int64 session_id = 1 /* type = ST_SESSION_ID */; + // 1-based number for transfer position. + optional int32 transfer_position = 2; + optional int32 concurrent_connections = 3; + optional ShareTargetInfo share_target_info = 4; + } + + // EventType: ACCEPT_FAST_INITIALIZATION + message AcceptFastInitialization {} + + // EventType: LAUNCH_ACTIVITY + message LaunchActivity { + optional location.nearby.proto.sharing.ActivityName activity_name = 1; + // Elapsed time in milliseconds between startActivity and stopActivity. + optional int64 duration_millis = 2; + // The name of the package that launched the activity + optional string referrer_name = 3; + // Is previous transfer in progress. + optional bool previous_transfer_in_progress = 4; + // Whether user has opted in before. For SETUP_ACTIVITY (Opt-In half sheet) + // and SETTINGS_ACTIVITY (Settings page). b/202415050, b/203248230 + optional bool has_opted_in = 5; + // Indicate which UI interaction triggers the opt-in half sheet. Currently + // this only applies to SETUP_ACTIVITY + optional location.nearby.proto.sharing.ActivityName source_activity_name = + 6; + // Is the activity simply pausing or completely finishing. + optional bool is_finishing = 7; + } + + // EventType: DISMISS_PRIVACY_NOTIFICATION + message DismissPrivacyNotification {} + + // EventType: TAP_PRIVACY_NOTIFICATION + message TapPrivacyNotification {} + + // EventType: TAP_HELP + message TapHelp {} + + // EventType: TAP_FEEDBACK + message TapFeedback {} + + // EventType: ADD_QUICK_SETTINGS_TILE + message AddQuickSettingsTile {} + + // EventType: REMOVE_QUICK_SETTINGS_TILE + message RemoveQuickSettingsTile {} + + // EventType: LAUNCH_PHONE_CONSENT + message LaunchPhoneConsent {} + + // EventType: DISPLAY_PHONE_CONSENT + message DisplayPhoneConsent {} + + // EventType: TAP_QUICK_SETTINGS_TILE + message TapQuickSettingsTile {} + + // EventType: TAP_QUICK_SETTINGS_FILE_SHARE + message TapQuickSettingsFileShare {} + + // EventType: DISPLAY_PRIVACY_NOTIFICATION + message DisplayPrivacyNotification {} + + // EventType: DEFAULT_OPT_IN + message DefaultOptIn {} + + // EventType: SET_DEVICE_NAME + message SetDeviceName { + optional int32 device_name_size = 1; + } + + // EventType: REQUEST_SETTING_PERMISSIONS + message RequestSettingPermissions { + optional location.nearby.proto.sharing.PermissionRequestType + permission_type = 1; + optional location.nearby.proto.sharing.PermissionRequestResult + permission_request_result = 2; + } + + // EventType: LAUNCH_CONSENT + message LaunchConsent { + optional location.nearby.proto.sharing.ConsentType consent_type = 1; + optional location.nearby.proto.sharing.ConsentAcceptanceStatus status = 2; + } + + // EventType: INSTALL_APK_STATUS + message InstallAPKStatus { + repeated location.nearby.proto.sharing.InstallAPKStatus status = 1 + [packed = true]; + repeated location.nearby.proto.sharing.ApkSource source = 2 [packed = true]; + } + + // EventType: VERIFY_APK_STATUS + message VerifyAPKStatus { + repeated location.nearby.proto.sharing.VerifyAPKStatus status = 1 + [packed = true]; + repeated location.nearby.proto.sharing.ApkSource source = 2 [packed = true]; + } + + // EventType: TOGGLE_SHOW_NOTIFICATION + message ToggleShowNotification { + optional location.nearby.proto.sharing.ShowNotificationStatus + previous_status = 1; + optional location.nearby.proto.sharing.ShowNotificationStatus + current_status = 2; + } + + // EventType: DECRYPT_CERTIFICATE_FAILURE + message DecryptCertificateFailure { + optional location.nearby.proto.sharing.DecryptCertificateFailureStatus + status = 1; + } + + // EventType: SHOW_ALLOW_PERMISSION_AUTO_ACCESS + message ShowAllowPermissionAutoAccess { + // Auto permission UI activity name + // Shows the auto permission UI if the device lacks Wifi or Bluetooth + // permission and the user has not allowed Nearby Share to automatically + // enable these permissions. Once the user allows access, the UI will + // not be shown again. + // Currently, only the SHARE_SHEET_ACTIVITY and RECEIVE_SURFACE_ACTIVITY + // show the UI. + optional location.nearby.proto.sharing.ActivityName activity_name = 1; + // True if user allowed NS to auto enable Wifi/BT permissions during file + // transfer and NS will recover the permissions after transffer is complete. + optional bool allowed_auto_access = 2; + // True if the device lacks Wifi permission. + optional bool is_wifi_missing = 3; + // True if the device lacks Bluetooth permission. + optional bool is_bt_missing = 4; + } + + // EventType: TAP_QR_CODE + message TapQrCode {} + + // QR_CODE_LINK_SHOWN + message QrCodeLinkShown {} + + // EventType: FAST_INIT_DISCOVER_DEVICE + message FastInitDiscoverDevice { + reserved 1; + // The advertisement type is NOTIFY or SILENT. + optional location.nearby.proto.sharing.FastInitType fast_init_type = 2; + // The distance of the found nearby fast init advertisement. + optional location.nearby.proto.sharing.FastInitState fast_init_state = 3; + } + + // The metadata of a share target. + message ShareTargetInfo { + optional location.nearby.proto.sharing.DeviceType device_type = 1; + optional location.nearby.proto.sharing.OSType os_type = 2; + optional location.nearby.proto.sharing.DeviceRelationship + device_relationship = 3; + } + + // The metadata of attachments to be shared. + message AttachmentsInfo { + repeated TextAttachment text_attachment = 1; + repeated FileAttachment file_attachment = 2; + // The App required by sender to open the attachments. + optional string required_app = 3; + repeated WifiCredentialsAttachment wifi_credentials_attachment = 4; + repeated AppAttachment app_attachment = 5; + repeated StreamAttachment stream_attachment = 6; + } + + message TextAttachment { + optional Type type = 1; + optional int64 size_bytes = 2; + // attachments are batched together by some source + optional int64 batch_id = 3 /* type = ST_SESSION_ID */; + optional location.nearby.proto.sharing.AttachmentSourceType source_type = 4; + + enum Type { + UNKNOWN_TEXT_TYPE = 0; + URL = 1; + ADDRESS = 2; + PHONE_NUMBER = 3; + } + } + + message FileAttachment { + optional Type type = 1; + optional int64 size_bytes = 2; + reserved 3; // optional string mime_type = 3 + optional int64 offset_bytes = 4; + // attachments are batched together by some source + optional int64 batch_id = 5 /* type = ST_SESSION_ID */; + optional location.nearby.proto.sharing.AttachmentSourceType source_type = 6; + + enum Type { + UNKNOWN_FILE_TYPE = 0; + IMAGE = 1; + VIDEO = 2; + ANDROID_APP = 3; + AUDIO = 4; + DOCUMENT = 5; + } + } + + message WifiCredentialsAttachment { + optional int32 security_type = 1; + // attachments are batched together by some source + optional int64 batch_id = 2 /* type = ST_SESSION_ID */; + optional location.nearby.proto.sharing.AttachmentSourceType source_type = 3; + } + + message AppAttachment { + optional string package_name = 1 /* type = ST_SOFTWARE_ID */; + // App size in bytes. + optional int64 size = 2; + // attachments are batched together by some source + optional int64 batch_id = 3 /* type = ST_SESSION_ID */; + optional location.nearby.proto.sharing.AttachmentSourceType source_type = 4; + } + + message StreamAttachment { + optional string package_name = 1 /* type = ST_SOFTWARE_ID */; + // attachments are batched together by some source + optional int64 batch_id = 2 /* type = ST_SESSION_ID */; + optional location.nearby.proto.sharing.AttachmentSourceType source_type = 3; + } + + // EventType: APP_CRASH + // Used only for Nearby Share Windows App now + message AppCrash { + optional location.nearby.proto.sharing.AppCrashReason crash_reason = 1; + } + + // EventType: SETUP_WIZARD + // The results of a setup wizard flow + message SetupWizard { + // The new visibility of the device. + optional location.nearby.proto.sharing.Visibility visibility = 1; + } + + message SendDesktopNotification { + reserved 2; + optional location.nearby.proto.sharing.DesktopNotification event = 1; + } + + message SendDesktopTransferEvent { + optional location.nearby.proto.sharing.DesktopTransferEventType event = 1; + } +} +// LINT.ThenChange(//depot/google3/logs/proto/location/nearby/nearby_client_log.proto) From b46ef89339ae85d133b6e0836b26f28eed8c0c3d Mon Sep 17 00:00:00 2001 From: Anay Wadhera Date: Tue, 9 Jan 2024 18:35:43 -0800 Subject: [PATCH 100/683] Add Android readme and sample app --- sharing/android/README.md | 6 + sharing/android/example/.gitignore | 16 ++ sharing/android/example/README.md | 15 ++ sharing/android/example/app/.gitignore | 1 + sharing/android/example/app/build.gradle.kts | 62 ++++++ .../android/example/app/proguard-rules.pro | 21 ++ .../example/app/src/main/AndroidManifest.xml | 28 +++ .../google/nearby/sharedemo/MainActivity.kt | 165 ++++++++++++++++ .../google/nearby/sharedemo/MainViewModel.kt | 123 ++++++++++++ .../google/nearby/sharedemo/ShareTarget.kt | 43 ++++ .../google/nearby/sharedemo/ui/theme/Theme.kt | 51 +++++ .../res/drawable/ic_launcher_background.xml | 170 ++++++++++++++++ .../res/drawable/ic_launcher_foreground.xml | 30 +++ .../main/res/mipmap-anydpi/ic_launcher.xml | 6 + .../res/mipmap-anydpi/ic_launcher_round.xml | 6 + .../src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 0 -> 1404 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 0 -> 2898 bytes .../src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 0 -> 982 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 0 -> 1772 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 0 -> 1900 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 0 -> 3918 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 0 -> 2884 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 0 -> 5914 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 0 -> 3844 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 0 -> 7778 bytes .../app/src/main/res/values/colors.xml | 10 + .../app/src/main/res/values/strings.xml | 3 + .../app/src/main/res/values/themes.xml | 5 + .../app/src/main/res/xml/backup_rules.xml | 13 ++ .../main/res/xml/data_extraction_rules.xml | 19 ++ sharing/android/example/build.gradle.kts | 5 + sharing/android/example/gradle.properties | 23 +++ .../example/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59203 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + sharing/android/example/gradlew | 185 ++++++++++++++++++ sharing/android/example/gradlew.bat | 89 +++++++++ sharing/android/example/settings.gradle.kts | 17 ++ 37 files changed, 1118 insertions(+) create mode 100644 sharing/android/README.md create mode 100644 sharing/android/example/.gitignore create mode 100644 sharing/android/example/README.md create mode 100644 sharing/android/example/app/.gitignore create mode 100644 sharing/android/example/app/build.gradle.kts create mode 100644 sharing/android/example/app/proguard-rules.pro create mode 100644 sharing/android/example/app/src/main/AndroidManifest.xml create mode 100644 sharing/android/example/app/src/main/java/com/google/nearby/sharedemo/MainActivity.kt create mode 100644 sharing/android/example/app/src/main/java/com/google/nearby/sharedemo/MainViewModel.kt create mode 100644 sharing/android/example/app/src/main/java/com/google/nearby/sharedemo/ShareTarget.kt create mode 100644 sharing/android/example/app/src/main/java/com/google/nearby/sharedemo/ui/theme/Theme.kt create mode 100644 sharing/android/example/app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 sharing/android/example/app/src/main/res/drawable/ic_launcher_foreground.xml create mode 100644 sharing/android/example/app/src/main/res/mipmap-anydpi/ic_launcher.xml create mode 100644 sharing/android/example/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml create mode 100644 sharing/android/example/app/src/main/res/mipmap-hdpi/ic_launcher.webp create mode 100644 sharing/android/example/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp create mode 100644 sharing/android/example/app/src/main/res/mipmap-mdpi/ic_launcher.webp create mode 100644 sharing/android/example/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp create mode 100644 sharing/android/example/app/src/main/res/mipmap-xhdpi/ic_launcher.webp create mode 100644 sharing/android/example/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp create mode 100644 sharing/android/example/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp create mode 100644 sharing/android/example/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp create mode 100644 sharing/android/example/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp create mode 100644 sharing/android/example/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp create mode 100644 sharing/android/example/app/src/main/res/values/colors.xml create mode 100644 sharing/android/example/app/src/main/res/values/strings.xml create mode 100644 sharing/android/example/app/src/main/res/values/themes.xml create mode 100644 sharing/android/example/app/src/main/res/xml/backup_rules.xml create mode 100644 sharing/android/example/app/src/main/res/xml/data_extraction_rules.xml create mode 100644 sharing/android/example/build.gradle.kts create mode 100644 sharing/android/example/gradle.properties create mode 100644 sharing/android/example/gradle/wrapper/gradle-wrapper.jar create mode 100644 sharing/android/example/gradle/wrapper/gradle-wrapper.properties create mode 100755 sharing/android/example/gradlew create mode 100644 sharing/android/example/gradlew.bat create mode 100644 sharing/android/example/settings.gradle.kts diff --git a/sharing/android/README.md b/sharing/android/README.md new file mode 100644 index 00000000..6d8ddba0 --- /dev/null +++ b/sharing/android/README.md @@ -0,0 +1,6 @@ +# Nearby Sharing Android API + +## The slice API +The nearby module in GMSCore provides a third-party accessible slice to bind to, to provide live data on nearby targets using Nearby Share. Clicking on any of these targets will take you to the main Nearby Share screen, where the transfer will begin and continually update the progress. + +The slice URI is `content://com.google.android.gms.nearby.sharing/scan`. Upon first launch after install, you will be prompted to grant permission to the client application. After that, the slice will be kept up to date with the latest targets nearby. diff --git a/sharing/android/example/.gitignore b/sharing/android/example/.gitignore new file mode 100644 index 00000000..565a5412 --- /dev/null +++ b/sharing/android/example/.gitignore @@ -0,0 +1,16 @@ +*.iml +.gradle +.idea +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/sharing/android/example/README.md b/sharing/android/example/README.md new file mode 100644 index 00000000..288d91c5 --- /dev/null +++ b/sharing/android/example/README.md @@ -0,0 +1,15 @@ +# Nearby Share sample app + +This app is a demonstration of how to bind to and use the Nearby Share slice. + +## Build instructions +From the root of the repository: +``` +$ cd sharing/android/example +$ ./gradlew build +``` + +## Key callouts +MainViewModel - contains the business logic for processing and binding to the slice, as well as the lifecycle of the slice. + +MainActivity - hosts the `MainView` composable and provides the intent to fill in the slice's PendingIntent action with, providing the data to send via Nearby Share. diff --git a/sharing/android/example/app/.gitignore b/sharing/android/example/app/.gitignore new file mode 100644 index 00000000..796b96d1 --- /dev/null +++ b/sharing/android/example/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/sharing/android/example/app/build.gradle.kts b/sharing/android/example/app/build.gradle.kts new file mode 100644 index 00000000..acbe5cc2 --- /dev/null +++ b/sharing/android/example/app/build.gradle.kts @@ -0,0 +1,62 @@ +plugins { + id("com.android.application") + id("org.jetbrains.kotlin.android") +} + +android { + namespace = "com.google.nearby.sharedemo" + compileSdk = 33 + + defaultConfig { + applicationId = "com.google.nearby.sharedemo" + minSdk = 30 + targetSdk = 33 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + vectorDrawables { + useSupportLibrary = true + } + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = "1.8" + } + buildFeatures { + compose = true + } + composeOptions { + kotlinCompilerExtensionVersion = "1.4.3" + } + packaging { + resources { + excludes += "/META-INF/{AL2.0,LGPL2.1}" + } + } +} + +dependencies { + implementation("androidx.core:core-ktx:1.9.0") + implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2") + implementation("androidx.activity:activity-compose:1.7.2") + implementation(platform("androidx.compose:compose-bom:2023.03.00")) + implementation("androidx.compose.ui:ui") + implementation("androidx.compose.ui:ui-graphics") + implementation("androidx.compose.ui:ui-tooling-preview") + implementation("androidx.compose.material3:material3") + implementation("androidx.slice:slice-core:1.1.0-alpha02") + implementation("androidx.slice:slice-view:1.1.0-alpha02") + debugImplementation("androidx.compose.ui:ui-tooling") + debugImplementation("androidx.compose.ui:ui-test-manifest") +} diff --git a/sharing/android/example/app/proguard-rules.pro b/sharing/android/example/app/proguard-rules.pro new file mode 100644 index 00000000..f1b42451 --- /dev/null +++ b/sharing/android/example/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/sharing/android/example/app/src/main/AndroidManifest.xml b/sharing/android/example/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..096bbb17 --- /dev/null +++ b/sharing/android/example/app/src/main/AndroidManifest.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + diff --git a/sharing/android/example/app/src/main/java/com/google/nearby/sharedemo/MainActivity.kt b/sharing/android/example/app/src/main/java/com/google/nearby/sharedemo/MainActivity.kt new file mode 100644 index 00000000..f4b7672e --- /dev/null +++ b/sharing/android/example/app/src/main/java/com/google/nearby/sharedemo/MainActivity.kt @@ -0,0 +1,165 @@ +package com.google.nearby.sharedemo + +import android.app.PendingIntent +import android.content.Intent +import android.net.Uri +import android.os.Bundle +import android.provider.OpenableColumns +import androidx.activity.ComponentActivity +import androidx.activity.compose.rememberLauncherForActivityResult +import androidx.activity.compose.setContent +import androidx.activity.result.contract.ActivityResultContracts +import androidx.activity.viewModels +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.foundation.lazy.grid.items +import androidx.compose.material3.Button +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp +import androidx.compose.ui.viewinterop.AndroidView +import androidx.slice.Slice +import androidx.slice.widget.SliceView +import com.google.nearby.sharedemo.ui.theme.NearbyShareDemoTheme + +class MainActivity : ComponentActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val viewModel: MainViewModel by viewModels(factoryProducer = { MainViewModel.Factory }) + setContent { + NearbyShareDemoTheme { + // A surface container using the 'background' color from the theme + val state by viewModel.targetsFlow.collectAsState() + Column( + modifier = Modifier + .fillMaxSize() + .background(MaterialTheme.colorScheme.background) + ) { + MainView( + state, + onShareTargetClicked = { data, intent -> + viewModel.onShareTargetClicked(data, this@MainActivity, intent) + }) + } + } + } + } +} + +@Composable +fun MainView( + state: SliceState, + onShareTargetClicked: (ShareTargetData, Intent) -> Unit, +) { + when (state) { + is SliceState.PermissionNeeded -> { + AndroidView(factory = { + val view = SliceView(it) + view.slice = state.slice + return@AndroidView view + }) + } + + is SliceState.Active -> { + var uris by rememberSaveable { mutableStateOf(listOf()) } + val launcher = + rememberLauncherForActivityResult(contract = ActivityResultContracts.GetMultipleContents()) { + uris = it + } + Column { + Button(onClick = { launcher.launch("*/*") }) { Text("Select files") } + if (uris.isNotEmpty()) { + for (uri in uris) { + Text( + uri.toString(), + style = MaterialTheme.typography.bodySmall + ) + } + val sendIntent = + Intent("com.google.android.gms.SHARE_NEARBY").apply { + if (uris.size == 1) { + putExtra(Intent.EXTRA_STREAM, uris[0]) + } else { + putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris.toArrayList()) + } + type = "*/*" + flags = Intent.FLAG_GRANT_READ_URI_PERMISSION + } + val context = LocalContext.current + // We need to call sendIntent.migrateExtraStreamToClipData() to show the preview images on + // Android Q and above but the method is hidden. Hence we call PendingIntent.getActivity as + // a proxy/wrapper which calls the above method. This method can throw exception if files + // are too large. + // We need to call sendIntent.migrateExtraStreamToClipData() to show the preview images on + // Android Q and above but the method is hidden. Hence we call PendingIntent.getActivity as + // a proxy/wrapper which calls the above method. This method can throw exception if files + // are too large. + val pendingIntentFlags = PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT + + PendingIntent.getActivity(context.applicationContext, 0, sendIntent, pendingIntentFlags) + ShareDestinations(sendIntent, state.targets, onShareTargetClicked = { data, intent -> + for (uri in uris) { + context.grantUriPermission( + "com.google.android.gms", + uri, + Intent.FLAG_GRANT_READ_URI_PERMISSION + ) + } + onShareTargetClicked(data, intent) + }) + } + } + } + } +} + +@Composable +fun ShareDestinations( + sendIntent: Intent, + targets: Set, + onShareTargetClicked: (ShareTargetData, Intent) -> Unit, +) { + Card( + modifier = Modifier.padding(16.dp), + colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceVariant) + ) { + if (targets.isEmpty()) { + Text("No devices nearby!") + return@Card + } + LazyVerticalGrid(columns = GridCells.Adaptive(minSize = 72.dp)) { + items(targets.toList()) { + ShareTarget(data = it, onShareTargetClicked = { data -> + onShareTargetClicked(data, sendIntent) + }) + } + } + } +} + +private fun List.toArrayList(): java.util.ArrayList { + val list = java.util.ArrayList() + list.addAll(this) + return list +} + +sealed class SliceState { + data class PermissionNeeded(val slice: Slice) : SliceState() + data class Active(val targets: Set) : SliceState() +} diff --git a/sharing/android/example/app/src/main/java/com/google/nearby/sharedemo/MainViewModel.kt b/sharing/android/example/app/src/main/java/com/google/nearby/sharedemo/MainViewModel.kt new file mode 100644 index 00000000..0cd48102 --- /dev/null +++ b/sharing/android/example/app/src/main/java/com/google/nearby/sharedemo/MainViewModel.kt @@ -0,0 +1,123 @@ +package com.google.nearby.sharedemo + +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import android.net.Uri +import androidx.core.graphics.drawable.IconCompat +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.viewmodel.initializer +import androidx.lifecycle.viewmodel.viewModelFactory +import androidx.slice.Slice +import androidx.slice.SliceViewManager +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow + +class MainViewModel(context: Context) : ViewModel() { + private val _targetsFlow: MutableStateFlow = MutableStateFlow(SliceState.Active(setOf())) + val targetsFlow: StateFlow = _targetsFlow.asStateFlow() + + private var targetMapping = mapOf() + + private val sliceManager = SliceViewManager.getInstance(context) + private val sliceCallback: (Slice?) -> Unit = { + targetMapping = parseSlice(it) + if (targetMapping.isEmpty() && it != null) { + _targetsFlow.value = SliceState.PermissionNeeded(it) + } else { + _targetsFlow.value = SliceState.Active(targetMapping.keys) + } + } + + init { + sliceManager.registerSliceCallback(SCAN_SLICE_URI, sliceCallback) + val slice = sliceManager.bindSlice(SCAN_SLICE_URI) + targetMapping = parseSlice(slice) + if (targetMapping.isEmpty() && slice != null) { + _targetsFlow.value = SliceState.PermissionNeeded(slice) + } else { + _targetsFlow.value = SliceState.Active(targetMapping.keys) + } + } + + /** + * This function is run just before the ViewModel is closed, allowing us to unpin the sharing + * slice. + */ + override fun onCleared() { + super.onCleared() + sliceManager.unregisterSliceCallback(SCAN_SLICE_URI, sliceCallback) + } + + /** + * Called when a slice's share target is tapped, as represented by [ShareTarget]. + */ + fun onShareTargetClicked(data: ShareTargetData, context: Context, sendIntent: Intent) { + targetMapping[data]!!.send(context, 0, sendIntent) + } + + private fun parseSlice(slice: Slice?): Map { + android.util.Log.d("NSDemo", "slice: $slice") + if (slice == null) { + return mapOf() + } + val ret = mutableMapOf() + for (targetItem in slice.items.reversed()) { + if (!(targetItem.format == SLICE && targetItem.hints.containsAll(listOf(LIST_ITEM, ACTIVITY)))) { + continue + } + val targetSlice = targetItem.slice + var deviceName: String? = null + var action: PendingIntent? = null + var profileIcon: IconCompat? = null + + for (item in targetSlice.items) { + if (item.format == TEXT && item.hints.contains(TITLE)) { + deviceName = item.text.toString() + } + if (item.format == ACTION && item.hints.containsAll(listOf(SHORTCUT, TITLE))) { + action = item.action + + val iconSlice: Slice? = item.slice + if (iconSlice != null) { + for (iconitem in iconSlice.items) { + if (iconitem.format == IMAGE && iconitem.hints.contains(NO_TINT)) { + profileIcon = iconitem.icon + } + } + } + } + } + // Returns null if the data parsed from the slice is incomplete. + if (deviceName == null || action == null || profileIcon == null) { + continue + } + ret[ShareTargetData(profileIcon, deviceName)] = action + } + return ret + } + + companion object { + private val SCAN_SLICE_URI: Uri = + Uri.parse("content://com.google.android.gms.nearby.sharing/scan") + + // Slice parsing. + private const val SLICE = "slice" + private const val LIST_ITEM = "list_item" + private const val ACTIVITY = "activity" + private const val TEXT = "text" + private const val TITLE = "title" + private const val ACTION = "action" + private const val SHORTCUT = "shortcut" + private const val IMAGE = "image" + private const val NO_TINT = "no_tint" + + val Factory: ViewModelProvider.Factory = viewModelFactory { + initializer { + MainViewModel(this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY]!!) + } + } + } +} diff --git a/sharing/android/example/app/src/main/java/com/google/nearby/sharedemo/ShareTarget.kt b/sharing/android/example/app/src/main/java/com/google/nearby/sharedemo/ShareTarget.kt new file mode 100644 index 00000000..2b3c843f --- /dev/null +++ b/sharing/android/example/app/src/main/java/com/google/nearby/sharedemo/ShareTarget.kt @@ -0,0 +1,43 @@ +package com.google.nearby.sharedemo + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp +import androidx.core.graphics.drawable.IconCompat +import androidx.core.graphics.drawable.toBitmap + +@Composable +fun ShareTarget(data: ShareTargetData, onShareTargetClicked: (ShareTargetData) -> Unit) { + val context = LocalContext.current + Column( + modifier = Modifier + .padding(8.dp) + .clickable { onShareTargetClicked(data) }, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Icon( + data.profileIcon.loadDrawable(context)!!.toBitmap().asImageBitmap(), + contentDescription = null, + tint = Color.Unspecified, + ) + Text( + data.deviceName, + style = MaterialTheme.typography.bodySmall, + ) + } +} + +data class ShareTargetData( + val profileIcon: IconCompat, + val deviceName: String, +) diff --git a/sharing/android/example/app/src/main/java/com/google/nearby/sharedemo/ui/theme/Theme.kt b/sharing/android/example/app/src/main/java/com/google/nearby/sharedemo/ui/theme/Theme.kt new file mode 100644 index 00000000..ced49795 --- /dev/null +++ b/sharing/android/example/app/src/main/java/com/google/nearby/sharedemo/ui/theme/Theme.kt @@ -0,0 +1,51 @@ +package com.google.nearby.sharedemo.ui.theme + +import android.app.Activity +import android.os.Build +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Typography +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.SideEffect +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalView +import androidx.core.view.WindowCompat + +private val DarkColorScheme = darkColorScheme() + +private val LightColorScheme = lightColorScheme() + +@Composable +fun NearbyShareDemoTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + // Dynamic color is available on Android 12+ + dynamicColor: Boolean = true, + content: @Composable () -> Unit +) { + val colorScheme = when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + dynamicLightColorScheme(context) + } + else -> LightColorScheme + } + val view = LocalView.current + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as Activity).window + window.statusBarColor = colorScheme.primary.toArgb() + WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme + } + } + + MaterialTheme( + colorScheme = colorScheme, + typography = Typography(), + content = content + ) +} diff --git a/sharing/android/example/app/src/main/res/drawable/ic_launcher_background.xml b/sharing/android/example/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 00000000..61bb79ed --- /dev/null +++ b/sharing/android/example/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sharing/android/example/app/src/main/res/drawable/ic_launcher_foreground.xml b/sharing/android/example/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 00000000..04d1a347 --- /dev/null +++ b/sharing/android/example/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + diff --git a/sharing/android/example/app/src/main/res/mipmap-anydpi/ic_launcher.xml b/sharing/android/example/app/src/main/res/mipmap-anydpi/ic_launcher.xml new file mode 100644 index 00000000..3fe24419 --- /dev/null +++ b/sharing/android/example/app/src/main/res/mipmap-anydpi/ic_launcher.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/sharing/android/example/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml b/sharing/android/example/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml new file mode 100644 index 00000000..3fe24419 --- /dev/null +++ b/sharing/android/example/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/sharing/android/example/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/sharing/android/example/app/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..c209e78ecd372343283f4157dcfd918ec5165bb3 GIT binary patch literal 1404 zcmV-?1%vuhNk&F=1pok7MM6+kP&il$0000G0000-002h-06|PpNX!5L00Dqw+t%{r zzW2vH!KF=w&cMnnN@{whkTw+#mAh0SV?YL=)3MimFYCWp#fpdtz~8$hD5VPuQgtcN zXl<@<#Cme5f5yr2h%@8TWh?)bSK`O z^Z@d={gn7J{iyxL_y_%J|L>ep{dUxUP8a{byupH&!UNR*OutO~0{*T4q5R6@ApLF! z5{w?Z150gC7#>(VHFJZ-^6O@PYp{t!jH(_Z*nzTK4 zkc{fLE4Q3|mA2`CWQ3{8;gxGizgM!zccbdQoOLZc8hThi-IhN90RFT|zlxh3Ty&VG z?Fe{#9RrRnxzsu|Lg2ddugg7k%>0JeD+{XZ7>Z~{=|M+sh1MF7~ zz>To~`~LVQe1nNoR-gEzkpe{Ak^7{{ZBk2i_<+`Bq<^GB!RYG+z)h;Y3+<{zlMUYd zrd*W4w&jZ0%kBuDZ1EW&KLpyR7r2=}fF2%0VwHM4pUs}ZI2egi#DRMYZPek*^H9YK zay4Iy3WXFG(F14xYsoDA|KXgGc5%2DhmQ1gFCkrgHBm!lXG8I5h*uf{rn48Z!_@ z4Bk6TJAB2CKYqPjiX&mWoW>OPFGd$wqroa($ne7EUK;#3VYkXaew%Kh^3OrMhtjYN?XEoY`tRPQsAkH-DSL^QqyN0>^ zmC>{#F14jz4GeW{pJoRpLFa_*GI{?T93^rX7SPQgT@LbLqpNA}<@2wH;q493)G=1Y z#-sCiRNX~qf3KgiFzB3I>4Z%AfS(3$`-aMIBU+6?gbgDb!)L~A)je+;fR0jWLL-Fu z4)P{c7{B4Hp91&%??2$v9iRSFnuckHUm}or9seH6 z>%NbT+5*@L5(I9j@06@(!{ZI?U0=pKn8uwIg&L{JV14+8s2hnvbRrU|hZCd}IJu7*;;ECgO%8_*W Kmw_-CKmY()leWbG literal 0 HcmV?d00001 diff --git a/sharing/android/example/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/sharing/android/example/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..b2dfe3d1ba5cf3ee31b3ecc1ced89044a1f3b7a9 GIT binary patch literal 2898 zcmV-Y3$650Nk&FW3jhFDMM6+kP&il$0000G0000-002h-06|PpNWB9900E$G+qN-D z+81ABX7q?;bwx%xBg?kcwr$(C-Tex-ZCkHUw(Y9#+`E5-zuONG5fgw~E2WDng@Bc@ z24xy+R1n%~6xI#u9vJ8zREI)sb<&Il(016}Z~V1n^PU3-_H17A*Bf^o)&{_uBv}Py zulRfeE8g(g6HFhk_?o_;0@tz?1I+l+Y#Q*;RVC?(ud`_cU-~n|AX-b`JHrOIqn(-t&rOg-o`#C zh0LPxmbOAEb;zHTu!R3LDh1QO zZTf-|lJNUxi-PpcbRjw3n~n-pG;$+dIF6eqM5+L();B2O2tQ~|p{PlpNcvDbd1l%c zLtXn%lu(3!aNK!V#+HNn_D3lp z2%l+hK-nsj|Bi9;V*WIcQRTt5j90A<=am+cc`J zTYIN|PsYAhJ|=&h*4wI4ebv-C=Be#u>}%m;a{IGmJDU`0snWS&$9zdrT(z8#{OZ_Y zxwJx!ZClUi%YJjD6Xz@OP8{ieyJB=tn?>zaI-4JN;rr`JQbb%y5h2O-?_V@7pG_+y z(lqAsqYr!NyVb0C^|uclHaeecG)Sz;WV?rtoqOdAAN{j%?Uo%owya(F&qps@Id|Of zo@~Y-(YmfB+chv^%*3g4k3R0WqvuYUIA+8^SGJ{2Bl$X&X&v02>+0$4?di(34{pt* zG=f#yMs@Y|b&=HyH3k4yP&goF2LJ#tBLJNNDo6lG06r}ghC-pC4Q*=x3;|+W04zte zAl>l4kzUBQFYF(E`KJy?ZXd1tnfbH+Z~SMmA21KokJNs#eqcXWKUIC>{TuoKe^vhF z);H)o`t9j~`$h1D`#bxe@E`oE`cM9w(@)5Bp8BNukIwM>wZHfd0S;5bcXA*5KT3bj zc&_~`&{z7u{Et!Z_k78H75gXf4g8<_ul!H$eVspPeU3j&&Au=2R*Zp#M9$9s;fqwgzfiX=E_?BwVcfx3tG9Q-+<5fw z%Hs64z)@Q*%s3_Xd5>S4dg$s>@rN^ixeVj*tqu3ZV)biDcFf&l?lGwsa zWj3rvK}?43c{IruV2L`hUU0t^MemAn3U~x3$4mFDxj=Byowu^Q+#wKRPrWywLjIAp z9*n}eQ9-gZmnd9Y0WHtwi2sn6n~?i#n9VN1B*074_VbZZ=WrpkMYr{RsI ztM_8X1)J*DZejxkjOTRJ&a*lrvMKBQURNP#K)a5wIitfu(CFYV4FT?LUB$jVwJSZz zNBFTWg->Yk0j&h3e*a5>B=-xM7dE`IuOQna!u$OoxLlE;WdrNlN)1 z7**de7-hZ!(%_ZllHBLg`Ir#|t>2$*xVOZ-ADZKTN?{(NUeLU9GbuG-+Axf*AZ-P1 z0ZZ*fx+ck4{XtFsbcc%GRStht@q!m*ImssGwuK+P@%gEK!f5dHymg<9nSCXsB6 zQ*{<`%^bxB($Z@5286^-A(tR;r+p7B%^%$N5h%lb*Vlz-?DL9x;!j<5>~kmXP$E}m zQV|7uv4SwFs0jUervsxVUm>&9Y3DBIzc1XW|CUZrUdb<&{@D5yuLe%Xniw^x&{A2s z0q1+owDSfc3Gs?ht;3jw49c#mmrViUfX-yvc_B*wY|Lo7; zGh!t2R#BHx{1wFXReX*~`NS-LpSX z#TV*miO^~B9PF%O0huw!1Zv>^d0G3$^8dsC6VI!$oKDKiXdJt{mGkyA`+Gwd4D-^1qtNTUK)`N*=NTG-6}=5k6suNfdLt*dt8D| z%H#$k)z#ZRcf|zDWB|pn<3+7Nz>?WW9WdkO5(a^m+D4WRJ9{wc>Y}IN)2Kbgn;_O? zGqdr&9~|$Y0tP=N(k7^Eu;iO*w+f%W`20BNo)=Xa@M_)+o$4LXJyiw{F?a633SC{B zl~9FH%?^Rm*LVz`lkULs)%idDX^O)SxQol(3jDRyBVR!7d`;ar+D7do)jQ}m`g$TevUD5@?*P8)voa?kEe@_hl{_h8j&5eB-5FrYW&*FHVt$ z$kRF9Nstj%KRzpjdd_9wO=4zO8ritN*NPk_9avYrsF(!4))tm{Ga#OY z(r{0buexOzu7+rw8E08Gxd`LTOID{*AC1m*6Nw@osfB%0oBF5sf<~wH1kL;sd zo)k6^VyRFU`)dt*iX^9&QtWbo6yE8XXH?`ztvpiOLgI3R+=MOBQ9=rMVgi<*CU%+d1PQQ0a1U=&b0vkF207%xU0ssI2 literal 0 HcmV?d00001 diff --git a/sharing/android/example/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/sharing/android/example/app/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..4f0f1d64e58ba64d180ce43ee13bf9a17835fbca GIT binary patch literal 982 zcmV;{11bDcNk&G_0{{S5MM6+kP&il$0000G0000l001ul06|PpNU8t;00Dqo+t#w^ z^1csucXz7-Qrhzl9HuHB%l>&>1tG2^vb*E&k^T3$FG1eQZ51g$uv4V+kI`0<^1Z@N zk?Jjh$olyC%l>)Xq;7!>{iBj&BjJ`P&$fsCfpve_epJOBkTF?nu-B7D!hO=2ZR}

C%4 zc_9eOXvPbC4kzU8YowIA8cW~Uv|eB&yYwAObSwL2vY~UYI7NXPvf3b+c^?wcs~_t{ ze_m66-0)^{JdOMKPwjpQ@Sna!*?$wTZ~su*tNv7o!gXT!GRgivP}ec?5>l1!7<(rT zds|8x(qGc673zrvYIz;J23FG{9nHMnAuP}NpAED^laz3mAN1sy+NXK)!6v1FxQ;lh zOBLA>$~P3r4b*NcqR;y6pwyhZ3_PiDb|%n1gGjl3ZU}ujInlP{eks-#oA6>rh&g+!f`hv#_%JrgYPu z(U^&XLW^QX7F9Z*SRPpQl{B%x)_AMp^}_v~?j7 zapvHMKxSf*Mtyx8I}-<*UGn3)oHd(nn=)BZ`d$lDBwq_GL($_TPaS{UeevT(AJ`p0 z9%+hQb6z)U9qjbuXjg|dExCLjpS8$VKQ55VsIC%@{N5t{NsW)=hNGI`J=x97_kbz@ E0Of=7!TQj4N+cqN`nQhxvX7dAV-`K|Ub$-q+H-5I?Tx0g9jWxd@A|?POE8`3b8fO$T))xP* z(X?&brZw({`)WU&rdAs1iTa0x6F@PIxJ&&L|dpySV!ID|iUhjCcKz(@mE z!x@~W#3H<)4Ae(4eQJRk`Iz3<1)6^m)0b_4_TRZ+cz#eD3f8V;2r-1fE!F}W zEi0MEkTTx}8i1{`l_6vo0(Vuh0HD$I4SjZ=?^?k82R51bC)2D_{y8mi_?X^=U?2|F{Vr7s!k(AZC$O#ZMyavHhlQ7 zUR~QXuH~#o#>(b$u4?s~HLF*3IcF7023AlwAYudn0FV~|odGH^05AYPEfR)8p`i{n zwg3zPVp{+wOsxKc>)(pMupKF!Y2HoUqQ3|Yu|8lwR=?5zZuhG6J?H`bSNk_wPoM{u zSL{c@pY7+c2kck>`^q1^^gR0QB7Y?KUD{vz-uVX~;V-rW)PDcI)$_UjgVV?S?=oLR zf4}zz{#*R_{LkiJ#0RdQLNC^2Vp%JPEUvG9ra2BVZ92(p9h7Ka@!yf9(lj#}>+|u* z;^_?KWdzkM`6gqPo9;;r6&JEa)}R3X{(CWv?NvgLeOTq$cZXqf7|sPImi-7cS8DCN zGf;DVt3Am`>hH3{4-WzH43Ftx)SofNe^-#|0HdCo<+8Qs!}TZP{HH8~z5n`ExcHuT zDL1m&|DVpIy=xsLO>8k92HcmfSKhflQ0H~9=^-{#!I1g(;+44xw~=* zxvNz35vfsQE)@)Zsp*6_GjYD};Squ83<_?^SbALb{a`j<0Gn%6JY!zhp=Fg}Ga2|8 z52e1WU%^L1}15Ex0fF$e@eCT(()_P zvV?CA%#Sy08_U6VPt4EtmVQraWJX` zh=N|WQ>LgrvF~R&qOfB$!%D3cGv?;Xh_z$z7k&s4N)$WYf*k=|*jCEkO19{h_(%W4 zPuOqbCw`SeAX*R}UUsbVsgtuG?xs(#Ikx9`JZoQFz0n*7ZG@Fv@kZk`gzO$HoA9kN z8U5{-yY zvV{`&WKU2$mZeoBmiJrEdzUZAv1sRxpePdg1)F*X^Y)zp^Y*R;;z~vOv-z&)&G)JQ{m!C9cmziu1^nHA z`#`0c>@PnQ9CJKgC5NjJD8HM3|KC(g5nnCq$n0Gsu_DXk36@ql%npEye|?%RmG)

FJ$wK}0tWNB{uH;AM~i literal 0 HcmV?d00001 diff --git a/sharing/android/example/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/sharing/android/example/app/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..948a3070fe34c611c42c0d3ad3013a0dce358be0 GIT binary patch literal 1900 zcmV-y2b1_xNk&Fw2LJ$9MM6+kP&il$0000G0001A003VA06|PpNH75a00DqwTbm-~ zullQTcXxO9ki!OCRx^i?oR|n!<8G0=kI^!JSjFi-LL*`V;ET0H2IXfU0*i>o6o6Gy zRq6Ap5(_{XLdXcL-MzlN`ugSdZY_`jXhcENAu)N_0?GhF))9R;E`!bo9p?g?SRgw_ zEXHhFG$0{qYOqhdX<(wE4N@es3VIo$%il%6xP9gjiBri+2pI6aY4 zJbgh-Ud|V%3O!IcHKQx1FQH(_*TK;1>FQWbt^$K1zNn^cczkBs=QHCYZ8b&l!UV{K z{L0$KCf_&KR^}&2Fe|L&?1I7~pBENnCtCuH3sjcx6$c zwqkNkru);ie``q+_QI;IYLD9OV0ZxkuyBz|5<$1BH|vtey$> z5oto4=l-R-Aaq`Dk0}o9N0VrkqW_#;!u{!bJLDq%0092{Ghe=F;(kn} z+sQ@1=UlX30+2nWjkL$B^b!H2^QYO@iFc0{(-~yXj2TWz?VG{v`Jg zg}WyYnwGgn>{HFaG7E~pt=)sOO}*yd(UU-D(E&x{xKEl6OcU?pl)K%#U$dn1mDF19 zSw@l8G!GNFB3c3VVK0?uyqN&utT-D5%NM4g-3@Sii9tSXKtwce~uF zS&Jn746EW^wV~8zdQ1XC28~kXu8+Yo9p!<8h&(Q({J*4DBglPdpe4M_mD8AguZFn~ ztiuO~{6Bx?SfO~_ZV(GIboeR9~hAym{{fV|VM=77MxDrbW6`ujX z<3HF(>Zr;#*uCvC*bpoSr~C$h?_%nXps@A)=l_;({Fo#6Y1+Zv`!T5HB+)#^-Ud_; zBwftPN=d8Vx)*O1Mj+0oO=mZ+NVH*ptNDC-&zZ7Hwho6UQ#l-yNvc0Cm+2$$6YUk2D2t#vdZX-u3>-Be1u9gtTBiMB^xwWQ_rgvGpZ6(C@e23c!^K=>ai-Rqu zhqT`ZQof;9Bu!AD(i^PCbYV%yha9zuoKMp`U^z;3!+&d@Hud&_iy!O-$b9ZLcSRh? z)R|826w}TU!J#X6P%@Zh=La$I6zXa#h!B;{qfug}O%z@K{EZECu6zl)7CiNi%xti0 zB{OKfAj83~iJvmpTU|&q1^?^cIMn2RQ?jeSB95l}{DrEPTW{_gmU_pqTc)h@4T>~& zluq3)GM=xa(#^VU5}@FNqpc$?#SbVsX!~RH*5p0p@w z;~v{QMX0^bFT1!cXGM8K9FP+=9~-d~#TK#ZE{4umGT=;dfvWi?rYj;^l_Zxywze`W z^Cr{55U@*BalS}K%Czii_80e0#0#Zkhlij4-~I@}`-JFJ7$5{>LnoJSs??J8kWVl6|8A}RCGAu9^rAsfCE=2}tHwl93t0C?#+jMpvr7O3`2=tr{Hg$=HlnjVG^ewm|Js0J*kfPa6*GhtB>`fN!m#9J(sU!?(OSfzY*zS(FJ<-Vb zfAIg+`U)YaXv#sY(c--|X zEB+TVyZ%Ie4L$gi#Fc++`h6%vzsS$pjz9aLt+ZL(g;n$Dzy5=m=_TV(3H8^C{r0xd zp#a%}ht55dOq?yhwYPrtp-m1xXp;4X;)NhxxUpgP%XTLmO zcjaFva^}dP3$&sfFTIR_jC=2pHh9kpI@2(6V*GQo7Ws)`j)hd+tr@P~gR*2gO@+1? zG<`_tB+LJuF|SZ9tIec;h%}}6WClT`L>HSW?E{Hp1h^+mlbf_$9zA>!ug>NALJsO{ mU%z=YwVD?}XMya)Bp;vlyE5&E_6!fzx9pwrdz474!~g(M6R?N? literal 0 HcmV?d00001 diff --git a/sharing/android/example/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/sharing/android/example/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..1b9a6956b3acdc11f40ce2bb3f6efbd845cc243f GIT binary patch literal 3918 zcmV-U53%r4Nk&FS4*&pHMM6+kP&il$0000G0001A003VA06|PpNSy@$00HoY|G(*G z+qV7x14$dSO^Re!iqt-AAIE9iwr$(CZQJL$blA4B`>;C3fBY6Q8_YSjb2%a=fc}4E zrSzssacq<^nmW|Rs93PJni30R<8w<(bK_$LO4L?!_OxLl$}K$MUEllnMK|rg=f3;y z*?;3j|Nh>)p0JQ3A~rf(MibH2r+)3cyV1qF&;8m{w-S*y+0mM){KTK^M5}ksc`qX3 zy>rf^b>~l>SSHds8(I@hz3&PD@LmEs4&prkT=BjsBCXTMhN$_)+kvnl0bLKW5rEsj z*d#KXGDB4P&>etx0X+`R19yC=LS)j!mgs5M0L~+o-T~Jl!p!AJxnGAhV%~rhYUL4hlWhgES3Kb5oA&X z{}?3OBSS-{!v$nCIGj->(-TAG)8LR{htr41^gxsT8yqt2@DEG6Yl`Uma3Nd4;YUoW zTbkYl3CMU5ypMF3EIkYmWL|*BknM`0+Kq6CpvO(y$#j94e+q{vI{Zp8cV_6RK!`&C zob$*5Q|$IZ09dW=L!V zw@#2wviu|<#3lgGE8GEhcx+zBt`} zOwP8j9X%^f7i_bth4PiJ$LYtFJSCN$3xwDN;8mr*B;CJwBP2G0TMq0uNt7S^DO_wE zepk!Wrn#Z#03j{`c*Rf~y3o7?J}w?tEELRUR2cgxB*Y{LzA#pxHgf}q?u5idu>077 zd^=p)`nA}6e`|@`p?u}YU66PP_MA}Zqqe!c{nK&z%Jwq1N4e_q<#4g^xaz=ao;u|6 zwpRcW2Lax=ZGbx=Q*HhlJ`Ns#Y*r0*%!T?P*TTiX;rb)$CGLz=rSUum$)3Qyv{BL2 zO*=OI2|%(Yz~`pNEOnLp>+?T@glq-DujlIp?hdJeZ7ctP4_OKx|5@EOps3rr(pWzg zK4d3&oN-X2qN(d_MkfwB4I)_)!I_6nj2iA9u^pQ{;GckGLxBGrJUM2Wdda!k)Y>lq zmjws>dVQ*vW9lvEMkiN3wE-__6OWD0txS&Qn0n22cyj4Q*8(nG4!G{6OOwNvsrPIL zCl-$W9UwkEUVuLwyD%|inbOF*xMODZ4VMEVAq_zUxZ+K#Gdqf!DW$5f)?7UNOFMz! zrB~tuu=6X2FE(p^iqgxr+?ZK;=yz`e;C$#_@D9Lj-+TDVOrva>(#*PVbaHO>A)mhl z07OJWCqYC60518$!&c`eNBcBW%GnfaQ*$eazV^2_AW?j)h;J1nUjN(I9=0+!RVx~% z3@Tf!P0TE+98jA?WceK-}A1% zW!K)lyKcGqy#M~})315-A#2NXQ`?6NR#Apo=S!oF=JfpX>iR*49ec{7AN$xxpK{D$ z2d%Fz&rdfSqourN$~Y^NFIMV1CZ?J*bMx~H3k&meGtH@q9ra2vZxmA$S(#jaaj-g4 ztJmxG+DLV<*q<|sDXPp$X>E)#S}Vm&sRaO5P&goh2><}FEdZSXDqsL$06sAkh(e+v zAsBhKSRexgwg6tIy~GFJzaTxXD(}|+0eOwFDA%rn`X;MVwDHT9=4=g%OaJ9s%3b9>9EUTnnp0t;2Zpa{*>mk~hZqItE_!dQ zOtC>8`$l|mV43Jbudf0N6&&X;{=z}Zi}d1`2qmJ}i|0*GsulD3>GgQXHN)pkR6sf1 z?5ZU%&xtL}oH;YiAA)d*^Ndw2T$+Mjuzyzz@-SM`9df7LqTxLuIwC~S0092~+=qYv z@*ja;?Wt!T!{U?c*Z0YtGe)XbI&y-?B&G2$`JDM)(dIV9G`Sc#6?sI60de6kv+)Qb zUW~2|WjvJq3TA8`0+sWA3zRhY9a~ow)O~&StBkG2{*{TGiY~S8ep{V&Vo2l<6LWsu z^#p0-v*t2?3&aA1)ozu|%efSR=XnpX$lvTeRdKlvM!@|pM5p2w3u-6 zU>}t2xiYLS+{|%C65AzX+23Mtlq?BS&YdYcYsVjoiE&rT>;Necn6l^K)T^lmE`5u{ zm1i+-a-gc;Z&v-{;8r)z6NYfBUv+=_L}ef}qa9FX01)+Aaf+;xj(mL6|JUzGJR1|fnanb%?BPPIp>SCjP|8qE5qJ{=n5ZGw?81z3(k;pzH%1CtlX50{E7h)$h{qGKfzC`e2o`*IqA#tjA z`Fz&^%$b9F*N`)U-#6>a)Z`55`$Dd0cfcs0$d13^ONrdCu9xcv_=n#WQo8stcz3jP9|2EvdI-RhJM3%Q%oM&!OlShM|0 z?gz?wHZSnm45njLtsz8PVT1S&jAlbKg5kVam$p16=EK@Sj4EP0OtH zmJDmdc^v)x>56Qg_wmYHz6h)>kl_h$>0@J!ypv%APmjZTAQVLy6Fu50RGY&JAVNhx zrF_qG6`x9MkT;1SFWo$)l{M$;3qUDn9JwE}z zRl#E_bDRJFii61kPgBybIgp8dNW!Cc1b*^YYk-#oWLJvtM_v^hQx~9?8LD4VFFxBF z3MlrsSC%f9Oupn*ctPL0U1fwfX?`tRhPD{PSLFPQOmIt$mDy0SgpNVvHS+f#Do>h1Gn?LZU9(KaN>Q_=Y*_T zvtD7%_u^^+{g`0VGzg(VZrpVQ6Ub5M=tI_p7T93R8@3Zulu3|#{iNcu!oiHxZ4Rf*( zfmiN$$ru(*_Zqn=`Gq#OuHRTSwp7uH_SokR&|)RuW5yo=Z|_4?qU-JU+tpt>!B&Is z@N(=SG;bpVc;AO@zbmMM zScqq1)b-ZQIrs={oD}|?6y{$HNB1U0^LsBh8JI&3!GBZxOXI<}&5-$lgkAaYqhOTb z?2vEnZ$-kk;*M_17(upJF3%+iH*s0-r{vttXVB2OUwI1s^+G(Ft(U8gYFXC}#P&E^ z>T@C^tS`Z7{6HT4_nF~n>JlZtk5&qDBl6r|^kzQYe`wq!C)n@$c>WOPA61NDFj<<6 zGW71NMMhwAl!U-yqrq2xrSFqRCI8acw7?}3j;ynxo*-b7Co;g5r%^j=H@9({PXXBf z@r>U>>N;E)81wx`B4f%{PB~MHka_);%kBCb(d|Jy5!MqJ%2p`t&@L)4$T2j&-WHvG zv3(uyA_gwqNu(k?jQTtv3dgPKRZoH8prxe7>pQBW5L&dpumS&5Ld2?(sCpJjvc4L5 zEnh&?91WVm)ZdTj=fjJ$pPDdgAttLXuke+?KdKxu*;kTC(r!tQk6;gxj4h%FdHAt(^M3YvYj(!tOeN)+Hvj6+< zzyJRG?^lZfWuR#t!tUKP&(?%3v&Zd$R2YN>lB(Lq`OInY48%4%yTv2 zYe1{G`3)(PDEio5Y@-I5tUf`c%%OCJMtSW56g3iEg%3`$7XSJJHyA z<|7&N)5Xrlgv~%BO24eFd;Hd;uiK%D`EdK|quUeRZDqbh9l)%j%J#0lfrZumvA<_w zu&=AVvdChf6}eqh(bUz`(`Ue*p01{fBAcTgKyDYLs_I+YyJEk+rM@avU~>fB$n)HS zM7pfJydu`i%gfS<{PF94kZDv$t>06sAkheDzu40NJ$5CMW%n^Lls?8^p^QGWURbKu3ZduZQZ((s2? zzE`}<{;Zt7<$C|9R8A~DJ~@%x>TfP zF>TX8)@v|t)q4GjRt<}5s6hLHwRel7>V@&r-O|Av(yh;Q1A{E>Ir>p+%dHD|=l+lT zpr(Dg&>#Nu=!)6bCLr-ZS%|;h)Ij$+e@r8_{qO19QvDe=&1tmpY*0lcA^Cc-#{9fQ z<~$*<&P$Q<_jy#<$40PMofM7aQ}C=jphI`4kLg}Z7CIN#26D{-4v-_CA-LiE@(%{y!BzsU%gG`Q?sjLUf%qFSl0y)2#ae*+EI>s|i`d^V$Dn)qmzqRq6VJRY|{4ujsIU%#bnqU6MR&-1I_43=|5(6Jr;Jvert) zE?S|Tmn}Tv<-??sxV5@9t}3D=>YZ0JrQe$CO~|EY=Lj9RM&4svQHPQL6%pV5fPFiH zfXDx;l@~et{*{U*#c#Dvzu)|znDO7$#CRx)Z&yp-}SrD{&|(MQtfUz~n35@RLfUy=aqrhCX0M}J_r5QsK~NmRCR|Nm&L z41UdsLjWxSUlL41r^0K&nCCK>fdR-!MYjFg(z9_mF^C|#ZQw?`)f6uVzF^`bRnVY& zo}@M06J&_+>w9@jpaO4snmU;0t-(zYW1qVBHtuD!d?%?AtN7Plp><-1Y8Rqb20ZaP zTCgn*-Sri4Q8Xn>=gNaWQ57%!D35UkA@ksOlPB*Dvw}t02ENAqw|kFhn%ZyyW%+t{ zNdM!uqEM^;2}f+tECHbwLmH*!nZVrb$-az%t50Y2pg(HqhvY-^-lb}>^6l{$jOI6} zo_kBzj%8aX|6H5M0Y<)7pzz_wLkIpRm!;PzY)9+24wk2&TT{w--phDGDCOz{cN_ca zpnm7`$oDy=HX%0i-`769*0M6(e5j-?(?24%)<)&46y0e&6@HCDZAm9W6Ib#Y#BF6- z=30crHGg+RRTe%VBC>T00OV6F+gQDAK38Ne3N9bm|62tPccBJi)5{B z4zc^Db72XiBd}v$CF|yU{Z=M|DZ%-(XarYNclODlb1Kz1_EKLy(NSLCN`eUl(rBCL zT*jx@wNvze0|TSqgE(QArOZU)_?qH(sj#TwzElLs9q)(0u!_P|R%Cy_0JFQxgGV>1 zz4?_uq<8_gM0`c*Hh|;UMz~vrg1gQXp{ufg`hM_qU;U>+zmvc5blCLSq@PrEBSGR# z&8=2Z4uXN`F3p73ueD1l{s{k$WipAvSh5W7ABe?4)t;r@V?y`bNB5FvBuE|0VRTb< zM1Hn^?DSsJY+sX@T5xW=#>T9VEV|?<(=6|ge$X6Sb05!LFdjDcoq*gM(Zq=t;_)Le&jyt(&9jzR73noru`a# zN*<`KwGa^gZU3-)MSLF0aFag#f0<>E(bYTeHmtdbns#|I)-$)mJ`q9ctQ8g0=ET?| zdO}eZ*b_p>ygRTtR^5Ggdam=Zb5wmd{}np+Jn1d_=M`~P=M67jj})fH4ztb5yQqQW z^C|C&^LHAK-u+ooIK)yM)QM?t;|<{P;;{`p=BclzAN#JzL4jCwXkQB1Dy{=^KR`=~ zTrr)y7eiYBzSNs_DvO=4A6#EgGS-zY%Vi)N*Yb`U;6o}KR}dq{r9pT5wqZ@3NOE8- z9-(}D|Nc5732CSYQbL)!gPQ#RbD8BhK3dl{sUuPvei0tkvnJBxDEAYTesU8H$)g(Plra{VH(v3u^CO1~(+ zU0O7#)jaS4{NcwA+LuSm&VBcX2#Im3xg)W}ySNw%->orn1taZ&+d)}8gJTqA!u|5P z{yv?zol_3|(1(%M(EVU=cp?L`{Pi|ixk{U)*guFML3P!OSlz;zGA#T+E@8@cgQ_mv1o7RSU=Zo_82F?&&2r;WE z@wk}JHYEZ9nYUc(Vv~iTCa3u8e4q(yq<29VoNbKk|`mq%I6u)My=gPIDuUb&lzf4`MEA9^g8u z)vp8|$$HE9m_BTV?lOosIGa4jud=jIbw)O2eCMfyw2*S8?hjWw^nqws$O*M$3I1)x zR0PWFb3$ySOcGTe1dz%N0l;RPc`x%05FtT^f^j{YCP}*Q=lvp4$ZXrTZQHhO+w%wJn3c8j%+5C3UAFD&%8dBl_qi9D5g8fry}6Ev z2_Q~)5^N$!IU`BPh1O|=BxQ#*C5*}`lluC515$lxc-vNC)IgW=K|=z7o%cWFpndn= zX}f{`!VK02_kU+Q5a3m37J;c} zTzbxteE{GNf?yLt5X=Bzc-mio^Up0nunMCgp*ZJ;%MJvPM3QK)BryP(_v@ei4UvHr z6+sbCifQaOkL6-;5fL8$W($zZ_;CZp305C;~$hhRquZr-r)jjd1z z31%ZK{-(`P#|Um_Sivn@p$-vz46uqT>QG0B1w9znfS9A8PB2LaHdzA|_)yjXVR*l{ zkcu3@vEf7bxH0nkh`q?8FmoO_Ucui*>_a~P?qQrlZ9@+D7%MTpSnztpylXrt5!-k8_QPB?YL8Kx_On8WD zgT+111d(Op$^$&KLAN5+@?>f7F4~wFi(8TL8+szgVmcMDTp5l&k6~=rA{Dt}!gb^r zSWY<)M7D|Z2P0cEodj6E42PV>&>DFmQpgt)E-|#sSUU@uKed+F680H@<;-x{p|nuH4!_mn85rx>wz;0mPi2ZkL#k6;sznu?cXh!T0S>{w6 zL^gvR05NY64l*<+_L>On$rjx9!US;l;LX6@z}yi#2XHh)F@Oo+l)h%fq$v}DNmF2> zfs^_t0)3N-W<9-N?uedVv{)-J0W5mh#29QM5R5h&KuiRM=0Zvnf#lF=K#WlCgc#9c zS;qvh(P$!_a8JwyhI^ZJV2k+B6Z^64?w|1?5gyo6y{}923CRZfYVe1#?F% z7h2SUiNO3;T#JUOyovSs@@C1GtwipycA=*x5{BpIZ_#GCMuV8XK=x;qCNy{d7?wA~ zC+=vjls;ci&zW=6$H~4^K%v{p}Ab?U%C6Z4p%eC<3ExqU$XR<}LLF67A$Sr20DR_pJ3yeBa~ z^sw{V0FI5;UpwXsScYuhbqGQ`YQ25;6p6W^+tgL&;Ml;>S3CGpSZ>VrTn0m1$y$HU z&65)I!c?oREz};c=nLCliriqQX->4uivHTgd${GqeAlf*!P^B|jkU|*IdNP(&6C>4 zqOW$)Nw9nvjy^&`?E|gotDV{JmJ9Q~vuhy<`^C4XIUDt|j4o6rK^e8_(=YqC zuaR6TRVf@tUFHB079o4MBIh{M~4>WwnGgesQH*3?w(RA%hCZ*7)b!aNV=yOQ%o_Y=Lt0Sl*(9^jfRnC210Om$=y>*o|3z} zAR&vAdrB#mWoaB0fJSw9xw|Am$fzK>rx-~R#7IFSAwdu_EI|SRfB*yl0w8oX09H^q zAjl2?0I)v*odGJ40FVGaF&2qJq9Gv`>V>2r0|c`GX8h>CX8eHcOy>S0@<;M3<_6UM z7yCEpug5NZL!H_0>Hg_HasQGxR`rY&Z{geOy?N92Z z{lER^um|$*?*G63*njwc(R?NT)Bei*3jVzR>FWUDb^gKhtL4A=kE_1p-%Fo2`!8M} z(0AjuCiS;G{?*^1tB-uY%=)SRx&D)pK4u@>f6@KPe3}2j_har$>HqzH;UCR^ssFD0 z7h+VLO4o@_Yt>>AeaZKUxqyvxWCAjKB>qjQ30UA)#w z&=RmdwlT`7a8J8Yae=7*c8XL|{@%wA8uvCqfsNX^?UZsS>wX}QD{K}ad4y~iO*p%4 z_cS{u7Ek%?WV6em2(U9#d8(&JDirb^u~7wK4+xP$iiI6IlD|a&S)6o=kG;59N|>K1 zn(0mUqbG3YIY7dQd+*4~)`!S9m7H6HP6YcKHhBc#b%1L}VIisp%;TckEkcu0>lo@u995$<*Em;XNodjTiCdC%R+TX|_ZR#|1`RR|`^@Teh zl#w@8fI1FTx2Dy+{blUT{`^kY*V-AZUd?ZZqCS4gW(kY5?retkLbF=>p=59Nl|=sf zo1Pc|{{N4>5nt#627ylGF`3n>X%`w%bw-Y~zWM_{Si$dc82|=YhISal{N7OY?O`C4 zD|qb}6nLWJ`hUyL+E>-;ricg9J@ZNYP(x(Sct&OI$Y!QWr*=^VN;G3#i>^1n4e#Je zOVhbFbLpXVu*16enDM+ic;97@R~u&kh__kgP#!R`*rQEnA+_dLkNP~L`0alC|J;c; zeiK=s8;BsLE)KbG3BD&Br@(Ha@SBT&$?xX`=$;eeel=|R_dIr6-Ro?=HEjnsJ_b`1 zK6Yg^-6;^2aW!xeTK)A~3Rm|L^FCHB_I>jIju7ZGo&N_1*QHkxH2!!%@o4iZ?vntS;&zJdPe1dH#04YD93A44o-MpfD zP{rn_aq>U%RDvC2+bp;xPlsOzauIi3*Lf42`jVKKZCRuKdYhi>FDuL2l=v{$BCN#Q6796s%r-AG$Q^t(3c@ zD?w0UhYr11@feiyl9kY_@H8~|xlmO<8PfQmj1!$@WieW@VxR@Psxfe-v9WCi1+f>F4VL?0O~K7T?m4-u|pSkBpUJZZe*16_wAp zSYZ@;k`3;W3UHKUWc8QeI}0jH5Ly=cGWQPw(Kr2fm=-5L(d`lcXofy8tJY3@Tuadz zYWXR{mW7XT!RF#RVCe%}=tM*O6!AD3^(!8un~opNI%Uko7$5t@<8+?; zTxDys(MyyGsUjtSu9$+|_-t!U3fVb1dkK?l`17<+jfl=hrBHnDSV>^R1=TnQeyqbW z>ov#l%!1|S!1>8UUxIdhQq`_klcHVx0{?#>K3#$4GlXncwldt!g17TcvKq-jo_996 z>oA=tH9CqRl6Yw?Uc`am!V?lHJbizOJaVaScf1UP5e7Dbgabq=b!B~T&_F6?ooU>w%x0A zH~&MHJ=q`fCH{U<7MDXE4SD32cDZA)WJeWkllJ`UspWaS#eDe^kg^oU_A14UE9zG-a^g{xaXf$})Wik>gT zl#dkzGr(;h0JZDuFn(+k8wNq?PZ5grQ<+sM?wBGt@JnH6v0#or-5wBQWKU~(S_> zkE!tc*ZJ1Y&*p(xX84POb3cClRMd!^qJ#CAZfIepEj-<`VURS_yCz0(?*Ixcj4 z-!zV1_QZhpm=0<;*(nm+F>T=)o?ep@CK5I%g^VAA+RB25ab?7)A~z~egru=I1S|@v zH7tXV!0wmGS^qj#e+MY;C5eUjEAp$Y?LDkS^QPZ}8WN85?r$u<-Epi;yZ1|J2J`se z$D6DpH~2F=eI0B&=UFAUnJvZAmClJlK)sutJ?M>xpZiWV&0=G4MZP+x+p>EX=HbCz zxls%Mw?*u^;LbHWIWCyq+yi)`GmFn9J112CZda_u@YIP%i;srFg_paU02Ifij*7}l z&CF-(3|>*a|+vbNR`^RP=9G?ymEJ0Z~)d&c*UE$UMepZ zcITr{0WqhxkjUnM15js_gW=e3Uh|y6ZReaXHIz-=p`x5VvB&rH9y>Amv@^WmXFEw) zQXYrk3feir=a{jMQ+wDIkkFnZ$k{sJakHn*?u za%4b!00ev8NVLM1TY=cl?KB&55BY_MU-sg?c>=Dbz_W{(Z~c?HJi*XpYL)C6Bd8WH zt+v-#0&o~@t4qESi*)+eW%@VD0|o^yF)n0hME$UtXF$*Lvh}7sso{`|pn*JDIy5^Fm3s$5*zEE=?u5<=l8FJc3r%+H} zdfoNl2J0^~!-*mOL5o-x32|e0Im*E!yY7F7E5N)W3>+v_LBydlEx?4$RL5f2oYRD# zaR0wv(-p~wO0eLDl3K=%`{5+0Gd$ktO=W)gWlGZJ0`K z$_RNA=ckrfa;H0KA~dR^p�(p-{x$&=IACIfoAR!za)F-^da-t3#0Dycnp zwO~NVXwXCl;jE<}>%@xz|=8fIJAB?>+E{7)|4l${4ngA3G|=r z2Dyv;VVWSgZx9Wj>qUjleGl3Ei9K4>h!(lPS%8VOG>Xu0%6VDz^O=bjJmuP7>DeUv zrbI}MlHB^^d?{zv6d=@_ZD2lg1&G7UjnVN{1}9WkaM3H~btX0GtSzB+tZ^qRgWo4m z!GmimlG$=wgXCnr6j@m<1gAL46#T~5Bnm=2{^@>|t&`9mkEPddj zAvG~@Tv~TAm2i%VW}R-g(Z0)z-Y|szHr@rk>4MAyG*Ma*7Yh#H7(!-5>DZ@8r;_dx z{prSe<>~099F8vsYd2xff7uAS%7{S)f(|@me3t2$iy&NEc7OUEchp@9A|X;;IA>8!oX+y(BKJ$EzV* znR$z;!L$s7uy@{OT~nG#B!NRraT8(X##Ho!0r_o@gg0CA-9H^;-uE&?$2$nHv_00o z%cbuUc-tCx$Uh&EZ4Nf4Zgqv)Y6>usG3>GeQnxx_Z6+PcbX-+ysbt1hQ`K1LDpOE? zrAhIZhSN9yVIAOa22gn577tbc&i3|3V8NWy&!tw##`}9*x}gtI^h1DzZRA>UuaJG) zaZ7j)dq!O}{?#8Y7~7i6fHh4{`pL?>-18|p!S75Y#^DM>-S3)vuZG+Q7l@ek zQP~#cBpWgg#mApc_sPYjpw8odQuRokmTkzcNl`^CcKB7e&;zViV;{Y{o^Y$%7i0m# z62%#1Lq!RC?}lK>%mp}T!3Xv;L*0v*>USLm``N%>w>@fwC+#T&Tx2bN4w(20JB}oU zuSa6v^kXi0xPs?pbaOHnyiqq6By1EZY9OZ^^QA>{q-Hsd&m`pbQ%8121aWG-F5xf zlZ%;B{;C>X19|`^_?dVyCq>n+41w7|!tUS!{9rHlbhX=SZO5CQ^;!Du_E7*`GiR^Q w)2!4MKjfSAeNo!9>IaV6aUZ*?W>} zs4%E?srLW`CJh0GCIK@hTkrW7A15Iu%N&?Q^$0+!{Tv&|t^Y@u%!L zglTg&?Q5q#ijZ;&HBQ?FNPp;k3J5!&{^+SGq?AX~SiOM9jJMRpyP?RCr@z38AQyy&WRMaC;n4una$~nJKSp?q|s8F00c9?Q! zY_ovvjTFm+DeQM^LXJ#v0}6HRt3R1%5PT*}W!k8BEM;Jrj8dIceFo2fhzTqaB3KKk zGlCLI)gU25(#u6ch6GeB1k@eHq7l{EHXv0n6xE#ws#ri}08kkCf8hUt{|Ejb`2YW* zvg}0nSSX1m=76s?sZhRY$K=3dpJ+y*eDULGnL2}4>4nvW^7_<~wIM_5fjvwt4h1|g z)g0Z6ZFq9j<~9~b8((~TN{Z?ZQfw|is&Xp~AC61sj;xItKyCHdI|tCMC_LbXF>~vR z=w6V3^H=W4CbAgR4#xw}ETTwu2guW~=Crl@SMXv85jQ=%y!s^?m4PI0My7MWICO;- z175jm%&PcPWh8QdOU(#8bp4!N7ET-+)N}N2zk2)8ch|4Q&lPFNQgT-thu053`r*h3 z_8dI@G;`zn;lH$zX3RzIk`E8~`J=BBdR}qD%n@vVG1834)!pS1Y?zVkJGtsa(sB~y zNfMYKsOJb%5J(0ivK8d+l2D2y&5X!cg3BG!AJ}910|_${nF}sC1QF^nLIhzXk-Y#x z0)&1iK!O;Og0Ky!;`b~v%b$`S4E&fB)1NB4v@8wr( z&+NX4e^&o)ecb=)dd~C!{(1e6t?&9j{l8%U*k4)?`(L3;Qjw z#w7FS+U(94MaJKS!J9O8^$)36_J8;thW#2$y9i{bB{?M{QS_inZIJ!jwqAbfXYVd$ zQ5fC$6Nc9hFi8m^;oI-%C#BS|c8vy+@{jx6hFcf^_;2VRgkoN(0h!_VSGmgNPRsxI z8$rTo0LaYq-H5i&gtj81=&xU?H-Y2==G@uQV7E`@+2E9XQW@{&j`?EOktk|Ho{HU>ZqDzvgjwBmdex z&uZNd2C1h{{}2k6Ys9$*nFP3;K%u!MhW`uZy7Sn`1M1zs@Es&;z*Z>Gsh@-3Fe6pE zQD2@cqF((NrRevgvLsvM_8;;iNyJ5nyPyy?e!kvKjGj`6diRFBEe49Oa7wwkJFV7Z z$YT&DWloYu-H?3<0BKn9L&JYDT-SK~*6c5pi18P26$JESKRYj{T7Zk6KiRJcbvOO*{P56Q6s8msbeI3>|j>K9}Q9UBeq*inXKemCm`-<5|-$ZyN4u$(3 z&HcvqehFD%5Yrmykg-^d`=BSa8(i=>ZoC77^mWY{evp(km@aHqhUECBz76YiR+VYK zY_avFC~V3$=`6C4JhfHAQ@DZtUOwH`L;oYX6zK0-uI^?hS$ALfq}A7evR;ohJHij} zHSZdW?EKv9U1s4oD*<(0oQ*;MaQ6@cvGL zuHCPgm_NhVsgp^sfr*ia^Db}swo1?O(_Q2)y+S$CBm+g=9wCOUPbz(x)_GbaKa@A7 zuI&!ynLiZRT#V%_y_-D`0Z5lT*auoe{(U5NylTzFSJW()W-#F6*&A`LNO1bV#Y;QJ zSbLBnp|B^dtK|KIWC|No>JjWBWE@n7O)x{&^E(WMeMvp57#qA8m* zeTow*U@_86B#Fm*rxyYu5PRWaWHx8y> z*qmHEp(AMDl0v)ij(AY8fnH=~ZwwjVAbu*m5;xPfidh@ov6d8g zfJsi&!QyK53Es%sC39ts;54V68koALD4b|%tNHW0bIkZAJKa=W&FomJSEDT>W1xIX z1x%Z>AvNIsSPLcn3RTcHXb@KB?cuM)=x6fcIx>&(GxqZ8w3p#jJ(GVgc*`c0HG}dv zIop&Qim!K1NFwic%07KcjWgHBPUkq7f~lj;TPqVGTiT#cUeim>;nY`>h@a*S{qQex zQ`z62WK|Mj)Y{tfF{;T4P;c8$Q|KU?Joh zIkA^z%X7z|r>4aTh@|StTi!-r1D!g=zb#3d#{{&K3CqE$Iz-UH<%37c zRfkO`&uM%#AD3PHv`g5t0e^O%nVL0d{Xlx^EjEC3#skF@`zl-7PF^0oxW)1!C!JxR zWvuAHH?)61FKA1QeT*_sY7;_Id#!GmV4n`MO{~sv}VLSK` zXRw=Y=Clz*00B(5y^K;gCZMAzjT5+c3IC=)l(9VIDdatpxj3y89WwI|bH&$!ZEvp` zPR!T@#!(|KfI-w?!&+7$N3F6>tD{YO4Qg$d_`nNEdfVCha9vaPn0jI0`)`@*72hq! zpU5ND^P*RoEkbD5o#az(-g=Y)L>HH>Oc%}$ zT3Rs_ih0;4+Lv4Y;@Iv(;fUbQ=i-G(#>vghec~*j(I#r|5mqFiJBpzi&hzEcD{u$< zRsm0BVYn=pT;0>R(itW|*D&;O%bOc7et9ACaH#J>z3A1A~6fdP>pmbM%xzm4>|;c_?B+%sl;Qs2{t!60$^u zH1t@9^6>;?!FuusnISi$f5CL&;z?EqJN$FBuWDA#D5`cy_UvCFIVvf{c?4N0teh;d zET$7aVbj08KTQS!x?Nd1Is8q8qFzs}a=!@nJ;7FSfCY^T@D-gpw`w<6e#X3+;O}1h z$%I!M)0bg|EKUA04Qjn@+x{Rj8vt6Wn!R|3A92z}^$KfF5(#CWr4y#~re1CN4i4w0 z#GsypBR{xA3Er7sgAi(|}1-W?s~n$7?K|9WL8kpVfw-;#b9 z+mn;=ep!162U5R>_t}fOt~tE?s#m( zO-S$7>Ay6*hHdZ)7_oU915WYYCIX;hFI-U2EWYX!pllONr@Q--2o~`!isi6vTPLJ4@(|o=%NHYjo0_S&q*UQIROw@*N-By@PaQ&;YxFZ0aR zX&}LeOEz);#m~Hwm^VAY8DK}b$F4bo{jMN?d!lxKPhNklzr^Cd`0f4oJr^z=I|l`* zm8AHm*fPV`0=lF3Pnnp}&J0N1X@}-D94YvmUabFrLGSnTz7Mu^21F#O5tN#CuY9Vh zUZBH=ez%h*wkf0hBtXJh1SN3d+IF{gzT7lp)j}n?03lt;XSQRAh7qd&v;RwTYDuQ# zbI2*r<>?x-G0@hM{;%{VBD7nLKt~D`T~-HAt5;h%i0_=Ifs=yHma5dhJ+QMG?Ux(a z|E?1CMy1!~oA`FP!k~iG=t&5#>bVdz=peT8HMB6Y)#7PpETtNryT^+Rv3vpJaF^zP z{H}0-LyV9Fu21ID%wO9f1IKlFr1p4c{o-?03vyB-tr5duk^&L$;m_|f$vs`^Sl{j2 z95}oY{LlY+=ZS%J+tZoXCd0*sSU7w^gjovXn+g7uyra5{cU49@yHf#Z^Jl-$9cIfo z+AJuxH$VLb=#+uBbVmUjnx zxb1pZ@-O9=AIk4@S)m6fJ2?{HrNYwwnL3a45muuNjr;6$O`bGEM0T4A2_S$t=86*- zcO+0mywg*j#A4mU}enR_!cGmIYQ;qwfchWtFEXL)AK%*;=j znYne+hS4EMy3S)C*mZ1KI>!+)0V@9!N6H$Y}~MJ{rYuf zz^KljIWvFi-?#?V@LPR&c6Nn{!=XM z>}-h$S76;$H{E{Y%@^zlmOl^efBwa%UU+jJD9UVukQ3ti_kH-?H*RC0?M1W%FCvMB zM_+v6fk$6X2sx)-p~B3&Kl{nscK}pNLM*qjtpaf9>AU{-iPKQZR8yCg!TY}Qg*(;) z)gdvCcB%kppZc$VdvsK@)3l1{&DG!d_6OHOS`y=ITLEVu`unSKA2E%JD*DVX{LJ}K z9l>hMRDqxQh0lnpGHpVYneX}eA3Pt|2v%=q;rt)``R|#bDyB)OXY&vI_@|*}h}G?^ z@aZ4_!7cQPX`!fW_?{oT1NTwHs#l5L-0`E|y@48<3Q^HFf8=Idi zpJYD%1MkII!~|7I^WGo)IF=?{>ACnjJ_WUi39C}!Q{QnheVJqeKKqq5^o5CBde(g9 zvw$X6^jz_^E2$wSw4!q5*RG(C2_^XO$HBn_55vbl44OnTTRwRaePP0vo{K)U1#99& z<>rq7V&V(<&@I%MFoN5zrY}sz=(*-L&}1QQ*a%`u25h{cFj===17eB_uGuzG&byQ< zrm8BJZl4r_E$3k|Wo6FW0-6M7>qac5uFQsQcmkLWGfeH74S3Z_rJ!jgN++!@i=HW8 zkyjI(oPH-+-N#Qc^-mpNO`bc6r=2-<%&Wy5K1vfFJB(L_IkpS6fY^NmuL8qsgj>MD zn~BHH9WM~32_3vd=W&B)k7F9q%stJx+b_L_X-4zr^LVUMCmyCTA3sWtkvsmME?Xiy z?xOSfB=_$oY06~J-HcCq&)qcW{j;uP;?Dm}=hkq?zh&n!;m((-G-u_t|6x399Q;>A zgNpxoJNj{u|MFDH7Rhq@FCAl0dE|ddnl!oh9{Lq?@JDoR6L;C941IK`ISfdE$4S zE0AUQ8+2|Ncl_q5QkSp#AODp~(^mfP&%Au@@|TBQwoP`UU+V{6u8|)6ZA{~uKmQ*M zmrMTDU8S~8Eqi{^v0Ug&5Upcm#y7Z1(RbgZAG8jB$eRwCspQ)>5;U)oGZ&E5aeR*K z8Yt`Y0$G))Yd(Y3KH}tA4`-_QmNke5hU_|nq=xtyjwW(_o?itz>B>WM&^63bNdQ)k@-IgDHW*RW$Xo9#RzrTrCn7L2H{9Amq|qNg@#eZY=|P zCoI?2s+L)zsM%WX(NbVEY^`C>lFjIBYmJ6@DKJ0ZT4&F&WHW!dwa%QzOG!?jY_2(S zDcEzZbz*2Q!43|z))9yOP9X1Xt%DXzwY(3tl-TR=Qb_MbZYRrooh;dYYmS!U_as1(=YVB?Q_A|tNu5Ut&_q3jbfDM zoFxT^uEuH`nX3*sB%K?GuHUkweYReBwnHqh3P)~`+s3+Tj!rDA1e)8vuBv5J*IsxC zkd^~b(aGzArj08{>cnzOuy04C+C`}gb|Yz-1avxeWzev3NzcHbz_&4W@QCr$z3~w=8Ua- z`;vfG1~BP8CyLb=F7t1am~ph_#|O%$khSJ9%Vtcn)YmpgQxF?xM^_Vb+5fnpB^W0I`f%X8gb9#X{Q-yJG0{Z56aWeI&zPxnf5pdJA38bM`cYnS#x)% z`n1tFf$i)W-hGm(f9mde^=X@NcV_lFb=P`4&CI&H=IArijGwdCk&X@uQ$5xmj!~^? z#$ROCI)V-~t%L%GS#wo@U27ddR`4`3)WoB{R-4snfNrfee|kI8^bu#yDgYqOwas9# zmcb`3!kRJ`Cr=_tq)8aMt{aGtUZsqwVlj6DgCGre>AEt&x8H_in!x@uwgExIh|-mA zjdaC(29~CTVSaaF7HPbql&*9Uo8P@f)>LqCXclr}peS7_1BQ28u9PO8Eq1@`l3q9o zkfKCaO2?T?ZyA6loW<#9_c^O=m<&h}CA!ineAD@=(gbq`vyT|tiJ6#^B1$P;;qax` z55k&Q?wEh#87niLo*+n4L@65J(Nz~=Ya%7^(miLb(E>A3B@|Jjl;FU&D>o|9#7PJH z?|ago!o;WC^h=|T7PVBg(DAB}72cyUS zb(f>Bwbr!F1eTCO5fpj<{PqhY5>143p?~5ZA5H40);=@M#MYvrB6gqHbU_!GSY??i z%s=>-ciA4*zOOZHds0a(kWewZ4h(k8h(ua7HX)Au&mY~H8KY6(_cb$_&fA@QjIW-*heP3%$d!m5^AdnT}`12qA^c@!g3DOwZ5WwE2?)-yU z!)Vx#Mtxt?FzFTwK!77sy7)sMzUd->w4^bxtpM2j!b1pjgyk zGKwWGeb4)^zjy{9Es&PU1}gwg?|J#L$KJB7ett9@4M%-nGtIQr0>Fl@8-yh`-+1ed zS6r}(MeSvgSoFmH*_WPu@i?}!AB~2?;i&IxrkNg~cQ9Som98tcq)k^|eeER|Zl77t za-TVUc;DNvzVXJ%w52+#weN?+;i#{f#!Oc&z?81*N>^e~ltRS%ZI@lR{rs()HmqG! zx*}ZrI-EZ}ckJMiy>A^oofwDfC~IH)z8{VHKGT@#E5I(Ll&+MnMCl>~AV7+>Gi%mF zkU1QlKASdR0B80!YhP<$Ywi0?W2Ux45oPfxv9QolWzJPD^weBfvo4SONxP35106sAmh(e+vAs0GboFD@PvNs)jNPvarhW}0YliZEg{Gazv z+JDIpoojRVPr<*C|BTq<`6ga{5q^8^!|0cxe=rZ!zxH3%f5ZO0cQ*Z<^$Yt2{|Ek0 zyT|*F+CO@K;(owBKtGg!S^xj-Z~rga2m6nxKl9J=fBSuNKW_dLKWhJKeg^-Xe`^1? z`TyJj)8E!#>_3Y?uKrwqq3LJ#SGU>AzUO|6`nR^u&3FNN_jGOc zw)Nw`wr3yIKhgcee6IaN=ws>M{6677%)hPwx&HzC(f&u~&)6@b2kNRzBDQAP0*H73 zq%McOmRk{B3i47qRe=DA*$&odrbEJZ*pV9XXa&p@wlW~@Yfs>V{yiTtplMhgM*-Bz zsSnlq&pG;z0OUN%$~$3=g1UF+G*>+17eRbBf3=y79J}KR8owon@$1Z7MIrvvWWH)34nK2SD)GsrJ{l z1Cl#oVo3A8qY3e=aF)qzms~FG#2$LzT=gs&aVMOj>(%{y<&O0cG!nCiESl~x=^dF{ zKvj8F1K8Ng171wwM5Fh4KoQw`_c6#y$(5cAm7e}~nJ#A*fx+c9;y#&W!#VukR)ugk zKp3=+;Ut+IYn%m+r4d*<`L2h%aDnX5}^!5R|H;(34AoVWjRx(msBZvk;rCI*|~ zdOijqI@9Z{Vu!~jvHW{lBa$rnl4+!s_5sfK3bCGk-B%iDe&@-}+%fOKU|(9?V1 zHE8&@4z)Kx!RAvAs z!Wic9=o#(bg?kc-G68-m(jZ`^=XGUXb)}t(%&~sjFnV^sEX%hSy6UKC4iOhgV=BHV z2w`4g7Y=s#Vu2B_?#VQ|hP39@eArgfX>-0S+dd&^mx0*wp}>)x;c4RUgxz%;oNe?& z-7-lJ@Y^2^C;=qJsxx5|xF)*pTGhch2B&kxtn;f!7=gznk}I3}Dh}(CoMXgA5-p&kS202!l?!fT3t|HG*rIP~mS* z$Wjo}jq3}z$Qq!9yrtd3fM0N629ZM?LU$nv@Tv9b7I;D|;0H2dsA~g7Z7zp1| zB)XmrkMgF6OQr|R)HHD^TE{Y#j!~SR?b`Xt3Qs`B+x<hxexYeAjMUWdZ-*n9%(1)Wb(n2U<><7&9dwGJmrob)4%H? zlQ%z+L-^$dFhhH|@u$%97Qz?*Ynh2VG@q|?8vY&L74&fs&_b&3$x&Oyjl~LQDRRap zJU4U*R+(2Dd!G+lh8!V{pT_UJn+^1Qg6$` zqkNm(a#hWyc6SP+p5=C4HL8-m`pO`5o~`-LI?_h5CsH?F_%?nDodmz&pWR20WTpJE z?N|wSzLjMUK8E)a2tI}Lf;+;*M|h3Y(U#>)g1>zk9|Hd}oZAa2 zLYBWBoSW!Ts!RwXr^8h+U*@{9{zqS^iH)Op<;r`Uw~nc}<^$V~_i%$GFjaG?X1@E|M`h)nekvFKt`Dh-f>@|0-`Xoq)o` zx;JmzDfOV9qCx|EVpogEe0LK~tGS?5$$L_i6P$P6wIsCQaP_;d{{N=iV@+8LI}o#( zvo*Ejy=IIn{rdIQh1&q-{EuohpVOjJ^Q3lD*YTp37$^RRgn8ihpdu5{Ct%5-KO!VL zcNB6dUajXI9jkm-P|i3~GB-A(X`P1Oqqb$tcku)UJw0w3GeUijb__#QT4j%64z%EeB7S?jlWwx_7&+EEvB|6N=kV}DwnyAlX=?j`) zmU#!$*^@NIu#n_d7;WoJV@*Fbv9|yJO4;n|BNF2xy(54RyB>t~8lUOUW$&2%Nwi1y zx6JxW88>U2$#qhl^6KUbtmg9}D0o5vYDT7kWJthLGkpGnN4T>{St^_EU>4;DmLF9o zr|LqsA8_MoNLQ=}w?8u!ziSZ@PC#Y<#9uJFo-ozVo6D;<8j^1$c|qAE3ZTE5i~zmE z$BU5lw6l=EWsg^y^;8>r9qH{xfL|~PZYK#md$zZ0?o11gV<*WSW~cgy2GYGQir%wf zt4iW8D+;s*;RGrmd(-T<@2&j(Cb9xhV*l-x`TpK`xq|7p?5R%5*s!69?2c!cC*VY* z2DE^9pvOPLU!1e}wA8S8opcTJ3`NB>hY=JQnL~QFXR4K8A$BqJnoEB$wn-%u@E6Mh zCfMF4kusv3N!(aHC}4)Xs^xoOwXd%e^6pi5|DZo=Q25j+6HlJ^7FodH6y1bMROR^q zGu6)fopS`h%Sw<;ZH%TEPf+#81-#_v+@8nlR0jLcIDKQtLleOC)6yLZgC!D9X3GgS zohwU{v$jl=quD#Go^hB{`@Qw*a%`(^jyT~=q^bWgGzRj;|12J55HWdCWV}EB|K=%N z3Nq-qxJJ`>^|1MNN+q}zTB&ooE3j==AgK@^UW<^oSbeALa2peF)Th6{@sj0KyMNHZ zksk1+MXN2tv+22A%cQOGpS9)77(uP9mh+!5T5ERLvF@b}$+WvXM45Z?-kCa)fb~f1 znVbTD$Gx-0Zxc`0D@YgHakge6SL0H`-vN_x?AP0>iGH0_EE&=v83hMJgaKAI0jJXm zVxVz;X<$v6WW7}fxROO7vr#YLP;;lij5VrX{;>7kK6TtOH&6|Ar^xo>00%+u$C4@# z>!jOt6*3><171+WxoZnKDTzJtDRw+T030;yI}~uV@9fCnei^I*j>Bp&mzP2d=FPb_ zCM*l_+$LDR3B*a!A$g#>xsrZvw0lckxmMg>0aQd7tPyN=t{dgXb;Ie+T8{fZH=gdu zM7Rg9c(kg(Jg0?ARRRl=AONFKrvFj)lTY$KfT%6^6s`mk*ABGhsce*LsoD>K{z_M2 ziPpnu+lw22PfF!CoId^6n*G4H(Ix+#+N{C(da7t1BYMGEaE#PdpOLxsVD5riQXHp@OX;`S`8VnpM~)I920w~<3|mo0 zf8~Az`*?2?H&gZ&*K&bRkV@qzvMlRHXys8*Ze2+1c?5o!^+$&MHxB@4Ee5cke52R! zmn7AZtY6ST%ixgU5)%$%QcwHj7Es-Qu^kLAPwy%7pGBw_4Q9#da^W2$}axNHr03)_nw z5?yuNmXrI5HgS46)c5&}B)Tts49oU92>3xBLLy}FMUW=84DQbVq^;7_e7|(Sdz|&J z73N+M`rc2rt*oSWu#7S{*s~nH6HRHJS1SmzeXk|;CA)FI4bat3<%}nkB%;;?=F>B7ms9QSxv#@+69;@>QaR?REYX4&)=itG>rM{<{A79Rmk)`5ON#GL`*KX%}Ihk3w(RtM-WLt z?f&FLF}4N^yE!(pZ&Yj&Bc`~K0@4_}*0Om?wN|}4WJ>WL;G^H2*QpgEkGA~OET-Km zkwz|5{6dnz1U<2Pe9DNL>3g5FEIvp1jzP&2K#z~j%g6!7B;^zF+o95?fV{3mnB8*RMhCDNp>Am-3e@jNfMj?jHV$MWjk!DDKP zkAz$Y?Sr)!GUOX}qTQ5aMh|wq1uq}~joWyKl=b_LboM#wi{CMuz5x6BKlA-qy++cM01D3b7`uD z#l6M4pI;JCypO8JZ6?U&wNxR!{4oB_ zlV!x9+-&Qy6{%MQ{~yoZGkKiTSC`YS_j22~G;xUV855g2&C(zm^V!(wpcm@zn{%!g z4}JGo(sGZ1O~to-}le

UmY2RIYtNPVDpE$%vda+HD#3m z&VuXJ{BK&Qe+rBa7eq}Q(bq|tn(RrJAk|ztj2(i{d>nmQnM?;HF2k&9sA6up5tmjl z7lySlzMbifH17-m-Lwa_F&e7nOH?ESi3#ckR3tsM+jsck3`oG!uMS}|eAwVXv>}qxwq?QY%QJ0}r@^;fhuUA9W z*BVl>TGo&N004@xSiwDUXUvp51sVmqO3m)=B55aPwf@0=e}cN+$-BdKxY`YrT_4)0 z_d10#i44Q*rFr8MC>*)v$EJvz``(pb{e&*6k+b zsMz%($|1+8hn8c2?P(l@;Rb&CsZeYoCI3?2!LqjbwPXW3z4G$Qfj=cT5Yb%vY0(AX oeb?AaKtwrnc|$|zzw9vfvn^aJJ!zd)XFXqqy0000001=f@-~a#s literal 0 HcmV?d00001 diff --git a/sharing/android/example/app/src/main/res/values/colors.xml b/sharing/android/example/app/src/main/res/values/colors.xml new file mode 100644 index 00000000..758655a2 --- /dev/null +++ b/sharing/android/example/app/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + diff --git a/sharing/android/example/app/src/main/res/values/strings.xml b/sharing/android/example/app/src/main/res/values/strings.xml new file mode 100644 index 00000000..d31406f5 --- /dev/null +++ b/sharing/android/example/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + Nearby Share Demo + diff --git a/sharing/android/example/app/src/main/res/values/themes.xml b/sharing/android/example/app/src/main/res/values/themes.xml new file mode 100644 index 00000000..3632dee2 --- /dev/null +++ b/sharing/android/example/app/src/main/res/values/themes.xml @@ -0,0 +1,5 @@ + + + +