[Nearby] Download certs during discovery and retry decryption
Previously, to ensure freshness of public certificates received from trusted contacts, we started downloading public certificates when discovery started. However, we did not block discovery on the download, and we did not retry certificate decryption using already-discovered advertisements after new certificates were downloaded. In this CL, if we discover a contact-based advertisement that cannot decrypt any locally stored public certificates, we cache that advertisement, download certificates from the server, and retry decryption. We check for cached advertisements every 10s during discovery, downloading certificates if necessary, but we limit the number of certificate downloads to a maximum of 3 for a given discovery session. The cache of advertisements is cleared for each new discovery session. Manually verified that changing the receiving phone or Chromebook's device name--which regenerates certificates--before or during discovery did not prevent the device from being discovered as long as we were within the retry limit. Note: Changing the device name during discovery might temporarily result in a stale share target with the old name. See https://crbug.com/1182540 Fixed: 1152158 Change-Id: Ie40317adb6e123c7d0157d066075c7706264c66f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2721003 Commit-Queue: Josh Nohle <nohle@chromium.org> Reviewed-by: James Vecore <vecore@google.com> Cr-Commit-Position: refs/heads/master@{#858043}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
3324874e17
commit
5d8f6e647d
@ -44,7 +44,8 @@ void FakeNearbyConnectionsManager::StartDiscovery(
|
||||
ConnectionsCallback callback) {
|
||||
is_shutdown_ = false;
|
||||
discovery_listener_ = listener;
|
||||
// TODO(alexchau): Implement.
|
||||
std::move(callback).Run(
|
||||
NearbyConnectionsManager::ConnectionsStatus::kSuccess);
|
||||
}
|
||||
|
||||
void FakeNearbyConnectionsManager::StopDiscovery() {
|
||||
|
@ -65,6 +65,15 @@ constexpr base::TimeDelta kBackgroundAdvertisementRotationDelayMax =
|
||||
constexpr base::TimeDelta kInvalidateSurfaceStateDelayAfterTransferDone =
|
||||
base::TimeDelta::FromMilliseconds(3000);
|
||||
|
||||
// The maximum number of certificate downloads that can be performed during a
|
||||
// discovery session.
|
||||
constexpr size_t kMaxCertificateDownloadsDuringDiscovery = 3u;
|
||||
// The time between certificate downloads during a discovery session. The
|
||||
// download is only attempted if there are discovered, contact-based
|
||||
// advertisements that cannot decrypt any currently stored public certificates.
|
||||
constexpr base::TimeDelta kCertificateDownloadDuringDiscoveryPeriod =
|
||||
base::TimeDelta::FromSeconds(10);
|
||||
|
||||
// Used to hash a token into a 4 digit string.
|
||||
constexpr int kHashModulo = 9973;
|
||||
constexpr int kHashBaseMultiplier = 31;
|
||||
@ -875,6 +884,7 @@ void NearbySharingServiceImpl::CleanupAfterNearbyProcessStopped() {
|
||||
|
||||
ClearOutgoingShareTargetInfoMap();
|
||||
incoming_share_target_info_map_.clear();
|
||||
discovered_advertisements_to_retry_map_.clear();
|
||||
|
||||
foreground_send_transfer_callbacks_.Clear();
|
||||
background_send_transfer_callbacks_.Clear();
|
||||
@ -896,6 +906,7 @@ void NearbySharingServiceImpl::CleanupAfterNearbyProcessStopped() {
|
||||
advertising_power_level_ = PowerLevel::kUnknown;
|
||||
|
||||
process_shutdown_pending_timer_.Stop();
|
||||
certificate_download_during_discovery_timer_.Stop();
|
||||
rotate_background_advertisement_timer_.Stop();
|
||||
}
|
||||
|
||||
@ -1048,8 +1059,18 @@ void NearbySharingServiceImpl::OnAllowedContactsChanged(
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::OnPublicCertificatesDownloaded() {
|
||||
// TODO(https://crbug.com/1152158): Possibly restart scanning after public
|
||||
// certificates are downloaded.
|
||||
if (!is_scanning_ || discovered_advertisements_to_retry_map_.empty())
|
||||
return;
|
||||
|
||||
NS_LOG(VERBOSE) << __func__
|
||||
<< ": Public certificates downloaded while scanning. "
|
||||
<< "Retrying decryption with "
|
||||
<< discovered_advertisements_to_retry_map_.size()
|
||||
<< " previously discovered advertisements.";
|
||||
const auto map_copy = discovered_advertisements_to_retry_map_;
|
||||
discovered_advertisements_to_retry_map_.clear();
|
||||
for (const auto& id_info_pair : map_copy)
|
||||
OnEndpointDiscovered(id_info_pair.first, id_info_pair.second);
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::OnPrivateCertificatesChanged() {
|
||||
@ -1291,13 +1312,14 @@ void NearbySharingServiceImpl::HandleEndpointDiscovered(
|
||||
endpoint_info,
|
||||
base::BindOnce(&NearbySharingServiceImpl::OnOutgoingAdvertisementDecoded,
|
||||
endpoint_discovery_weak_ptr_factory_.GetWeakPtr(),
|
||||
endpoint_id));
|
||||
endpoint_id, endpoint_info));
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::HandleEndpointLost(
|
||||
const std::string& endpoint_id) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
NS_LOG(VERBOSE) << __func__ << ": endpoint_id=" << endpoint_id;
|
||||
|
||||
if (!is_scanning_) {
|
||||
NS_LOG(VERBOSE)
|
||||
<< __func__
|
||||
@ -1306,6 +1328,7 @@ void NearbySharingServiceImpl::HandleEndpointLost(
|
||||
return;
|
||||
}
|
||||
|
||||
discovered_advertisements_to_retry_map_.erase(endpoint_id);
|
||||
RemoveOutgoingShareTargetWithEndpointId(endpoint_id);
|
||||
FinishEndpointDiscoveryEvent();
|
||||
}
|
||||
@ -1324,6 +1347,7 @@ void NearbySharingServiceImpl::FinishEndpointDiscoveryEvent() {
|
||||
|
||||
void NearbySharingServiceImpl::OnOutgoingAdvertisementDecoded(
|
||||
const std::string& endpoint_id,
|
||||
const std::vector<uint8_t>& endpoint_info,
|
||||
sharing::mojom::AdvertisementPtr advertisement) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
if (!advertisement) {
|
||||
@ -1352,11 +1376,12 @@ void NearbySharingServiceImpl::OnOutgoingAdvertisementDecoded(
|
||||
std::move(encrypted_metadata_key),
|
||||
base::BindOnce(&NearbySharingServiceImpl::OnOutgoingDecryptedCertificate,
|
||||
endpoint_discovery_weak_ptr_factory_.GetWeakPtr(),
|
||||
endpoint_id, std::move(advertisement)));
|
||||
endpoint_id, endpoint_info, std::move(advertisement)));
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::OnOutgoingDecryptedCertificate(
|
||||
const std::string& endpoint_id,
|
||||
const std::vector<uint8_t>& endpoint_info,
|
||||
sharing::mojom::AdvertisementPtr advertisement,
|
||||
base::Optional<NearbyShareDecryptedPublicCertificate> certificate) {
|
||||
// Check again for this endpoint id, to avoid race conditions.
|
||||
@ -1374,7 +1399,9 @@ void NearbySharingServiceImpl::OnOutgoingDecryptedCertificate(
|
||||
if (!share_target) {
|
||||
NS_LOG(VERBOSE) << __func__
|
||||
<< ": Failed to convert advertisement to share target from "
|
||||
"discovered advertisement. Ignoring endpoint.";
|
||||
<< "discovered advertisement. Ignoring endpoint until next "
|
||||
<< "certificate download.";
|
||||
discovered_advertisements_to_retry_map_[endpoint_id] = endpoint_info;
|
||||
FinishEndpointDiscoveryEvent();
|
||||
return;
|
||||
}
|
||||
@ -1403,6 +1430,34 @@ void NearbySharingServiceImpl::OnOutgoingDecryptedCertificate(
|
||||
FinishEndpointDiscoveryEvent();
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::ScheduleCertificateDownloadDuringDiscovery(
|
||||
size_t download_count) {
|
||||
if (download_count >= kMaxCertificateDownloadsDuringDiscovery)
|
||||
return;
|
||||
|
||||
certificate_download_during_discovery_timer_.Start(
|
||||
FROM_HERE, kCertificateDownloadDuringDiscoveryPeriod,
|
||||
base::BindOnce(&NearbySharingServiceImpl::
|
||||
OnCertificateDownloadDuringDiscoveryTimerFired,
|
||||
weak_ptr_factory_.GetWeakPtr(), download_count));
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::OnCertificateDownloadDuringDiscoveryTimerFired(
|
||||
size_t download_count) {
|
||||
if (!is_scanning_)
|
||||
return;
|
||||
|
||||
if (!discovered_advertisements_to_retry_map_.empty()) {
|
||||
NS_LOG(VERBOSE) << __func__ << ": Detected "
|
||||
<< discovered_advertisements_to_retry_map_.size()
|
||||
<< " discovered advertisements that could not decrypt any "
|
||||
<< "public certificates. Re-downloading certificates.";
|
||||
certificate_manager_->DownloadPublicCertificates();
|
||||
++download_count;
|
||||
}
|
||||
ScheduleCertificateDownloadDuringDiscovery(download_count);
|
||||
}
|
||||
|
||||
bool NearbySharingServiceImpl::IsBluetoothPresent() const {
|
||||
return bluetooth_adapter_.get() && bluetooth_adapter_->IsPresent();
|
||||
}
|
||||
@ -1799,6 +1854,7 @@ void NearbySharingServiceImpl::StartScanning() {
|
||||
InvalidateReceiveSurfaceState();
|
||||
|
||||
ClearOutgoingShareTargetInfoMap();
|
||||
discovered_advertisements_to_retry_map_.clear();
|
||||
|
||||
nearby_connections_manager_->StartDiscovery(
|
||||
/*listener=*/this, settings_.GetDataUsage(),
|
||||
@ -1818,6 +1874,9 @@ NearbySharingService::StatusCodes NearbySharingServiceImpl::StopScanning() {
|
||||
nearby_connections_manager_->StopDiscovery();
|
||||
is_scanning_ = false;
|
||||
|
||||
certificate_download_during_discovery_timer_.Stop();
|
||||
discovered_advertisements_to_retry_map_.clear();
|
||||
|
||||
// Note: We don't know if we stopped scanning in preparation to send a file,
|
||||
// or we stopped because the user left the page. We'll invalidate after a
|
||||
// short delay.
|
||||
@ -3711,6 +3770,10 @@ void NearbySharingServiceImpl::OnStartDiscoveryResult(
|
||||
NS_LOG(VERBOSE)
|
||||
<< __func__
|
||||
<< ": StartDiscovery over Nearby Connections was successful.";
|
||||
|
||||
// Periodically download certificates if there are discovered, contact-based
|
||||
// advertisements that cannot decrypt any currently stored certificates.
|
||||
ScheduleCertificateDownloadDuringDiscovery(/*attempt_count=*/0);
|
||||
} else {
|
||||
NS_LOG(ERROR) << __func__
|
||||
<< ": StartDiscovery over Nearby Connections failed: "
|
||||
|
@ -191,11 +191,15 @@ class NearbySharingServiceImpl
|
||||
void FinishEndpointDiscoveryEvent();
|
||||
void OnOutgoingAdvertisementDecoded(
|
||||
const std::string& endpoint_id,
|
||||
const std::vector<uint8_t>& endpoint_info,
|
||||
sharing::mojom::AdvertisementPtr advertisement);
|
||||
void OnOutgoingDecryptedCertificate(
|
||||
const std::string& endpoint_id,
|
||||
const std::vector<uint8_t>& endpoint_info,
|
||||
sharing::mojom::AdvertisementPtr advertisement,
|
||||
base::Optional<NearbyShareDecryptedPublicCertificate> certificate);
|
||||
void ScheduleCertificateDownloadDuringDiscovery(size_t attempt_count);
|
||||
void OnCertificateDownloadDuringDiscoveryTimerFired(size_t attempt_count);
|
||||
|
||||
bool IsBluetoothPresent() const;
|
||||
bool IsBluetoothPowered() const;
|
||||
@ -384,6 +388,7 @@ class NearbySharingServiceImpl
|
||||
NearbyFileHandler file_handler_;
|
||||
bool is_screen_locked_ = false;
|
||||
base::OneShotTimer rotate_background_advertisement_timer_;
|
||||
base::OneShotTimer certificate_download_during_discovery_timer_;
|
||||
base::OneShotTimer process_shutdown_pending_timer_;
|
||||
|
||||
// A list of service observers.
|
||||
@ -432,6 +437,12 @@ class NearbySharingServiceImpl
|
||||
// For metrics. The IDs of ShareTargets that are cancelled while trying to
|
||||
// establish an outgoing connection.
|
||||
base::flat_set<base::UnguessableToken> cancelled_share_target_ids_;
|
||||
// A map from endpoint ID to endpoint info from discovered, contact-based
|
||||
// advertisements that could not decrypt any available public certificates.
|
||||
// During discovery, if certificates are downloaded, we revist this map and
|
||||
// retry certificate decryption.
|
||||
base::flat_map<std::string, std::vector<uint8_t>>
|
||||
discovered_advertisements_to_retry_map_;
|
||||
|
||||
// A mapping of Attachment Id to additional AttachmentInfo related to the
|
||||
// Attachment.
|
||||
|
@ -235,6 +235,10 @@ constexpr int kPayloadSize = 1;
|
||||
const std::vector<int64_t> kValidIntroductionFramePayloadIds = {1, 2, 3,
|
||||
kFilePayloadId};
|
||||
|
||||
constexpr size_t kMaxCertificateDownloadsDuringDiscovery = 3u;
|
||||
constexpr base::TimeDelta kCertificateDownloadDuringDiscoveryPeriod =
|
||||
base::TimeDelta::FromSeconds(10);
|
||||
|
||||
bool FileExists(const base::FilePath& file_path) {
|
||||
base::ScopedAllowBlockingForTesting allow_blocking;
|
||||
return base::PathExists(file_path);
|
||||
@ -605,6 +609,7 @@ class NearbySharingServiceImplTest : public testing::Test {
|
||||
|
||||
void SetUpAdvertisementDecoder(const std::vector<uint8_t>& endpoint_info,
|
||||
bool return_empty_advertisement,
|
||||
bool return_empty_device_name,
|
||||
size_t expected_number_of_calls) {
|
||||
EXPECT_CALL(mock_decoder_,
|
||||
DecodeAdvertisement(testing::Eq(endpoint_info), testing::_))
|
||||
@ -618,11 +623,15 @@ class NearbySharingServiceImplTest : public testing::Test {
|
||||
return;
|
||||
}
|
||||
|
||||
base::Optional<std::string> device_name;
|
||||
if (!return_empty_device_name)
|
||||
device_name = kDeviceName;
|
||||
|
||||
sharing::mojom::AdvertisementPtr advertisement =
|
||||
sharing::mojom::Advertisement::New(
|
||||
GetNearbyShareTestEncryptedMetadataKey().salt(),
|
||||
GetNearbyShareTestEncryptedMetadataKey().encrypted_key(),
|
||||
kDeviceType, kDeviceName);
|
||||
kDeviceType, device_name);
|
||||
std::move(callback).Run(std::move(advertisement));
|
||||
}));
|
||||
}
|
||||
@ -662,6 +671,7 @@ class NearbySharingServiceImplTest : public testing::Test {
|
||||
kToken);
|
||||
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
|
||||
/*return_empty_advertisement=*/false,
|
||||
/*return_empty_device_name=*/false,
|
||||
/*expected_number_of_calls=*/1u);
|
||||
SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/false);
|
||||
|
||||
@ -714,6 +724,7 @@ class NearbySharingServiceImplTest : public testing::Test {
|
||||
// Ensure decoder parses a valid endpoint advertisement.
|
||||
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
|
||||
/*return_empty_advertisement=*/false,
|
||||
/*return_empty_device_name=*/false,
|
||||
/*expected_number_of_calls=*/1u);
|
||||
|
||||
// Start discovering, to ensure a discovery listener is registered.
|
||||
@ -881,6 +892,17 @@ class NearbySharingServiceImplTest : public testing::Test {
|
||||
*fake_nearby_connections_manager_->advertising_endpoint_info()));
|
||||
}
|
||||
|
||||
void FindEndpoint(const std::string& endpoint_id) {
|
||||
fake_nearby_connections_manager_->OnEndpointFound(
|
||||
endpoint_id,
|
||||
location::nearby::connections::mojom::DiscoveredEndpointInfo::New(
|
||||
kValidV1EndpointInfo, kServiceId));
|
||||
}
|
||||
|
||||
void LoseEndpoint(const std::string& endpoint_id) {
|
||||
fake_nearby_connections_manager_->OnEndpointLost(endpoint_id);
|
||||
}
|
||||
|
||||
protected:
|
||||
FakeNearbyShareLocalDeviceDataManager* local_device_data_manager() {
|
||||
EXPECT_EQ(1u, local_device_data_manager_factory_.instances().size());
|
||||
@ -1316,6 +1338,7 @@ TEST_F(NearbySharingServiceImplTest,
|
||||
// Ensure decoder parses a valid endpoint advertisement.
|
||||
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
|
||||
/*return_empty_advertisement=*/false,
|
||||
/*return_empty_device_name=*/false,
|
||||
/*expected_number_of_calls=*/1u);
|
||||
|
||||
// Start discovering, to ensure a discovery listener is registered.
|
||||
@ -1379,6 +1402,7 @@ TEST_F(NearbySharingServiceImplTest, RegisterSendSurfaceEmptyCertificate) {
|
||||
// Ensure decoder parses a valid endpoint advertisement.
|
||||
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
|
||||
/*return_empty_advertisement=*/false,
|
||||
/*return_empty_device_name=*/false,
|
||||
/*expected_number_of_calls=*/1u);
|
||||
|
||||
// Start discovering, to ensure a discovery listener is registered.
|
||||
@ -2041,6 +2065,7 @@ TEST_F(NearbySharingServiceImplTest,
|
||||
kToken);
|
||||
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
|
||||
/*return_empty_advertisement=*/false,
|
||||
/*return_empty_device_name=*/false,
|
||||
/*expected_number_of_calls=*/1u);
|
||||
|
||||
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
|
||||
@ -2073,6 +2098,7 @@ TEST_F(NearbySharingServiceImplTest,
|
||||
kToken);
|
||||
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
|
||||
/*return_empty_advertisement=*/false,
|
||||
/*return_empty_device_name=*/false,
|
||||
/*expected_number_of_calls=*/1u);
|
||||
SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/true);
|
||||
|
||||
@ -2122,6 +2148,7 @@ TEST_F(NearbySharingServiceImplTest,
|
||||
kToken);
|
||||
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
|
||||
/*return_empty_advertisement=*/false,
|
||||
/*return_empty_device_name=*/false,
|
||||
/*expected_number_of_calls=*/1u);
|
||||
SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/false);
|
||||
|
||||
@ -2205,6 +2232,7 @@ TEST_F(NearbySharingServiceImplTest, IncomingConnection_OutOfStorage) {
|
||||
kToken);
|
||||
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
|
||||
/*return_empty_advertisement=*/false,
|
||||
/*return_empty_device_name=*/false,
|
||||
/*expected_number_of_calls=*/1u);
|
||||
|
||||
// Set a huge file size in introduction frame to go out of storage.
|
||||
@ -2277,6 +2305,7 @@ TEST_F(NearbySharingServiceImplTest, IncomingConnection_FileSizeOverflow) {
|
||||
kToken);
|
||||
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
|
||||
/*return_empty_advertisement=*/false,
|
||||
/*return_empty_device_name=*/false,
|
||||
/*expected_number_of_calls=*/1u);
|
||||
|
||||
// Set file size sum huge to check for overflow.
|
||||
@ -2352,6 +2381,7 @@ TEST_F(NearbySharingServiceImplTest,
|
||||
kToken);
|
||||
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
|
||||
/*return_empty_advertisement=*/false,
|
||||
/*return_empty_device_name=*/false,
|
||||
/*expected_number_of_calls=*/1u);
|
||||
SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/false);
|
||||
|
||||
@ -2940,6 +2970,7 @@ TEST_F(NearbySharingServiceImplTest,
|
||||
kToken);
|
||||
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
|
||||
/*return_empty_advertisement=*/false,
|
||||
/*return_empty_device_name=*/false,
|
||||
/*expected_number_of_calls=*/1u);
|
||||
SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/false);
|
||||
|
||||
@ -2993,6 +3024,7 @@ TEST_F(NearbySharingServiceImplTest,
|
||||
kToken);
|
||||
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
|
||||
/*return_empty_advertisement=*/false,
|
||||
/*return_empty_device_name=*/false,
|
||||
/*expected_number_of_calls=*/1u);
|
||||
SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/false);
|
||||
|
||||
@ -3050,6 +3082,7 @@ TEST_F(NearbySharingServiceImplTest,
|
||||
kToken);
|
||||
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
|
||||
/*return_empty_advertisement=*/false,
|
||||
/*return_empty_device_name=*/false,
|
||||
/*expected_number_of_calls=*/1u);
|
||||
|
||||
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
|
||||
@ -3084,6 +3117,7 @@ TEST_F(NearbySharingServiceImplTest,
|
||||
IncomingConnection_EmptyAuthToken_KeyVerificationRunnerStatusFail) {
|
||||
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
|
||||
/*return_empty_advertisement=*/false,
|
||||
/*return_empty_device_name=*/false,
|
||||
/*expected_number_of_calls=*/1u);
|
||||
|
||||
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
|
||||
@ -3665,16 +3699,12 @@ TEST_F(NearbySharingServiceImplTest, OrderedEndpointDiscoveryEvents) {
|
||||
// Expect the advertisement decoder to be invoked once for each discovery.
|
||||
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
|
||||
/*return_empty_advertisement=*/false,
|
||||
/*return_empty_device_name=*/false,
|
||||
/*expected_number_of_calls=*/3u);
|
||||
{
|
||||
base::RunLoop run_loop;
|
||||
fake_nearby_connections_manager_->OnEndpointFound(
|
||||
/*endpoint_id=*/"1",
|
||||
location::nearby::connections::mojom::DiscoveredEndpointInfo::New(
|
||||
kValidV1EndpointInfo, kServiceId));
|
||||
fake_nearby_connections_manager_->OnEndpointLost(
|
||||
/*endpoint_id=*/"1");
|
||||
|
||||
FindEndpoint(/*endpoint_id=*/"1");
|
||||
LoseEndpoint(/*endpoint_id=*/"1");
|
||||
::testing::InSequence s;
|
||||
EXPECT_CALL(discovery_callback, OnShareTargetDiscovered);
|
||||
EXPECT_CALL(discovery_callback, OnShareTargetLost)
|
||||
@ -3687,19 +3717,10 @@ TEST_F(NearbySharingServiceImplTest, OrderedEndpointDiscoveryEvents) {
|
||||
}
|
||||
{
|
||||
base::RunLoop run_loop;
|
||||
fake_nearby_connections_manager_->OnEndpointFound(
|
||||
/*endpoint_id=*/"2",
|
||||
location::nearby::connections::mojom::DiscoveredEndpointInfo::New(
|
||||
kValidV1EndpointInfo, kServiceId));
|
||||
fake_nearby_connections_manager_->OnEndpointFound(
|
||||
/*endpoint_id=*/"3",
|
||||
location::nearby::connections::mojom::DiscoveredEndpointInfo::New(
|
||||
kValidV1EndpointInfo, kServiceId));
|
||||
fake_nearby_connections_manager_->OnEndpointLost(
|
||||
/*endpoint_id=*/"3");
|
||||
fake_nearby_connections_manager_->OnEndpointLost(
|
||||
/*endpoint_id=*/"2");
|
||||
|
||||
FindEndpoint(/*endpoint_id=*/"2");
|
||||
FindEndpoint(/*endpoint_id=*/"3");
|
||||
LoseEndpoint(/*endpoint_id=*/"3");
|
||||
LoseEndpoint(/*endpoint_id=*/"2");
|
||||
::testing::InSequence s;
|
||||
EXPECT_CALL(discovery_callback, OnShareTargetDiscovered)
|
||||
.WillOnce([](ShareTarget share_target) {
|
||||
@ -3730,6 +3751,207 @@ TEST_F(NearbySharingServiceImplTest, OrderedEndpointDiscoveryEvents) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(NearbySharingServiceImplTest,
|
||||
RetryDiscoveredEndpoints_NoDownloadIfDecryption) {
|
||||
// Start discovery.
|
||||
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
|
||||
MockTransferUpdateCallback transfer_callback;
|
||||
MockShareTargetDiscoveredCallback discovery_callback;
|
||||
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
|
||||
SendSurfaceState::kForeground);
|
||||
EXPECT_EQ(1u,
|
||||
certificate_manager()->num_download_public_certificates_calls());
|
||||
EXPECT_TRUE(fake_nearby_connections_manager_->IsDiscovering());
|
||||
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
|
||||
/*return_empty_advertisement=*/false,
|
||||
/*return_empty_device_name=*/true,
|
||||
/*expected_number_of_calls=*/1u);
|
||||
// Order of events:
|
||||
// - Discover endpoint 1 --> decrypts public certificate
|
||||
// - Fire certificate download timer --> no download because no cached
|
||||
// advertisements
|
||||
{
|
||||
base::RunLoop run_loop;
|
||||
FindEndpoint(/*endpoint_id=*/"1");
|
||||
EXPECT_CALL(discovery_callback, OnShareTargetDiscovered)
|
||||
.WillOnce([&run_loop](ShareTarget share_target) { run_loop.Quit(); });
|
||||
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1,
|
||||
/*success=*/true);
|
||||
run_loop.Run();
|
||||
}
|
||||
task_environment_.FastForwardBy(kCertificateDownloadDuringDiscoveryPeriod);
|
||||
EXPECT_EQ(1u,
|
||||
certificate_manager()->num_download_public_certificates_calls());
|
||||
|
||||
EXPECT_CALL(discovery_callback, OnShareTargetLost);
|
||||
service_->Shutdown();
|
||||
service_.reset();
|
||||
}
|
||||
|
||||
TEST_F(NearbySharingServiceImplTest,
|
||||
RetryDiscoveredEndpoints_DownloadCertsAndRetryDecryption) {
|
||||
// Start discovery.
|
||||
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
|
||||
MockTransferUpdateCallback transfer_callback;
|
||||
MockShareTargetDiscoveredCallback discovery_callback;
|
||||
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
|
||||
SendSurfaceState::kForeground);
|
||||
EXPECT_EQ(1u,
|
||||
certificate_manager()->num_download_public_certificates_calls());
|
||||
EXPECT_TRUE(fake_nearby_connections_manager_->IsDiscovering());
|
||||
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
|
||||
/*return_empty_advertisement=*/false,
|
||||
/*return_empty_device_name=*/true,
|
||||
/*expected_number_of_calls=*/6u);
|
||||
// Order of events:
|
||||
// - Discover endpoint 1 --> decrypts public certificate
|
||||
// - Discover endpoint 2 --> cannot decrypt public certificate
|
||||
// - Discover endpoint 3 --> decrypts public certificate
|
||||
// - Discover endpoint 4 --> cannot decrypt public certificate
|
||||
// - Lose endpoint 3
|
||||
// - Fire certificate download timer --> certificates downloaded
|
||||
// - (Re)discover endpoints 2 and 4
|
||||
{
|
||||
base::RunLoop run_loop;
|
||||
FindEndpoint(/*endpoint_id=*/"1");
|
||||
FindEndpoint(/*endpoint_id=*/"2");
|
||||
FindEndpoint(/*endpoint_id=*/"3");
|
||||
FindEndpoint(/*endpoint_id=*/"4");
|
||||
LoseEndpoint(/*endpoint_id=*/"3");
|
||||
::testing::InSequence s;
|
||||
EXPECT_CALL(discovery_callback, OnShareTargetDiscovered).Times(2);
|
||||
EXPECT_CALL(discovery_callback, OnShareTargetLost)
|
||||
.WillOnce([&run_loop](ShareTarget share_target) { run_loop.Quit(); });
|
||||
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1,
|
||||
/*success=*/true);
|
||||
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/2,
|
||||
/*success=*/false);
|
||||
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/3,
|
||||
/*success=*/true);
|
||||
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/4,
|
||||
/*success=*/false);
|
||||
run_loop.Run();
|
||||
}
|
||||
task_environment_.FastForwardBy(kCertificateDownloadDuringDiscoveryPeriod);
|
||||
EXPECT_EQ(2u,
|
||||
certificate_manager()->num_download_public_certificates_calls());
|
||||
certificate_manager()->NotifyPublicCertificatesDownloaded();
|
||||
{
|
||||
base::RunLoop run_loop;
|
||||
::testing::InSequence s;
|
||||
EXPECT_CALL(discovery_callback, OnShareTargetDiscovered);
|
||||
EXPECT_CALL(discovery_callback, OnShareTargetDiscovered)
|
||||
.WillOnce([&run_loop](ShareTarget share_target) { run_loop.Quit(); });
|
||||
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/5,
|
||||
/*success=*/true);
|
||||
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/6,
|
||||
/*success=*/true);
|
||||
run_loop.Run();
|
||||
}
|
||||
EXPECT_CALL(discovery_callback, OnShareTargetLost).Times(3);
|
||||
service_->Shutdown();
|
||||
service_.reset();
|
||||
}
|
||||
|
||||
TEST_F(NearbySharingServiceImplTest,
|
||||
RetryDiscoveredEndpoints_DiscoveryRestartClearsCache) {
|
||||
// Start discovery.
|
||||
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
|
||||
MockTransferUpdateCallback transfer_callback;
|
||||
MockShareTargetDiscoveredCallback discovery_callback;
|
||||
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
|
||||
SendSurfaceState::kForeground);
|
||||
EXPECT_EQ(1u,
|
||||
certificate_manager()->num_download_public_certificates_calls());
|
||||
EXPECT_TRUE(fake_nearby_connections_manager_->IsDiscovering());
|
||||
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
|
||||
/*return_empty_advertisement=*/false,
|
||||
/*return_empty_device_name=*/true,
|
||||
/*expected_number_of_calls=*/1u);
|
||||
// Order of events:
|
||||
// - Discover endpoint 1 --> cannot decrypt public certificate
|
||||
// - Stop discovery
|
||||
// - Certificate download timer not running; not discovering
|
||||
// - Start discovery
|
||||
// - Fire certificate download timer --> certificates not downloaded; cached
|
||||
// advertisement map has been cleared
|
||||
FindEndpoint(/*endpoint_id=*/"1");
|
||||
::testing::InSequence s;
|
||||
EXPECT_CALL(discovery_callback, OnShareTargetDiscovered).Times(0);
|
||||
EXPECT_CALL(discovery_callback, OnShareTargetLost).Times(0);
|
||||
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1,
|
||||
/*success=*/false);
|
||||
service_->UnregisterSendSurface(&transfer_callback, &discovery_callback);
|
||||
task_environment_.FastForwardBy(kCertificateDownloadDuringDiscoveryPeriod);
|
||||
EXPECT_EQ(1u,
|
||||
certificate_manager()->num_download_public_certificates_calls());
|
||||
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
|
||||
SendSurfaceState::kForeground);
|
||||
// Note: Certificate downloads are also requested in RegisterSendSurface; this
|
||||
// is not related to the retry timer.
|
||||
EXPECT_EQ(2u,
|
||||
certificate_manager()->num_download_public_certificates_calls());
|
||||
EXPECT_TRUE(fake_nearby_connections_manager_->IsDiscovering());
|
||||
task_environment_.FastForwardBy(kCertificateDownloadDuringDiscoveryPeriod);
|
||||
EXPECT_EQ(2u,
|
||||
certificate_manager()->num_download_public_certificates_calls());
|
||||
service_->Shutdown();
|
||||
service_.reset();
|
||||
}
|
||||
|
||||
TEST_F(NearbySharingServiceImplTest, RetryDiscoveredEndpoints_DownloadLimit) {
|
||||
// Start discovery.
|
||||
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
|
||||
MockTransferUpdateCallback transfer_callback;
|
||||
MockShareTargetDiscoveredCallback discovery_callback;
|
||||
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
|
||||
SendSurfaceState::kForeground);
|
||||
EXPECT_EQ(1u,
|
||||
certificate_manager()->num_download_public_certificates_calls());
|
||||
EXPECT_TRUE(fake_nearby_connections_manager_->IsDiscovering());
|
||||
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
|
||||
/*return_empty_advertisement=*/false,
|
||||
/*return_empty_device_name=*/true,
|
||||
/*expected_number_of_calls=*/2u +
|
||||
kMaxCertificateDownloadsDuringDiscovery);
|
||||
// Order of events:
|
||||
// - x3:
|
||||
// - (Re)discover endpoint 1 --> cannot decrypt public certificate
|
||||
// - Fire certificate download timer --> certificates downloaded
|
||||
// - Rediscover endpoint 1 --> cannot decrypt public certificate
|
||||
// - Fire certificate download timer --> no download; limit reached
|
||||
// - Restart discovery which resets limit counter
|
||||
FindEndpoint(/*endpoint_id=*/"1");
|
||||
for (size_t i = 1; i <= kMaxCertificateDownloadsDuringDiscovery; ++i) {
|
||||
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/i,
|
||||
/*success=*/false);
|
||||
task_environment_.FastForwardBy(kCertificateDownloadDuringDiscoveryPeriod);
|
||||
EXPECT_EQ(1u + i,
|
||||
certificate_manager()->num_download_public_certificates_calls());
|
||||
certificate_manager()->NotifyPublicCertificatesDownloaded();
|
||||
}
|
||||
task_environment_.FastForwardBy(kCertificateDownloadDuringDiscoveryPeriod);
|
||||
EXPECT_EQ(1u + kMaxCertificateDownloadsDuringDiscovery,
|
||||
certificate_manager()->num_download_public_certificates_calls());
|
||||
service_->UnregisterSendSurface(&transfer_callback, &discovery_callback);
|
||||
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
|
||||
SendSurfaceState::kForeground);
|
||||
// Note: Certificate downloads are also requested in RegisterSendSurface; this
|
||||
// is not related to the retry timer.
|
||||
EXPECT_EQ(2u + kMaxCertificateDownloadsDuringDiscovery,
|
||||
certificate_manager()->num_download_public_certificates_calls());
|
||||
FindEndpoint(/*endpoint_id=*/"1");
|
||||
ProcessLatestPublicCertificateDecryption(
|
||||
/*expected_num_calls=*/1u + kMaxCertificateDownloadsDuringDiscovery,
|
||||
/*success=*/false);
|
||||
task_environment_.FastForwardBy(kCertificateDownloadDuringDiscoveryPeriod);
|
||||
EXPECT_EQ(3u + kMaxCertificateDownloadsDuringDiscovery,
|
||||
certificate_manager()->num_download_public_certificates_calls());
|
||||
|
||||
service_->Shutdown();
|
||||
service_.reset();
|
||||
}
|
||||
|
||||
using ServiceRestartTestParams = std::tuple<bool, NearbyProcessShutdownReason>;
|
||||
|
||||
class NearbySharingServiceRestartTest
|
||||
|
Reference in New Issue
Block a user