Commit aa6970c7 authored by Himanshu Jaju's avatar Himanshu Jaju Committed by Commit Bot

Implement IsOutOfStorage for incoming attachments in Nearby Share

- Checks if incoming files are store-able in the Downloads section
- Adds a test to get Fail incoming connection due to storage crunch
- PRD for decision on storing in Downloads (go/cros-nearby)

Bug: 1085068
Change-Id: Ibee41fce67d0da5b904112b4b9970215ae874b60
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2336033
Commit-Queue: Himanshu Jaju <himanshujaju@chromium.org>
Reviewed-by: default avatarJames Vecore <vecore@google.com>
Reviewed-by: default avatarRichard Knoll <knollr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#799096}
parent e445f27f
...@@ -8,10 +8,13 @@ ...@@ -8,10 +8,13 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/numerics/checked_math.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/system/sys_info.h"
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "base/task_runner_util.h" #include "base/task_runner_util.h"
#include "base/threading/sequenced_task_runner_handle.h" #include "base/threading/sequenced_task_runner_handle.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl.h" #include "chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl.h"
#include "chrome/browser/nearby_sharing/certificates/nearby_share_encrypted_metadata_key.h" #include "chrome/browser/nearby_sharing/certificates/nearby_share_encrypted_metadata_key.h"
#include "chrome/browser/nearby_sharing/client/nearby_share_client_impl.h" #include "chrome/browser/nearby_sharing/client/nearby_share_client_impl.h"
...@@ -28,6 +31,7 @@ ...@@ -28,6 +31,7 @@
#include "chrome/services/sharing/public/cpp/advertisement.h" #include "chrome/services/sharing/public/cpp/advertisement.h"
#include "chrome/services/sharing/public/mojom/nearby_connections_types.mojom.h" #include "chrome/services/sharing/public/mojom/nearby_connections_types.mojom.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
#include "content/public/browser/download_manager.h"
#include "device/bluetooth/bluetooth_adapter_factory.h" #include "device/bluetooth/bluetooth_adapter_factory.h"
#include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/shared_url_loader_factory.h"
#include "ui/base/idle/idle.h" #include "ui/base/idle/idle.h"
...@@ -110,6 +114,11 @@ std::string ToFourDigitString(const std::vector<uint8_t>& bytes) { ...@@ -110,6 +114,11 @@ std::string ToFourDigitString(const std::vector<uint8_t>& bytes) {
return base::StringPrintf("%04d", std::abs(hash)); return base::StringPrintf("%04d", std::abs(hash));
} }
bool IsOutOfStorage(base::FilePath file_path, int64_t storage_required) {
int64_t free_space = base::SysInfo::AmountOfFreeDiskSpace(file_path);
return free_space < storage_required;
}
} // namespace } // namespace
NearbySharingServiceImpl::NearbySharingServiceImpl( NearbySharingServiceImpl::NearbySharingServiceImpl(
...@@ -1491,6 +1500,8 @@ void NearbySharingServiceImpl::OnReceivedIntroduction( ...@@ -1491,6 +1500,8 @@ void NearbySharingServiceImpl::OnReceivedIntroduction(
NS_LOG(INFO) << __func__ << ": Successfully read the introduction frame."; NS_LOG(INFO) << __func__ << ": Successfully read the introduction frame.";
base::CheckedNumeric<int64_t> file_size_sum(0);
sharing::mojom::IntroductionFramePtr introduction_frame = sharing::mojom::IntroductionFramePtr introduction_frame =
std::move((*frame)->get_introduction()); std::move((*frame)->get_introduction());
for (const auto& file : introduction_frame->file_metadata) { for (const auto& file : introduction_frame->file_metadata) {
...@@ -1509,6 +1520,15 @@ void NearbySharingServiceImpl::OnReceivedIntroduction( ...@@ -1509,6 +1520,15 @@ void NearbySharingServiceImpl::OnReceivedIntroduction(
file->mime_type); file->mime_type);
SetAttachmentPayloadId(attachment, file->payload_id); SetAttachmentPayloadId(attachment, file->payload_id);
share_target.file_attachments.push_back(std::move(attachment)); share_target.file_attachments.push_back(std::move(attachment));
file_size_sum += file->size;
if (!file_size_sum.IsValid()) {
Fail(share_target, TransferMetadata::Status::kNotEnoughSpace);
NS_LOG(WARNING) << __func__
<< ": Ignoring introduction, total file size overflowed "
"64 bit integer.";
return;
}
} }
for (const auto& text : introduction_frame->text_metadata) { for (const auto& text : introduction_frame->text_metadata) {
...@@ -1541,7 +1561,31 @@ void NearbySharingServiceImpl::OnReceivedIntroduction( ...@@ -1541,7 +1561,31 @@ void NearbySharingServiceImpl::OnReceivedIntroduction(
return; return;
} }
if (IsOutOfStorage(share_target)) { if (file_size_sum.ValueOrDie() == 0) {
OnStorageCheckCompleted(std::move(share_target), std::move(token),
/*is_out_of_storage=*/false);
return;
}
base::FilePath download_path =
DownloadPrefs::FromDownloadManager(
content::BrowserContext::GetDownloadManager(profile_))
->DownloadPath();
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, {base::MayBlock()},
base::BindOnce(&IsOutOfStorage, std::move(download_path),
file_size_sum.ValueOrDie()),
base::BindOnce(&NearbySharingServiceImpl::OnStorageCheckCompleted,
weak_ptr_factory_.GetWeakPtr(), std::move(share_target),
std::move(token)));
}
void NearbySharingServiceImpl::OnStorageCheckCompleted(
ShareTarget share_target,
base::Optional<std::string> token,
bool is_out_of_storage) {
if (is_out_of_storage) {
Fail(share_target, TransferMetadata::Status::kNotEnoughSpace); Fail(share_target, TransferMetadata::Status::kNotEnoughSpace);
NS_LOG(WARNING) << __func__ NS_LOG(WARNING) << __func__
<< ": Not enough space on the receiver. We have informed " << ": Not enough space on the receiver. We have informed "
...@@ -1549,6 +1593,13 @@ void NearbySharingServiceImpl::OnReceivedIntroduction( ...@@ -1549,6 +1593,13 @@ void NearbySharingServiceImpl::OnReceivedIntroduction(
return; return;
} }
NearbyConnection* connection = GetIncomingConnection(share_target);
if (!connection) {
NS_LOG(WARNING) << __func__ << ": Invalid connection for share target - "
<< share_target.device_name;
return;
}
mutual_acceptance_timeout_alarm_.Reset(base::BindOnce( mutual_acceptance_timeout_alarm_.Reset(base::BindOnce(
&NearbySharingServiceImpl::OnIncomingMutualAcceptanceTimeout, &NearbySharingServiceImpl::OnIncomingMutualAcceptanceTimeout,
weak_ptr_factory_.GetWeakPtr(), share_target)); weak_ptr_factory_.GetWeakPtr(), share_target));
...@@ -1646,11 +1697,6 @@ void NearbySharingServiceImpl::OnIncomingConnectionDisconnected( ...@@ -1646,11 +1697,6 @@ void NearbySharingServiceImpl::OnIncomingConnectionDisconnected(
UnregisterShareTarget(share_target); UnregisterShareTarget(share_target);
} }
bool NearbySharingServiceImpl::IsOutOfStorage(const ShareTarget& share_target) {
// TODO(himanshujaju) - Check storage space based on file path.
return false;
}
void NearbySharingServiceImpl::OnIncomingMutualAcceptanceTimeout( void NearbySharingServiceImpl::OnIncomingMutualAcceptanceTimeout(
const ShareTarget& share_target) { const ShareTarget& share_target) {
DCHECK(share_target.is_incoming); DCHECK(share_target.is_incoming);
......
...@@ -194,13 +194,15 @@ class NearbySharingServiceImpl ...@@ -194,13 +194,15 @@ class NearbySharingServiceImpl
void OnReceivedIntroduction(ShareTarget share_target, void OnReceivedIntroduction(ShareTarget share_target,
base::Optional<std::string> token, base::Optional<std::string> token,
base::Optional<sharing::mojom::V1FramePtr> frame); base::Optional<sharing::mojom::V1FramePtr> frame);
void OnStorageCheckCompleted(ShareTarget share_target,
base::Optional<std::string> token,
bool is_out_of_storage);
void OnFrameRead(ShareTarget share_target, void OnFrameRead(ShareTarget share_target,
base::Optional<sharing::mojom::V1FramePtr> frame); base::Optional<sharing::mojom::V1FramePtr> frame);
void HandleCertificateInfoFrame( void HandleCertificateInfoFrame(
const sharing::mojom::CertificateInfoFramePtr& certificate_frame); const sharing::mojom::CertificateInfoFramePtr& certificate_frame);
void OnIncomingConnectionDisconnected(const ShareTarget& share_target); void OnIncomingConnectionDisconnected(const ShareTarget& share_target);
bool IsOutOfStorage(const ShareTarget& share_target);
void OnIncomingMutualAcceptanceTimeout(const ShareTarget& share_target); void OnIncomingMutualAcceptanceTimeout(const ShareTarget& share_target);
base::Optional<ShareTarget> CreateShareTarget( base::Optional<ShareTarget> CreateShareTarget(
......
...@@ -13,9 +13,14 @@ ...@@ -13,9 +13,14 @@
#include "base/containers/span.h" #include "base/containers/span.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/system/sys_info.h"
#include "base/test/bind_test_util.h" #include "base/test/bind_test_util.h"
#include "base/test/scoped_feature_list.h" #include "base/test/scoped_feature_list.h"
#include "chrome/browser/browser_features.h" #include "chrome/browser/browser_features.h"
#include "chrome/browser/download/chrome_download_manager_delegate.h"
#include "chrome/browser/download/download_core_service_factory.h"
#include "chrome/browser/download/download_core_service_impl.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/nearby_sharing/certificates/fake_nearby_share_certificate_manager.h" #include "chrome/browser/nearby_sharing/certificates/fake_nearby_share_certificate_manager.h"
#include "chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl.h" #include "chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl.h"
#include "chrome/browser/nearby_sharing/certificates/test_util.h" #include "chrome/browser/nearby_sharing/certificates/test_util.h"
...@@ -230,6 +235,7 @@ class NearbySharingServiceImplTest : public testing::Test { ...@@ -230,6 +235,7 @@ class NearbySharingServiceImplTest : public testing::Test {
void SetUp() override { void SetUp() override {
ASSERT_TRUE(profile_manager_.SetUp()); ASSERT_TRUE(profile_manager_.SetUp());
network_notifier_ = net::test::MockNetworkChangeNotifier::Create();
NearbyShareLocalDeviceDataManagerImpl::Factory::SetFactoryForTesting( NearbyShareLocalDeviceDataManagerImpl::Factory::SetFactoryForTesting(
&local_device_data_manager_factory_); &local_device_data_manager_factory_);
...@@ -260,23 +266,35 @@ class NearbySharingServiceImplTest : public testing::Test { ...@@ -260,23 +266,35 @@ class NearbySharingServiceImplTest : public testing::Test {
.WillRepeatedly(testing::Return(&mock_decoder_)); .WillRepeatedly(testing::Return(&mock_decoder_));
} }
void TearDown() override { profile_manager_.DeleteAllTestingProfiles(); } void TearDown() override {
if (profile_) {
DownloadCoreServiceFactory::GetForBrowserContext(profile_)
->SetDownloadManagerDelegateForTesting(nullptr);
profile_ = nullptr;
}
profile_manager_.DeleteAllTestingProfiles();
}
std::unique_ptr<NearbySharingServiceImpl> CreateService( std::unique_ptr<NearbySharingServiceImpl> CreateService(
const std::string& profile_name) { const std::string& profile_name) {
Profile* profile = profile_manager_.CreateTestingProfile(profile_name); profile_ = profile_manager_.CreateTestingProfile(profile_name);
fake_nearby_connections_manager_ = new FakeNearbyConnectionsManager(); fake_nearby_connections_manager_ = new FakeNearbyConnectionsManager();
notification_tester_ = notification_tester_ =
std::make_unique<NotificationDisplayServiceTester>(profile); std::make_unique<NotificationDisplayServiceTester>(profile_);
NotificationDisplayService* notification_display_service = NotificationDisplayService* notification_display_service =
NotificationDisplayServiceFactory::GetForProfile(profile); NotificationDisplayServiceFactory::GetForProfile(profile_);
auto service = std::make_unique<NearbySharingServiceImpl>( auto service = std::make_unique<NearbySharingServiceImpl>(
&prefs_, notification_display_service, profile, &prefs_, notification_display_service, profile_,
base::WrapUnique(fake_nearby_connections_manager_), base::WrapUnique(fake_nearby_connections_manager_),
&mock_nearby_process_manager_); &mock_nearby_process_manager_);
ON_CALL(mock_nearby_process_manager_, IsActiveProfile(profile)) ON_CALL(mock_nearby_process_manager_, IsActiveProfile(profile_))
.WillByDefault(Return(true)); .WillByDefault(Return(true));
DownloadCoreServiceFactory::GetForBrowserContext(profile_)
->SetDownloadManagerDelegateForTesting(
std::make_unique<ChromeDownloadManagerDelegate>(profile_));
// Allow the posted task to fetch the BluetoothAdapter to finish. // Allow the posted task to fetch the BluetoothAdapter to finish.
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
...@@ -508,9 +526,14 @@ class NearbySharingServiceImplTest : public testing::Test { ...@@ -508,9 +526,14 @@ class NearbySharingServiceImplTest : public testing::Test {
} }
base::test::ScopedFeatureList scoped_feature_list_; base::test::ScopedFeatureList scoped_feature_list_;
// We need to ensure that |network_notifier_| is created and destroyed after
// |task_environment_| to avoid UAF issues when using
// ChromeDownloadManagerDelegate.
std::unique_ptr<net::test::MockNetworkChangeNotifier> network_notifier_;
content::BrowserTaskEnvironment task_environment_; content::BrowserTaskEnvironment task_environment_;
ui::ScopedSetIdleState idle_state_{ui::IDLE_STATE_IDLE}; ui::ScopedSetIdleState idle_state_{ui::IDLE_STATE_IDLE};
TestingProfileManager profile_manager_{TestingBrowserProcess::GetGlobal()}; TestingProfileManager profile_manager_{TestingBrowserProcess::GetGlobal()};
Profile* profile_ = nullptr;
sync_preferences::TestingPrefServiceSyncable prefs_; sync_preferences::TestingPrefServiceSyncable prefs_;
FakeNearbyConnectionsManager* fake_nearby_connections_manager_ = nullptr; FakeNearbyConnectionsManager* fake_nearby_connections_manager_ = nullptr;
FakeNearbyShareLocalDeviceDataManager::Factory FakeNearbyShareLocalDeviceDataManager::Factory
...@@ -526,8 +549,6 @@ class NearbySharingServiceImplTest : public testing::Test { ...@@ -526,8 +549,6 @@ class NearbySharingServiceImplTest : public testing::Test {
device::BluetoothAdapter::Observer* adapter_observer_ = nullptr; device::BluetoothAdapter::Observer* adapter_observer_ = nullptr;
scoped_refptr<NiceMock<device::MockBluetoothAdapter>> mock_bluetooth_adapter_; scoped_refptr<NiceMock<device::MockBluetoothAdapter>> mock_bluetooth_adapter_;
NiceMock<MockNearbyProcessManager> mock_nearby_process_manager_; NiceMock<MockNearbyProcessManager> mock_nearby_process_manager_;
std::unique_ptr<net::test::MockNetworkChangeNotifier> network_notifier_ =
net::test::MockNetworkChangeNotifier::Create();
NiceMock<MockNearbySharingDecoder> mock_decoder_; NiceMock<MockNearbySharingDecoder> mock_decoder_;
FakeNearbyConnection connection_; FakeNearbyConnection connection_;
}; };
...@@ -1570,6 +1591,161 @@ TEST_F(NearbySharingServiceImplTest, ...@@ -1570,6 +1591,161 @@ TEST_F(NearbySharingServiceImplTest,
service_->UnregisterReceiveSurface(&callback); service_->UnregisterReceiveSurface(&callback);
} }
TEST_F(NearbySharingServiceImplTest, IncomingConnection_OutOfStorage) {
fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId,
kToken);
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
/*return_empty_advertisement=*/false);
base::FilePath file_path =
DownloadPrefs::FromDownloadManager(
content::BrowserContext::GetDownloadManager(profile_))
->DownloadPath();
int64_t free_space = base::SysInfo::AmountOfFreeDiskSpace(file_path);
// Might return -1 for failure.
if (free_space < 0)
free_space = 0;
// Set a huge file size in introduction frame to go out of storage.
std::string intro = "introduction_frame";
std::vector<uint8_t> bytes(intro.begin(), intro.end());
EXPECT_CALL(mock_decoder_, DecodeFrame(testing::Eq(bytes), testing::_))
.WillOnce(testing::Invoke(
[&free_space](
const std::vector<uint8_t>& data,
MockNearbySharingDecoder::DecodeFrameCallback callback) {
std::vector<sharing::mojom::FileMetadataPtr> mojo_file_metadatas;
mojo_file_metadatas.push_back(sharing::mojom::FileMetadata::New(
"name", sharing::mojom::FileMetadata::Type::kAudio,
/*payload_id=*/1, free_space + 1, "mime_type",
/*id=*/123));
sharing::mojom::V1FramePtr mojo_v1frame =
sharing::mojom::V1Frame::New();
mojo_v1frame->set_introduction(
sharing::mojom::IntroductionFrame::New(
std::move(mojo_file_metadatas),
std::vector<sharing::mojom::TextMetadataPtr>(),
/*required_package=*/base::nullopt,
std::vector<sharing::mojom::WifiCredentialsMetadataPtr>()));
sharing::mojom::FramePtr mojo_frame = sharing::mojom::Frame::New();
mojo_frame->set_v1(std::move(mojo_v1frame));
std::move(callback).Run(std::move(mojo_frame));
}));
connection_.AppendReadableData(std::move(bytes));
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
NiceMock<MockTransferUpdateCallback> callback;
base::RunLoop run_loop;
EXPECT_CALL(callback, OnTransferUpdate(testing::_, testing::_))
.WillOnce(testing::Invoke([&run_loop](const ShareTarget& share_target,
TransferMetadata metadata) {
EXPECT_TRUE(share_target.is_incoming);
EXPECT_TRUE(share_target.is_known);
EXPECT_TRUE(share_target.has_attachments());
EXPECT_EQ(0u, share_target.text_attachments.size());
EXPECT_EQ(1u, share_target.file_attachments.size());
EXPECT_EQ(kDeviceName, share_target.device_name);
EXPECT_EQ(GURL(kTestMetadataIconUrl), share_target.image_url);
EXPECT_EQ(nearby_share::mojom::ShareTargetType::kUnknown,
share_target.type);
EXPECT_TRUE(share_target.device_id);
EXPECT_NE(kEndpointId, share_target.device_id);
EXPECT_EQ(kTestMetadataFullName, share_target.full_name);
EXPECT_EQ(TransferMetadata::Status::kNotEnoughSpace, metadata.status());
run_loop.Quit();
}));
SetUpKeyVerification(sharing::mojom::PairedKeyResultFrame_Status::kSuccess);
SetUpForegroundReceiveSurface(callback);
service_->OnIncomingConnection(kEndpointId, kValidV1EndpointInfo,
&connection_);
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1,
/*success=*/true);
run_loop.Run();
// To avoid UAF in OnIncomingTransferUpdate().
service_->UnregisterReceiveSurface(&callback);
}
TEST_F(NearbySharingServiceImplTest, IncomingConnection_FileSizeOverflow) {
fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId,
kToken);
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
/*return_empty_advertisement=*/false);
// Set file size sum huge to check for overflow.
std::string intro = "introduction_frame";
std::vector<uint8_t> bytes(intro.begin(), intro.end());
EXPECT_CALL(mock_decoder_, DecodeFrame(testing::Eq(bytes), testing::_))
.WillOnce(testing::Invoke(
[](const std::vector<uint8_t>& data,
MockNearbySharingDecoder::DecodeFrameCallback callback) {
std::vector<sharing::mojom::FileMetadataPtr> mojo_file_metadatas;
mojo_file_metadatas.push_back(sharing::mojom::FileMetadata::New(
"name_1", sharing::mojom::FileMetadata::Type::kAudio,
/*payload_id=*/1, /*size=*/std::numeric_limits<int64_t>::max(),
"mime_type",
/*id=*/123));
mojo_file_metadatas.push_back(sharing::mojom::FileMetadata::New(
"name_2", sharing::mojom::FileMetadata::Type::kVideo,
/*payload_id=*/2, /*size=*/100, "mime_type",
/*id=*/124));
sharing::mojom::V1FramePtr mojo_v1frame =
sharing::mojom::V1Frame::New();
mojo_v1frame->set_introduction(
sharing::mojom::IntroductionFrame::New(
std::move(mojo_file_metadatas),
std::vector<sharing::mojom::TextMetadataPtr>(),
/*required_package=*/base::nullopt,
std::vector<sharing::mojom::WifiCredentialsMetadataPtr>()));
sharing::mojom::FramePtr mojo_frame = sharing::mojom::Frame::New();
mojo_frame->set_v1(std::move(mojo_v1frame));
std::move(callback).Run(std::move(mojo_frame));
}));
connection_.AppendReadableData(std::move(bytes));
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
NiceMock<MockTransferUpdateCallback> callback;
base::RunLoop run_loop;
EXPECT_CALL(callback, OnTransferUpdate(testing::_, testing::_))
.WillOnce(testing::Invoke([&run_loop](const ShareTarget& share_target,
TransferMetadata metadata) {
EXPECT_TRUE(share_target.is_incoming);
EXPECT_TRUE(share_target.is_known);
EXPECT_EQ(kDeviceName, share_target.device_name);
EXPECT_EQ(GURL(kTestMetadataIconUrl), share_target.image_url);
EXPECT_EQ(nearby_share::mojom::ShareTargetType::kUnknown,
share_target.type);
EXPECT_TRUE(share_target.device_id);
EXPECT_NE(kEndpointId, share_target.device_id);
EXPECT_EQ(kTestMetadataFullName, share_target.full_name);
EXPECT_EQ(TransferMetadata::Status::kNotEnoughSpace, metadata.status());
run_loop.Quit();
}));
SetUpKeyVerification(sharing::mojom::PairedKeyResultFrame_Status::kSuccess);
SetUpForegroundReceiveSurface(callback);
service_->OnIncomingConnection(kEndpointId, kValidV1EndpointInfo,
&connection_);
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1,
/*success=*/true);
run_loop.Run();
// To avoid UAF in OnIncomingTransferUpdate().
service_->UnregisterReceiveSurface(&callback);
}
TEST_F(NearbySharingServiceImplTest, TEST_F(NearbySharingServiceImplTest,
IncomingConnection_ValidIntroductionFrame_ValidCertificate) { IncomingConnection_ValidIntroductionFrame_ValidCertificate) {
fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId, fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment