Commit fa869e00 authored by Naomi Musgrave's avatar Naomi Musgrave Committed by Commit Bot

Implement the send surface in NearbySharingService.

Track share targets as they are (un)registered, and start scanning.
Only handles surfaces registered to the foreground for now.

Bug: 1084644
Change-Id: I852388f8dd1d355263979d94f2959cc79f905929
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2292214
Commit-Queue: Naomi Musgrave <nmusgrave@chromium.org>
Reviewed-by: default avatarRichard Knoll <knollr@chromium.org>
Reviewed-by: default avatarAlex Chau <alexchau@chromium.org>
Cr-Commit-Position: refs/heads/master@{#796384}
parent b4283204
...@@ -110,6 +110,23 @@ void FakeNearbyConnectionsManager::UpgradeBandwidth( ...@@ -110,6 +110,23 @@ void FakeNearbyConnectionsManager::UpgradeBandwidth(
upgrade_bandwidth_endpoint_ids_.insert(endpoint_id); upgrade_bandwidth_endpoint_ids_.insert(endpoint_id);
} }
void FakeNearbyConnectionsManager::OnEndpointFound(
const std::string& endpoint_id,
location::nearby::connections::mojom::DiscoveredEndpointInfoPtr info) {
if (!discovery_listener_)
return;
discovery_listener_->OnEndpointDiscovered(endpoint_id, info->endpoint_info);
}
void FakeNearbyConnectionsManager::OnEndpointLost(
const std::string& endpoint_id) {
if (!discovery_listener_)
return;
discovery_listener_->OnEndpointLost(endpoint_id);
}
bool FakeNearbyConnectionsManager::IsAdvertising() { bool FakeNearbyConnectionsManager::IsAdvertising() {
return advertising_listener_ != nullptr; return advertising_listener_ != nullptr;
} }
......
...@@ -12,11 +12,13 @@ ...@@ -12,11 +12,13 @@
#include <vector> #include <vector>
#include "chrome/browser/nearby_sharing/nearby_connections_manager.h" #include "chrome/browser/nearby_sharing/nearby_connections_manager.h"
#include "chrome/services/sharing/public/mojom/nearby_connections.mojom.h"
// Fake NearbyConnectionsManager for testing. // Fake NearbyConnectionsManager for testing.
class FakeNearbyConnectionsManager : public NearbyConnectionsManager { class FakeNearbyConnectionsManager
: public NearbyConnectionsManager,
public location::nearby::connections::mojom::EndpointDiscoveryListener {
public: public:
FakeNearbyConnectionsManager(); FakeNearbyConnectionsManager();
~FakeNearbyConnectionsManager() override; ~FakeNearbyConnectionsManager() override;
...@@ -50,6 +52,13 @@ class FakeNearbyConnectionsManager : public NearbyConnectionsManager { ...@@ -50,6 +52,13 @@ class FakeNearbyConnectionsManager : public NearbyConnectionsManager {
const std::string& endpoint_id) override; const std::string& endpoint_id) override;
void UpgradeBandwidth(const std::string& endpoint_id) override; void UpgradeBandwidth(const std::string& endpoint_id) override;
// mojom::EndpointDiscoveryListener:
void OnEndpointFound(
const std::string& endpoint_id,
location::nearby::connections::mojom::DiscoveredEndpointInfoPtr info)
override;
void OnEndpointLost(const std::string& endpoint_id) override;
// Testing methods // Testing methods
bool IsAdvertising(); bool IsAdvertising();
bool IsDiscovering(); bool IsDiscovering();
......
...@@ -33,6 +33,14 @@ class NearbySharingService : public KeyedService { ...@@ -33,6 +33,14 @@ class NearbySharingService : public KeyedService {
kOk, kOk,
// The operation failed since it was called in an invalid order. // The operation failed since it was called in an invalid order.
kOutOfOrderApiCall, kOutOfOrderApiCall,
// Tried to stop something that was already stopped.
kStatusAlreadyStopped,
// Tried to register an opposite foreground surface in the midst of a
// transfer or connection.
// (Tried to register Send Surface when receiving a file or tried to
// register Receive Surface when
// sending a file.)
kTransferAlreadyInProgress,
}; };
enum class ReceiveSurfaceState { enum class ReceiveSurfaceState {
......
...@@ -7,8 +7,10 @@ ...@@ -7,8 +7,10 @@
#include <utility> #include <utility>
#include "base/bind.h" #include "base/bind.h"
#include "base/logging.h"
#include "base/task/post_task.h"
#include "base/task_runner_util.h" #include "base/task_runner_util.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/sequenced_task_runner_handle.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/client/nearby_share_client_impl.h" #include "chrome/browser/nearby_sharing/client/nearby_share_client_impl.h"
#include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h" #include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h"
...@@ -34,6 +36,9 @@ constexpr base::TimeDelta kReadResponseFrameTimeout = ...@@ -34,6 +36,9 @@ constexpr base::TimeDelta kReadResponseFrameTimeout =
base::TimeDelta::FromSeconds(60); base::TimeDelta::FromSeconds(60);
constexpr base::TimeDelta kIncomingRejectionDelay = constexpr base::TimeDelta kIncomingRejectionDelay =
base::TimeDelta::FromSeconds(2); base::TimeDelta::FromSeconds(2);
// Time to delay running the task to invalidate send and receive surfaces.
constexpr base::TimeDelta kInvalidateDelay =
base::TimeDelta::FromMilliseconds(500);
std::string ReceiveSurfaceStateToString( std::string ReceiveSurfaceStateToString(
NearbySharingService::ReceiveSurfaceState state) { NearbySharingService::ReceiveSurfaceState state) {
...@@ -130,8 +135,7 @@ NearbySharingServiceImpl::NearbySharingServiceImpl( ...@@ -130,8 +135,7 @@ NearbySharingServiceImpl::NearbySharingServiceImpl(
Profile* profile, Profile* profile,
std::unique_ptr<NearbyConnectionsManager> nearby_connections_manager, std::unique_ptr<NearbyConnectionsManager> nearby_connections_manager,
NearbyProcessManager* process_manager) NearbyProcessManager* process_manager)
: prefs_(prefs), : profile_(profile),
profile_(profile),
settings_(prefs), settings_(prefs),
nearby_connections_manager_(std::move(nearby_connections_manager)), nearby_connections_manager_(std::move(nearby_connections_manager)),
process_manager_(process_manager), process_manager_(process_manager),
...@@ -146,7 +150,6 @@ NearbySharingServiceImpl::NearbySharingServiceImpl( ...@@ -146,7 +150,6 @@ NearbySharingServiceImpl::NearbySharingServiceImpl(
contact_manager_(NearbyShareContactManagerImpl::Factory::Create()), contact_manager_(NearbyShareContactManagerImpl::Factory::Create()),
certificate_manager_( certificate_manager_(
NearbyShareCertificateManagerImpl::Factory::Create()) { NearbyShareCertificateManagerImpl::Factory::Create()) {
DCHECK(prefs_);
DCHECK(profile_); DCHECK(profile_);
DCHECK(nearby_connections_manager_); DCHECK(nearby_connections_manager_);
...@@ -178,7 +181,61 @@ NearbySharingService::StatusCodes NearbySharingServiceImpl::RegisterSendSurface( ...@@ -178,7 +181,61 @@ NearbySharingService::StatusCodes NearbySharingServiceImpl::RegisterSendSurface(
ShareTargetDiscoveredCallback* discovery_callback, ShareTargetDiscoveredCallback* discovery_callback,
SendSurfaceState state) { SendSurfaceState state) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// TODO(crrbug.com/1084644): Implement send surface logic. DCHECK(transfer_callback);
DCHECK(discovery_callback);
DCHECK_NE(state, SendSurfaceState::kUnknown);
if (!process_manager_->IsActiveProfile(profile_)) {
NS_LOG(VERBOSE) << __func__
<< ": RegisterSendSurface failed, since profile not active";
return StatusCodes::kError;
}
if (foreground_send_transfer_callbacks_.HasObserver(transfer_callback) ||
background_send_transfer_callbacks_.HasObserver(transfer_callback)) {
NS_LOG(VERBOSE) << __func__
<< ": RegisterSendSurface failed. Already registered.";
return StatusCodes::kError;
}
if (state == SendSurfaceState::kForeground) {
foreground_send_transfer_callbacks_.AddObserver(transfer_callback);
foreground_send_discovery_callbacks_.AddObserver(discovery_callback);
} else {
background_send_transfer_callbacks_.AddObserver(transfer_callback);
background_send_discovery_callbacks_.AddObserver(discovery_callback);
}
NS_LOG(VERBOSE) << __func__ << ": RegisterSendSurface";
if (is_receiving_files_) {
UnregisterSendSurface(transfer_callback, discovery_callback);
NS_LOG(VERBOSE)
<< __func__
<< ": Ignore registering (and unregistering if registered) send "
"surface because we're currently receiving files.";
return StatusCodes::kTransferAlreadyInProgress;
}
// If the share sheet to be registered is a foreground surface, let it catch
// up with most recent transfer metadata immediately.
if (state == SendSurfaceState::kForeground && last_outgoing_metadata_) {
// When a new share sheet is registered, we want to immediately show the
// in-progress bar.
discovery_callback->OnShareTargetDiscovered(last_outgoing_metadata_->first);
transfer_callback->OnTransferUpdate(last_outgoing_metadata_->first,
last_outgoing_metadata_->second);
}
// Let newly registered send surface catch up with discovered share targets
// from current scanning session.
for (const std::pair<std::string, ShareTarget>& item :
outgoing_share_target_map_) {
discovery_callback->OnShareTargetDiscovered(item.second);
}
NS_LOG(VERBOSE) << __func__ << ": A SendSurface has been registered.";
InvalidateSendSurfaceState();
if (state == SendSurfaceState::kForeground) if (state == SendSurfaceState::kForeground)
StartFastInitiationAdvertising(); StartFastInitiationAdvertising();
return StatusCodes::kOk; return StatusCodes::kOk;
...@@ -189,6 +246,46 @@ NearbySharingServiceImpl::UnregisterSendSurface( ...@@ -189,6 +246,46 @@ NearbySharingServiceImpl::UnregisterSendSurface(
TransferUpdateCallback* transfer_callback, TransferUpdateCallback* transfer_callback,
ShareTargetDiscoveredCallback* discovery_callback) { ShareTargetDiscoveredCallback* discovery_callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(transfer_callback);
DCHECK(discovery_callback);
if (!foreground_send_transfer_callbacks_.HasObserver(transfer_callback) &&
!background_send_transfer_callbacks_.HasObserver(transfer_callback)) {
NS_LOG(VERBOSE)
<< __func__
<< ": unregisterSendSurface failed. Unknown TransferUpdateCallback";
return StatusCodes::kError;
}
if (foreground_send_transfer_callbacks_.might_have_observers() &&
last_outgoing_metadata_ &&
last_outgoing_metadata_->second.is_final_status()) {
// We already saw the final status in the foreground
// Nullify it so the next time the user opens sharing, it starts the UI from
// the beginning
last_outgoing_metadata_.reset();
}
if (foreground_send_transfer_callbacks_.HasObserver(transfer_callback)) {
foreground_send_transfer_callbacks_.RemoveObserver(transfer_callback);
foreground_send_discovery_callbacks_.RemoveObserver(discovery_callback);
} else {
background_send_transfer_callbacks_.RemoveObserver(transfer_callback);
background_send_discovery_callbacks_.RemoveObserver(discovery_callback);
}
// Displays the most recent payload status processed by foreground surfaces on
// background surfaces.
if (!foreground_send_transfer_callbacks_.might_have_observers() &&
last_outgoing_metadata_) {
for (TransferUpdateCallback& background_transfer_callback :
background_send_transfer_callbacks_) {
background_transfer_callback.OnTransferUpdate(
last_outgoing_metadata_->first, last_outgoing_metadata_->second);
}
}
NS_LOG(VERBOSE) << __func__ << ": A SendSurface has been unregistered";
InvalidateSurfaceState();
StopFastInitiationAdvertising(); StopFastInitiationAdvertising();
return StatusCodes::kOk; return StatusCodes::kOk;
} }
...@@ -200,6 +297,14 @@ NearbySharingServiceImpl::RegisterReceiveSurface( ...@@ -200,6 +297,14 @@ NearbySharingServiceImpl::RegisterReceiveSurface(
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(transfer_callback); DCHECK(transfer_callback);
DCHECK_NE(state, ReceiveSurfaceState::kUnknown); DCHECK_NE(state, ReceiveSurfaceState::kUnknown);
if (!process_manager_->IsActiveProfile(profile_)) {
NS_LOG(VERBOSE)
<< __func__
<< ": registerReceiveSurface failed, since profile not active";
return StatusCodes::kError;
}
if (foreground_receive_callbacks_.HasObserver(transfer_callback) || if (foreground_receive_callbacks_.HasObserver(transfer_callback) ||
background_receive_callbacks_.HasObserver(transfer_callback)) { background_receive_callbacks_.HasObserver(transfer_callback)) {
NS_LOG(VERBOSE) << __func__ NS_LOG(VERBOSE) << __func__
...@@ -272,8 +377,7 @@ NearbySharingServiceImpl::UnregisterReceiveSurface( ...@@ -272,8 +377,7 @@ NearbySharingServiceImpl::UnregisterReceiveSurface(
NS_LOG(VERBOSE) << __func__ << ": A ReceiveSurface(" NS_LOG(VERBOSE) << __func__ << ": A ReceiveSurface("
<< (is_foreground ? "foreground" : "background") << (is_foreground ? "foreground" : "background")
<< ") has been unregistered"; << ") has been unregistered";
InvalidateSurfaceState();
InvalidateReceiveSurfaceState();
return StatusCodes::kOk; return StatusCodes::kOk;
} }
...@@ -363,6 +467,8 @@ NearbyShareSettings* NearbySharingServiceImpl::GetSettings() { ...@@ -363,6 +467,8 @@ NearbyShareSettings* NearbySharingServiceImpl::GetSettings() {
void NearbySharingServiceImpl::OnNearbyProfileChanged(Profile* profile) { void NearbySharingServiceImpl::OnNearbyProfileChanged(Profile* profile) {
// TODO(crbug.com/1084576): Notify UI about the new active profile. // TODO(crbug.com/1084576): Notify UI about the new active profile.
NS_LOG(VERBOSE) << __func__ << ": Nearby profile changed to "
<< process_manager_->IsActiveProfile(profile_);
} }
void NearbySharingServiceImpl::OnNearbyProcessStarted() { void NearbySharingServiceImpl::OnNearbyProcessStarted() {
...@@ -384,7 +490,6 @@ void NearbySharingServiceImpl::OnIncomingConnection( ...@@ -384,7 +490,6 @@ void NearbySharingServiceImpl::OnIncomingConnection(
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(connection); DCHECK(connection);
// TODO(crbug/1085068): Handle incoming connection; use CertificateManager // TODO(crbug/1085068): Handle incoming connection; use CertificateManager
// TODO(himanshujaju) - Update placeholder implementation // TODO(himanshujaju) - Update placeholder implementation
ShareTarget share_target; ShareTarget share_target;
share_target.is_incoming = true; share_target.is_incoming = true;
...@@ -398,15 +503,128 @@ void NearbySharingServiceImpl::OnIncomingConnection( ...@@ -398,15 +503,128 @@ void NearbySharingServiceImpl::OnIncomingConnection(
ReceiveIntroduction(std::move(share_target), /*token=*/base::nullopt); ReceiveIntroduction(std::move(share_target), /*token=*/base::nullopt);
} }
void NearbySharingServiceImpl::OnEndpointDiscovered(
const std::string& endpoint_id,
const std::vector<uint8_t>& endpoint_info) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!is_scanning_) {
NS_LOG(VERBOSE)
<< __func__
<< ": Ignoring discovered endpoint because we're no longer scanning";
return;
}
process_manager_->GetOrStartNearbySharingDecoder(profile_)
->DecodeAdvertisement(
endpoint_info,
base::BindOnce(
&NearbySharingServiceImpl::OnOutgoingAdvertisementDecoded,
weak_ptr_factory_.GetWeakPtr(), endpoint_id));
}
void NearbySharingServiceImpl::OnOutgoingAdvertisementDecoded(
const std::string& endpoint_id,
sharing::mojom::AdvertisementPtr advertisement) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!advertisement) {
NS_LOG(VERBOSE) << __func__
<< ": Failed to parse discovered advertisement.";
return;
}
// Now we will report endpoints met before in NearbyConnectionsManager.
// Check outgoingShareTargetInfoMap first and pass the same shareTarget if we
// found one.
// Looking for the ShareTarget based on endpoint id.
if (outgoing_share_target_map_.find(endpoint_id) !=
outgoing_share_target_map_.end()) {
return;
}
// Once get the advertisement, first thing to do is to decrypt its device name
// based on its visibility and create a ShareTarget to represent this remote
// device.
base::Optional<ShareTarget> share_target =
CreateShareTarget(endpoint_id, std::move(advertisement),
/*is_incoming=*/false);
if (!share_target) {
NS_LOG(VERBOSE) << __func__
<< ": Failed to convert advertisement to share target from "
"discovered advertisement. Ignoring endpoint.";
return;
}
// Update the endpoint id for the share target.
NS_LOG(VERBOSE) << __func__
<< ": An endpoint has been discovered, with an advertisement "
"containing a valid share target.";
GetOrCreateOutgoingShareTargetInfo(*share_target, endpoint_id)
.set_endpoint_id(endpoint_id);
// Notifies the user that we discovered a device.
for (ShareTargetDiscoveredCallback& discovery_callback :
foreground_send_discovery_callbacks_) {
discovery_callback.OnShareTargetDiscovered(*share_target);
}
for (ShareTargetDiscoveredCallback& discovery_callback :
background_send_discovery_callbacks_) {
discovery_callback.OnShareTargetDiscovered(*share_target);
}
NS_LOG(VERBOSE) << __func__ << ": Reported OnShareTargetDiscovered "
<< (base::Time::Now() - scanning_start_timestamp_);
// TODO(crbug/1108348) CachingManager should cache known and non-external
// share targets.
}
void NearbySharingServiceImpl::OnEndpointLost(const std::string& endpoint_id) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!is_scanning_) {
NS_LOG(VERBOSE)
<< __func__
<< ": Ignoring lost endpoint because we're no longer scanning";
return;
}
// Remove the share target with this endpoint id.
auto it = outgoing_share_target_map_.find(endpoint_id);
if (it == outgoing_share_target_map_.end()) {
NS_LOG(VERBOSE) << __func__
<< ": Ignoring lost endpoint because we don't have an "
"associated ShareTarget";
return;
}
ShareTarget share_target = std::move(it->second);
outgoing_share_target_info_map_.erase(share_target.id);
outgoing_share_target_map_.erase(it);
for (ShareTargetDiscoveredCallback& discovery_callback :
foreground_send_discovery_callbacks_) {
discovery_callback.OnShareTargetLost(share_target);
}
for (ShareTargetDiscoveredCallback& discovery_callback :
background_send_discovery_callbacks_) {
discovery_callback.OnShareTargetLost(share_target);
}
NS_LOG(VERBOSE) << __func__ << ": Reported onShareTargetLost";
}
void NearbySharingServiceImpl::OnEnabledChanged(bool enabled) { void NearbySharingServiceImpl::OnEnabledChanged(bool enabled) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (enabled) { if (enabled) {
NS_LOG(VERBOSE) << __func__ << ": Nearby sharing enabled!"; NS_LOG(VERBOSE) << __func__ << ": Nearby sharing enabled!";
} else { } else {
NS_LOG(VERBOSE) << __func__ << ": Nearby sharing disabled!"; NS_LOG(VERBOSE) << __func__ << ": Nearby sharing disabled!";
StopAdvertising(); StopAdvertising();
StopScanning();
// TODO(crbug/1085067): Stop discovery. // TODO(crbug/1085067): Stop discovery.
nearby_connections_manager_->Shutdown(); nearby_connections_manager_->Shutdown();
} }
InvalidateSurfaceState();
} }
void NearbySharingServiceImpl::FlushMojoForTesting() { void NearbySharingServiceImpl::FlushMojoForTesting() {
...@@ -437,25 +655,43 @@ bool NearbySharingServiceImpl::IsVisibleInBackground(Visibility visibility) { ...@@ -437,25 +655,43 @@ bool NearbySharingServiceImpl::IsVisibleInBackground(Visibility visibility) {
} }
void NearbySharingServiceImpl::OnVisibilityChanged(Visibility new_visibility) { void NearbySharingServiceImpl::OnVisibilityChanged(Visibility new_visibility) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
NS_LOG(VERBOSE) << __func__ << ": Nearby sharing visibility changed to " NS_LOG(VERBOSE) << __func__ << ": Nearby sharing visibility changed to "
<< VisibilityToString(new_visibility); << VisibilityToString(new_visibility);
if (advertising_power_level_ != PowerLevel::kUnknown)
if (advertising_power_level_ != PowerLevel::kUnknown) {
StopAdvertising(); StopAdvertising();
}
InvalidateReceiveSurfaceState(); InvalidateSurfaceState();
} }
void NearbySharingServiceImpl::OnDataUsageChanged(DataUsage data_usage) { void NearbySharingServiceImpl::OnDataUsageChanged(DataUsage data_usage) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
NS_LOG(VERBOSE) << __func__ << ": Nearby sharing data usage changed to " NS_LOG(VERBOSE) << __func__ << ": Nearby sharing data usage changed to "
<< DataUsageToString(data_usage); << DataUsageToString(data_usage);
if (advertising_power_level_ != PowerLevel::kUnknown) { if (advertising_power_level_ != PowerLevel::kUnknown)
StopAdvertising(); StopAdvertising();
}
InvalidateReceiveSurfaceState(); InvalidateSurfaceState();
}
const base::Optional<std::vector<uint8_t>>
NearbySharingServiceImpl::CreateEndpointInfo(
const base::Optional<std::string>& device_name) {
// TODO(nmusgrave) fill values from CertificateManager
std::vector<uint8_t> salt(sharing::Advertisement::kSaltSize, 0);
std::vector<uint8_t> encrypted_metadata_key(
sharing::Advertisement::kMetadataEncryptionKeyHashByteSize, 0);
// TODO(nmusgrave) fill value from local device data manager
std::unique_ptr<sharing::Advertisement> advertisement =
sharing::Advertisement::NewInstance(
std::move(salt), std::move(encrypted_metadata_key), device_name);
if (advertisement) {
return advertisement->ToEndpointInfo();
} else {
return base::nullopt;
}
} }
void NearbySharingServiceImpl::OnDeviceNameChanged( void NearbySharingServiceImpl::OnDeviceNameChanged(
...@@ -557,6 +793,19 @@ bool NearbySharingServiceImpl::IsBluetoothPowered() const { ...@@ -557,6 +793,19 @@ bool NearbySharingServiceImpl::IsBluetoothPowered() const {
return IsBluetoothPresent() && bluetooth_adapter_->IsPowered(); return IsBluetoothPresent() && bluetooth_adapter_->IsPowered();
} }
bool NearbySharingServiceImpl::HasAvailableConnectionMediums() {
// Check if Wifi or Ethernet LAN is off. Advertisements won't work, so
// disable them, unless bluetooth is known to be enabled. Not all platforms
// have bluetooth, so wifi LAN is a platform-agnostic check.
net::NetworkChangeNotifier::ConnectionType connection_type =
net::NetworkChangeNotifier::GetConnectionType();
return IsBluetoothPresent() ||
(connection_type ==
net::NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI ||
connection_type ==
net::NetworkChangeNotifier::ConnectionType::CONNECTION_ETHERNET);
}
void NearbySharingServiceImpl::AdapterPresentChanged( void NearbySharingServiceImpl::AdapterPresentChanged(
device::BluetoothAdapter* adapter, device::BluetoothAdapter* adapter,
bool present) { bool present) {
...@@ -571,9 +820,14 @@ void NearbySharingServiceImpl::AdapterPoweredChanged( ...@@ -571,9 +820,14 @@ void NearbySharingServiceImpl::AdapterPoweredChanged(
StopFastInitiationAdvertising(); StopFastInitiationAdvertising();
} }
void NearbySharingServiceImpl::InvalidateSurfaceState() {
InvalidateSendSurfaceState();
InvalidateReceiveSurfaceState();
}
void NearbySharingServiceImpl::InvalidateReceiveSurfaceState() { void NearbySharingServiceImpl::InvalidateReceiveSurfaceState() {
InvalidateAdvertisingState(); InvalidateAdvertisingState();
// TODO(crbug/154846208) InvalidateFastInitScan(); // TODO(b/161889067) InvalidateFastInitScan();
} }
void NearbySharingServiceImpl::InvalidateAdvertisingState() { void NearbySharingServiceImpl::InvalidateAdvertisingState() {
...@@ -585,16 +839,7 @@ void NearbySharingServiceImpl::InvalidateAdvertisingState() { ...@@ -585,16 +839,7 @@ void NearbySharingServiceImpl::InvalidateAdvertisingState() {
return; return;
} }
// Check if Wifi or Ethernet LAN is off. Advertisements won't work, so if (!HasAvailableConnectionMediums()) {
// disable them, unless bluetooth is known to be enabled. Not all platforms
// have bluetooth, so wifi LAN is a platform-agnostic check.
net::NetworkChangeNotifier::ConnectionType connection_type =
net::NetworkChangeNotifier::GetConnectionType();
if (!IsBluetoothPresent() &&
!(connection_type ==
net::NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI ||
connection_type ==
net::NetworkChangeNotifier::ConnectionType::CONNECTION_ETHERNET)) {
StopAdvertising(); StopAdvertising();
NS_LOG(VERBOSE) NS_LOG(VERBOSE)
<< __func__ << __func__
...@@ -621,7 +866,7 @@ void NearbySharingServiceImpl::InvalidateAdvertisingState() { ...@@ -621,7 +866,7 @@ void NearbySharingServiceImpl::InvalidateAdvertisingState() {
return; return;
} }
if (is_transferring_files_) { if (is_transferring_) {
StopAdvertising(); StopAdvertising();
NS_LOG(VERBOSE) NS_LOG(VERBOSE)
<< __func__ << __func__
...@@ -664,10 +909,10 @@ void NearbySharingServiceImpl::InvalidateAdvertisingState() { ...@@ -664,10 +909,10 @@ void NearbySharingServiceImpl::InvalidateAdvertisingState() {
if (power_level == advertising_power_level_) { if (power_level == advertising_power_level_) {
NS_LOG(VERBOSE) NS_LOG(VERBOSE)
<< __func__ << __func__
<< "Failed to advertise because we're already advertising with power" << ": Failed to advertise because we're already advertising with "
<< " level " << PowerLevelToString(advertising_power_level_) "power level "
<< " and data usage preference " << PowerLevelToString(advertising_power_level_)
<< DataUsageToString(settings_.GetDataUsage()); << " and data usage preference " << DataUsageToString(data_usage);
return; return;
} }
...@@ -678,23 +923,23 @@ void NearbySharingServiceImpl::InvalidateAdvertisingState() { ...@@ -678,23 +923,23 @@ void NearbySharingServiceImpl::InvalidateAdvertisingState() {
<< DataUsageToString(data_usage); << DataUsageToString(data_usage);
} }
base::Optional<std::string> device_name;
if (foreground_receive_callbacks_.might_have_observers())
device_name = local_device_data_manager_->GetDeviceName();
// Starts advertising through Nearby Connections. Caller is expected to ensure // Starts advertising through Nearby Connections. Caller is expected to ensure
// |listener| remains valid until StopAdvertising is called. // |listener| remains valid until StopAdvertising is called.
base::Optional<std::vector<uint8_t>> endpoint_info =
CreateEndpointInfo(device_name);
if (!endpoint_info) {
NS_LOG(VERBOSE) << __func__
<< ": Unable to advertise since could not parse the "
"endpoint info from the advertisement.";
return;
}
// TODO(nmusgrave) fill values from CertificateManager
std::vector<uint8_t> salt(sharing::Advertisement::kSaltSize, 0);
std::vector<uint8_t> encrypted_metadata_key(
sharing::Advertisement::kMetadataEncryptionKeyHashByteSize, 0);
// TODO(nmusgrave) fill value from local device data manager
base::Optional<std::string> device_name = "todo_device_name";
std::vector<uint8_t> endpoint_info =
sharing::Advertisement::NewInstance(std::move(salt),
std::move(encrypted_metadata_key),
std::move(device_name))
->ToEndpointInfo();
nearby_connections_manager_->StartAdvertising( nearby_connections_manager_->StartAdvertising(
std::move(endpoint_info), *endpoint_info,
/* listener= */ this, power_level, data_usage, /* listener= */ this, power_level, data_usage,
base::BindOnce([](NearbyConnectionsManager::ConnectionsStatus status) { base::BindOnce([](NearbyConnectionsManager::ConnectionsStatus status) {
NS_LOG(VERBOSE) NS_LOG(VERBOSE)
...@@ -722,11 +967,139 @@ void NearbySharingServiceImpl::StopAdvertising() { ...@@ -722,11 +967,139 @@ void NearbySharingServiceImpl::StopAdvertising() {
} }
nearby_connections_manager_->StopAdvertising(); nearby_connections_manager_->StopAdvertising();
advertising_power_level_ = PowerLevel::kUnknown; advertising_power_level_ = PowerLevel::kUnknown;
NS_LOG(VERBOSE) << __func__ << ": Advertising has stopped"; NS_LOG(VERBOSE) << __func__ << ": Advertising has stopped";
} }
void NearbySharingServiceImpl::InvalidateSendSurfaceState() {
InvalidateScanningState();
// TODO(b/161889067) InvalidateFastInitAdvertisement();
}
void NearbySharingServiceImpl::InvalidateScanningState() {
// Screen is off. Do no work.
if (ui::CheckIdleStateIsLocked()) {
StopScanning();
NS_LOG(VERBOSE) << __func__
<< ": Stopping discovery because the screen is locked.";
return;
}
if (!HasAvailableConnectionMediums()) {
StopScanning();
NS_LOG(VERBOSE)
<< __func__
<< ": Stopping scanning because both bluetooth and wifi LAN are "
"disabled.";
return;
}
// Nearby Sharing is disabled. Don't advertise.
if (!settings_.GetEnabled()) {
StopScanning();
NS_LOG(VERBOSE)
<< __func__
<< ": Stopping discovery because Nearby Sharing is disabled.";
return;
}
if (is_transferring_ || is_connecting_) {
StopScanning();
NS_LOG(VERBOSE)
<< __func__
<< ": Stopping discovery because we're currently in the midst of a "
"transfer.";
return;
}
if (!foreground_send_transfer_callbacks_.might_have_observers()) {
StopScanning();
NS_LOG(VERBOSE)
<< __func__
<< ": Stopping discovery because no scanning surface has been "
"registered.";
return;
}
// Screen is on, Bluetooth is enabled, and Nearby Sharing is enabled! Start
// discovery.
StartScanning();
}
void NearbySharingServiceImpl::StartScanning() {
if (!settings_.GetEnabled()) {
NS_LOG(VERBOSE) << __func__
<< ": Failed to scan because we're not enabled.";
return;
}
if (ui::CheckIdleStateIsLocked()) {
NS_LOG(VERBOSE) << __func__
<< ": Failed to scan because the user's screen is locked.";
return;
}
if (!HasAvailableConnectionMediums()) {
NS_LOG(VERBOSE) << __func__ << ": Failed to scan because Bluetooth is off.";
return;
}
if (is_scanning_) {
NS_LOG(VERBOSE) << __func__
<< ": Failed to scan because we're currently scanning.";
return;
}
if (!foreground_send_transfer_callbacks_.might_have_observers()) {
NS_LOG(VERBOSE)
<< __func__
<< ": Failed to scan because there's no scanning send surface "
"registered.";
return;
}
scanning_start_timestamp_ = base::Time::Now();
is_scanning_ = true;
InvalidateReceiveSurfaceState();
ClearOutgoingShareTargetInfoMap();
nearby_connections_manager_->StartDiscovery(
/* listener= */ this,
base::BindOnce([](NearbyConnectionsManager::ConnectionsStatus status) {
NS_LOG(VERBOSE) << __func__
<< ": Scanning start attempted over Nearby Connections "
"with result "
<< ConnectionsStatusToString(status);
}));
InvalidateSendSurfaceState();
NS_LOG(VERBOSE) << __func__ << ": Scanning has started";
}
NearbySharingService::StatusCodes NearbySharingServiceImpl::StopScanning() {
if (!is_scanning_) {
NS_LOG(VERBOSE) << __func__
<< ": Failed to stop scanning because weren't scanning.";
return StatusCodes::kStatusAlreadyStopped;
}
nearby_connections_manager_->StopDiscovery();
is_scanning_ = false;
// 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.
base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::BindOnce(&NearbySharingServiceImpl::InvalidateSurfaceState,
weak_ptr_factory_.GetWeakPtr()),
kInvalidateDelay);
NS_LOG(VERBOSE) << __func__ << ": Scanning has stopped.";
return StatusCodes::kOk;
}
void NearbySharingServiceImpl::OnIncomingTransferUpdate( void NearbySharingServiceImpl::OnIncomingTransferUpdate(
const ShareTarget& share_target, const ShareTarget& share_target,
TransferMetadata metadata) { TransferMetadata metadata) {
...@@ -1074,17 +1447,6 @@ void NearbySharingServiceImpl::OnIncomingConnectionDisconnected( ...@@ -1074,17 +1447,6 @@ void NearbySharingServiceImpl::OnIncomingConnectionDisconnected(
UnregisterShareTarget(share_target); UnregisterShareTarget(share_target);
} }
void NearbySharingServiceImpl::UnregisterShareTarget(
const ShareTarget& share_target) {
if (share_target.is_incoming) {
incoming_share_target_info_map_.erase(share_target.id);
nearby_connections_manager_->ClearIncomingPayloads();
} else {
// TODO(crbug.com/1084644) - Clear from outgoing map.
}
mutual_acceptance_timeout_alarm_.Cancel();
}
bool NearbySharingServiceImpl::IsOutOfStorage(const ShareTarget& share_target) { bool NearbySharingServiceImpl::IsOutOfStorage(const ShareTarget& share_target) {
// TODO(himanshujaju) - Check storage space based on file path. // TODO(himanshujaju) - Check storage space based on file path.
return false; return false;
...@@ -1116,13 +1478,68 @@ NearbyConnection* NearbySharingServiceImpl::GetIncomingConnection( ...@@ -1116,13 +1478,68 @@ NearbyConnection* NearbySharingServiceImpl::GetIncomingConnection(
return GetIncomingShareTargetInfo(share_target).connection(); return GetIncomingShareTargetInfo(share_target).connection();
} }
OutgoingShareTargetInfo& NearbySharingServiceImpl::GetOutgoingShareTargetInfo( OutgoingShareTargetInfo&
const ShareTarget& share_target) { NearbySharingServiceImpl::GetOrCreateOutgoingShareTargetInfo(
const ShareTarget& share_target,
const std::string& endpoint_id) {
// Default initialize outgoing_share_target_map_ as well, since Share Target
// needs to have fields explicitly set.
outgoing_share_target_map_.emplace(endpoint_id, share_target);
return outgoing_share_target_info_map_[share_target.id]; return outgoing_share_target_info_map_[share_target.id];
} }
void NearbySharingServiceImpl::ClearOutgoingShareTargetInfoMap() { void NearbySharingServiceImpl::ClearOutgoingShareTargetInfoMap() {
// TODO(crbug.com/1085068) close file payloads
outgoing_share_target_info_map_.clear(); outgoing_share_target_info_map_.clear();
outgoing_share_target_map_.clear();
}
base::Optional<ShareTarget> NearbySharingServiceImpl::CreateShareTarget(
const std::string& endpoint_id,
sharing::mojom::AdvertisementPtr advertisement,
bool is_incoming) {
if (!advertisement->device_name) {
// TODO(crbug/1085068): Handle incoming connection; relies upon
// CertificateManager
return base::nullopt;
}
return ShareTarget(*advertisement->device_name, /* image_url= */ GURL(),
nearby_share::mojom::ShareTargetType::kUnknown,
std::vector<TextAttachment>(),
std::vector<FileAttachment>(), is_incoming,
/* full_name= */ base::nullopt, /* is_known= */ false);
}
void NearbySharingServiceImpl::UnregisterShareTarget(
const ShareTarget& share_target) {
if (share_target.is_incoming) {
incoming_share_target_info_map_.erase(share_target.id);
// Clear legacy incoming payloads to release resource
nearby_connections_manager_->ClearIncomingPayloads();
} else {
// Find the endpoint id that matches the given share target.
base::Optional<std::string> endpoint_id;
auto it = outgoing_share_target_info_map_.find(share_target.id);
if (it != outgoing_share_target_info_map_.end())
endpoint_id = it->second.endpoint_id();
// Remove info except for this endpoint id, if present.
ClearOutgoingShareTargetInfoMap();
if (endpoint_id) {
NS_LOG(VERBOSE) << __func__ << ": Unregister share target: "
<< share_target.device_name;
GetOrCreateOutgoingShareTargetInfo(share_target, *endpoint_id)
.set_endpoint_id(*endpoint_id);
} else {
NS_LOG(VERBOSE)
<< __func__
<< ": Cannot unregister share target since none registered: "
<< share_target.device_name;
}
}
mutual_acceptance_timeout_alarm_.Cancel();
} }
void NearbySharingServiceImpl::SetAttachmentPayloadId( void NearbySharingServiceImpl::SetAttachmentPayloadId(
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/scoped_observer.h" #include "base/scoped_observer.h"
#include "base/sequence_checker.h" #include "base/sequence_checker.h"
#include "base/time/time.h"
#include "base/unguessable_token.h" #include "base/unguessable_token.h"
#include "chrome/browser/nearby_sharing/attachment.h" #include "chrome/browser/nearby_sharing/attachment.h"
#include "chrome/browser/nearby_sharing/attachment_info.h" #include "chrome/browser/nearby_sharing/attachment_info.h"
...@@ -23,6 +24,7 @@ ...@@ -23,6 +24,7 @@
#include "chrome/browser/nearby_sharing/common/nearby_share_enums.h" #include "chrome/browser/nearby_sharing/common/nearby_share_enums.h"
#include "chrome/browser/nearby_sharing/incoming_frames_reader.h" #include "chrome/browser/nearby_sharing/incoming_frames_reader.h"
#include "chrome/browser/nearby_sharing/incoming_share_target_info.h" #include "chrome/browser/nearby_sharing/incoming_share_target_info.h"
#include "chrome/browser/nearby_sharing/local_device_data/nearby_share_local_device_data_manager.h"
#include "chrome/browser/nearby_sharing/nearby_connections_manager.h" #include "chrome/browser/nearby_sharing/nearby_connections_manager.h"
#include "chrome/browser/nearby_sharing/nearby_notification_manager.h" #include "chrome/browser/nearby_sharing/nearby_notification_manager.h"
#include "chrome/browser/nearby_sharing/nearby_process_manager.h" #include "chrome/browser/nearby_sharing/nearby_process_manager.h"
...@@ -52,7 +54,8 @@ class NearbySharingServiceImpl ...@@ -52,7 +54,8 @@ class NearbySharingServiceImpl
public nearby_share::mojom::NearbyShareSettingsObserver, public nearby_share::mojom::NearbyShareSettingsObserver,
public NearbyProcessManager::Observer, public NearbyProcessManager::Observer,
public device::BluetoothAdapter::Observer, public device::BluetoothAdapter::Observer,
public NearbyConnectionsManager::IncomingConnectionListener { public NearbyConnectionsManager::IncomingConnectionListener,
public NearbyConnectionsManager::DiscoveryListener {
public: public:
explicit NearbySharingServiceImpl( explicit NearbySharingServiceImpl(
PrefService* prefs, PrefService* prefs,
...@@ -117,8 +120,15 @@ class NearbySharingServiceImpl ...@@ -117,8 +120,15 @@ class NearbySharingServiceImpl
NearbyShareContactManager* GetContactManager() override; NearbyShareContactManager* GetContactManager() override;
NearbyShareCertificateManager* GetCertificateManager() override; NearbyShareCertificateManager* GetCertificateManager() override;
// NearbyConnectionsManager::DiscoveryListener:
void OnEndpointDiscovered(const std::string& endpoint_id,
const std::vector<uint8_t>& endpoint_info) override;
void OnEndpointLost(const std::string& endpoint_id) override;
private: private:
bool IsVisibleInBackground(Visibility visibility); bool IsVisibleInBackground(Visibility visibility);
const base::Optional<std::vector<uint8_t>> CreateEndpointInfo(
const base::Optional<std::string>& device_name);
void StartFastInitiationAdvertising(); void StartFastInitiationAdvertising();
void StopFastInitiationAdvertising(); void StopFastInitiationAdvertising();
void GetBluetoothAdapter(); void GetBluetoothAdapter();
...@@ -126,12 +136,19 @@ class NearbySharingServiceImpl ...@@ -126,12 +136,19 @@ class NearbySharingServiceImpl
void OnStartFastInitiationAdvertising(); void OnStartFastInitiationAdvertising();
void OnStartFastInitiationAdvertisingError(); void OnStartFastInitiationAdvertisingError();
void OnStopFastInitiationAdvertising(); void OnStopFastInitiationAdvertising();
void OnOutgoingAdvertisementDecoded(
const std::string& endpoint_id,
sharing::mojom::AdvertisementPtr advertisement);
bool IsBluetoothPresent() const; bool IsBluetoothPresent() const;
bool IsBluetoothPowered() const; bool IsBluetoothPowered() const;
bool HasAvailableConnectionMediums();
void AdapterPresentChanged(device::BluetoothAdapter* adapter, void AdapterPresentChanged(device::BluetoothAdapter* adapter,
bool present) override; bool present) override;
void AdapterPoweredChanged(device::BluetoothAdapter* adapter, void AdapterPoweredChanged(device::BluetoothAdapter* adapter,
bool powered) override; bool powered) override;
void InvalidateSurfaceState();
void InvalidateSendSurfaceState();
void InvalidateScanningState();
void InvalidateReceiveSurfaceState(); void InvalidateReceiveSurfaceState();
void InvalidateAdvertisingState(); void InvalidateAdvertisingState();
void StopAdvertising(); void StopAdvertising();
...@@ -143,6 +160,10 @@ class NearbySharingServiceImpl ...@@ -143,6 +160,10 @@ class NearbySharingServiceImpl
NearbyConnection& connection, NearbyConnection& connection,
sharing::nearby::ConnectionResponseFrame::Status reponse_status); sharing::nearby::ConnectionResponseFrame::Status reponse_status);
void Fail(const ShareTarget& share_target, TransferMetadata::Status status); void Fail(const ShareTarget& share_target, TransferMetadata::Status status);
void StartScanning(
base::Optional<ShareTargetDiscoveredCallback*> discovery_callback);
void StartScanning();
StatusCodes StopScanning();
void OnIncomingTransferUpdate(const ShareTarget& share_target, void OnIncomingTransferUpdate(const ShareTarget& share_target,
TransferMetadata metadata); TransferMetadata metadata);
void CloseConnection(const ShareTarget& share_target); void CloseConnection(const ShareTarget& share_target);
...@@ -158,7 +179,6 @@ class NearbySharingServiceImpl ...@@ -158,7 +179,6 @@ class NearbySharingServiceImpl
const sharing::mojom::CertificateInfoFramePtr& certificate_frame); const sharing::mojom::CertificateInfoFramePtr& certificate_frame);
void OnIncomingConnectionDisconnected(const ShareTarget& share_target); void OnIncomingConnectionDisconnected(const ShareTarget& share_target);
void UnregisterShareTarget(const ShareTarget& share_target);
bool IsOutOfStorage(const ShareTarget& share_target); bool IsOutOfStorage(const ShareTarget& share_target);
void OnIncomingMutualAcceptanceTimeout(const ShareTarget& share_target); void OnIncomingMutualAcceptanceTimeout(const ShareTarget& share_target);
...@@ -166,14 +186,19 @@ class NearbySharingServiceImpl ...@@ -166,14 +186,19 @@ class NearbySharingServiceImpl
IncomingShareTargetInfo& GetIncomingShareTargetInfo( IncomingShareTargetInfo& GetIncomingShareTargetInfo(
const ShareTarget& share_target); const ShareTarget& share_target);
NearbyConnection* GetIncomingConnection(const ShareTarget& share_target); NearbyConnection* GetIncomingConnection(const ShareTarget& share_target);
OutgoingShareTargetInfo& GetOutgoingShareTargetInfo( OutgoingShareTargetInfo& GetOrCreateOutgoingShareTargetInfo(
const ShareTarget& share_target); const ShareTarget& share_target,
const std::string& endpoint_id);
void ClearOutgoingShareTargetInfoMap(); void ClearOutgoingShareTargetInfoMap();
void SetAttachmentPayloadId(const Attachment& attachment, int64_t payload_id); void SetAttachmentPayloadId(const Attachment& attachment, int64_t payload_id);
base::Optional<int64_t> GetAttachmentPayloadId( base::Optional<int64_t> GetAttachmentPayloadId(
const base::UnguessableToken& attachment_id); const base::UnguessableToken& attachment_id);
base::Optional<ShareTarget> CreateShareTarget(
const std::string& endpoint_id,
sharing::mojom::AdvertisementPtr advertisement,
bool is_incoming);
void UnregisterShareTarget(const ShareTarget& share_target);
PrefService* prefs_;
Profile* profile_; Profile* profile_;
NearbyShareSettings settings_; NearbyShareSettings settings_;
std::unique_ptr<NearbyConnectionsManager> nearby_connections_manager_; std::unique_ptr<NearbyConnectionsManager> nearby_connections_manager_;
...@@ -193,6 +218,20 @@ class NearbySharingServiceImpl ...@@ -193,6 +218,20 @@ class NearbySharingServiceImpl
base::ObserverList<TransferUpdateCallback> foreground_receive_callbacks_; base::ObserverList<TransferUpdateCallback> foreground_receive_callbacks_;
// A list of foreground receivers. // A list of foreground receivers.
base::ObserverList<TransferUpdateCallback> background_receive_callbacks_; base::ObserverList<TransferUpdateCallback> background_receive_callbacks_;
// A list of foreground receivers for transfer updates on the send surface.
base::ObserverList<TransferUpdateCallback>
foreground_send_transfer_callbacks_;
// A list of foreground receivers for discovered device updates on the send
// surface.
base::ObserverList<ShareTargetDiscoveredCallback>
foreground_send_discovery_callbacks_;
// A list of background receivers for transfer updates on the send surface.
base::ObserverList<TransferUpdateCallback>
background_send_transfer_callbacks_;
// A list of background receivers for discovered device updates on the send
// surface.
base::ObserverList<ShareTargetDiscoveredCallback>
background_send_discovery_callbacks_;
// Registers the most recent TransferMetadata and ShareTarget used for // Registers the most recent TransferMetadata and ShareTarget used for
// transitioning notifications between foreground surfaces and background // transitioning notifications between foreground surfaces and background
...@@ -207,6 +246,10 @@ class NearbySharingServiceImpl ...@@ -207,6 +246,10 @@ class NearbySharingServiceImpl
// incoming share target. // incoming share target.
base::flat_map<base::UnguessableToken, IncomingShareTargetInfo> base::flat_map<base::UnguessableToken, IncomingShareTargetInfo>
incoming_share_target_info_map_; incoming_share_target_info_map_;
// A map of endpoint id to ShareTarget, where each ShareTarget entry
// directly corresponds to a OutgoingShareTargetInfo entry in
// outgoing_share_target_info_map_;
base::flat_map<std::string, ShareTarget> outgoing_share_target_map_;
// A map of ShareTarget id to OutgoingShareTargetInfo. This lets us know which // A map of ShareTarget id to OutgoingShareTargetInfo. This lets us know which
// endpoint and public certificate are related to the outgoing share target. // endpoint and public certificate are related to the outgoing share target.
// TODO(crbug/1085068) update this map when handling payloads // TODO(crbug/1085068) update this map when handling payloads
...@@ -227,7 +270,13 @@ class NearbySharingServiceImpl ...@@ -227,7 +270,13 @@ class NearbySharingServiceImpl
// True if we are currently scanning for remote devices. // True if we are currently scanning for remote devices.
bool is_scanning_ = false; bool is_scanning_ = false;
// True if we're currently sending or receiving a file. // True if we're currently sending or receiving a file.
bool is_transferring_files_ = false; bool is_transferring_ = false;
// True if we're currently receiving a file.
bool is_receiving_files_ = false;
// True if we're currently attempting to connect to a remote device.
bool is_connecting_ = false;
// The time scanning began.
base::Time scanning_start_timestamp_;
mojo::Receiver<nearby_share::mojom::NearbyShareSettingsObserver> mojo::Receiver<nearby_share::mojom::NearbyShareSettingsObserver>
settings_receiver_{this}; settings_receiver_{this};
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "chrome/browser/nearby_sharing/nearby_connections_manager.h" #include "chrome/browser/nearby_sharing/nearby_connections_manager.h"
#include "chrome/browser/notifications/notification_display_service_factory.h" #include "chrome/browser/notifications/notification_display_service_factory.h"
#include "chrome/browser/notifications/notification_display_service_tester.h" #include "chrome/browser/notifications/notification_display_service_tester.h"
#include "chrome/services/sharing/public/cpp/advertisement.h"
#include "chrome/services/sharing/public/proto/wire_format.pb.h" #include "chrome/services/sharing/public/proto/wire_format.pb.h"
#include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile.h"
...@@ -43,6 +44,8 @@ using testing::Return; ...@@ -43,6 +44,8 @@ using testing::Return;
using NetConnectionType = net::NetworkChangeNotifier::ConnectionType; using NetConnectionType = net::NetworkChangeNotifier::ConnectionType;
using SendSurfaceState = NearbySharingService::SendSurfaceState;
class FakeFastInitiationManager : public FastInitiationManager { class FakeFastInitiationManager : public FastInitiationManager {
public: public:
explicit FakeFastInitiationManager( explicit FakeFastInitiationManager(
...@@ -112,7 +115,10 @@ class FakeFastInitiationManagerFactory : public FastInitiationManager::Factory { ...@@ -112,7 +115,10 @@ class FakeFastInitiationManagerFactory : public FastInitiationManager::Factory {
} }
size_t StartAdvertisingCount() { size_t StartAdvertisingCount() {
return last_fake_fast_initiation_manager_->start_advertising_call_count(); return last_fake_fast_initiation_manager_
? last_fake_fast_initiation_manager_
->start_advertising_call_count()
: 0;
} }
bool StopAdvertisingCalledAndManagerDestroyed() { bool StopAdvertisingCalledAndManagerDestroyed() {
...@@ -139,9 +145,22 @@ class MockTransferUpdateCallback : public TransferUpdateCallback { ...@@ -139,9 +145,22 @@ class MockTransferUpdateCallback : public TransferUpdateCallback {
(override)); (override));
}; };
class MockShareTargetDiscoveredCallback : public ShareTargetDiscoveredCallback {
public:
~MockShareTargetDiscoveredCallback() override = default;
MOCK_METHOD(void,
OnShareTargetDiscovered,
(ShareTarget shareTarget),
(override));
MOCK_METHOD(void, OnShareTargetLost, (ShareTarget shareTarget), (override));
};
namespace { namespace {
const char kServiceId[] = "NearbySharing";
const char kEndpointId[] = "endpoint_id"; const char kEndpointId[] = "endpoint_id";
const char kDeviceName[] = "device_name";
sharing::mojom::FramePtr GetValidIntroductionFrame() { sharing::mojom::FramePtr GetValidIntroductionFrame() {
std::vector<sharing::mojom::TextMetadataPtr> mojo_text_metadatas; std::vector<sharing::mojom::TextMetadataPtr> mojo_text_metadatas;
...@@ -162,6 +181,19 @@ sharing::mojom::FramePtr GetValidIntroductionFrame() { ...@@ -162,6 +181,19 @@ sharing::mojom::FramePtr GetValidIntroductionFrame() {
return mojo_frame; return mojo_frame;
} }
// Length sharing::Advertisement::kSaltSize
const uint8_t kSalt[] = {0x0c, 0x08};
// Length sharing::Advertisement::kMetadataEncryptionKeyHashByteSize
const uint8_t kMetadataEncryptionKeyHashByte[] = {0x07, 0x01, 0x08, 0x08, 0x04,
0x09, 0x06, 0x00, 0x0b, 0x0f,
0x0c, 0x09, 0x03, 0x0d};
const int kEndpointInfoSize =
1 + sharing::Advertisement::kSaltSize +
sharing::Advertisement::kMetadataEncryptionKeyHashByteSize;
const uint8_t kEndpointInfo[] = {0x00, 0x0c, 0x08, 0x07, 0x01, 0x08,
0x08, 0x04, 0x09, 0x06, 0x00, 0x0b,
0x0f, 0x0c, 0x09, 0x03, 0x0d};
class NearbySharingServiceImplTest : public testing::Test { class NearbySharingServiceImplTest : public testing::Test {
public: public:
NearbySharingServiceImplTest() { NearbySharingServiceImplTest() {
...@@ -206,6 +238,8 @@ class NearbySharingServiceImplTest : public testing::Test { ...@@ -206,6 +238,8 @@ class NearbySharingServiceImplTest : public testing::Test {
&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_);
NearbyProcessManager& process_manager = NearbyProcessManager::GetInstance();
process_manager.SetActiveProfile(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();
...@@ -259,6 +293,47 @@ class NearbySharingServiceImplTest : public testing::Test { ...@@ -259,6 +293,47 @@ class NearbySharingServiceImplTest : public testing::Test {
net::test::MockNetworkChangeNotifier::Create(); net::test::MockNetworkChangeNotifier::Create();
}; };
struct ValidSendSurfaceTestData {
ui::IdleState idle_state;
bool bluetooth_enabled;
net::NetworkChangeNotifier::ConnectionType connection_type;
} kValidSendSurfaceTestData[] = {
// No network connection, only bluetooth available
{ui::IDLE_STATE_IDLE, true, net::NetworkChangeNotifier::CONNECTION_NONE},
// Wifi available
{ui::IDLE_STATE_IDLE, true, net::NetworkChangeNotifier::CONNECTION_WIFI},
// Ethernet available
{ui::IDLE_STATE_IDLE, true,
net::NetworkChangeNotifier::CONNECTION_ETHERNET},
// 3G available
{ui::IDLE_STATE_IDLE, true, net::NetworkChangeNotifier::CONNECTION_3G},
// Wifi available and no bluetooth
{ui::IDLE_STATE_IDLE, false, net::NetworkChangeNotifier::CONNECTION_WIFI},
// Ethernet available and no bluetooth
{ui::IDLE_STATE_IDLE, false,
net::NetworkChangeNotifier::CONNECTION_ETHERNET}};
class NearbySharingServiceImplValidSendTest
: public NearbySharingServiceImplTest,
public testing::WithParamInterface<ValidSendSurfaceTestData> {};
struct InvalidSendSurfaceTestData {
ui::IdleState idle_state;
bool bluetooth_enabled;
net::NetworkChangeNotifier::ConnectionType connection_type;
} kInvalidSendSurfaceTestData[] = {
// Screen locked
{ui::IDLE_STATE_LOCKED, true, net::NetworkChangeNotifier::CONNECTION_WIFI},
// No network connection and no bluetooth
{ui::IDLE_STATE_IDLE, false, net::NetworkChangeNotifier::CONNECTION_NONE},
// 3G available and no bluetooth
{ui::IDLE_STATE_IDLE, false, net::NetworkChangeNotifier::CONNECTION_3G},
};
class NearbySharingServiceImplInvalidSendTest
: public NearbySharingServiceImplTest,
public testing::WithParamInterface<InvalidSendSurfaceTestData> {};
} // namespace } // namespace
TEST_F(NearbySharingServiceImplTest, AddsNearbyProcessObserver) { TEST_F(NearbySharingServiceImplTest, AddsNearbyProcessObserver) {
...@@ -272,79 +347,111 @@ TEST_F(NearbySharingServiceImplTest, RemovesNearbyProcessObserver) { ...@@ -272,79 +347,111 @@ TEST_F(NearbySharingServiceImplTest, RemovesNearbyProcessObserver) {
} }
TEST_F(NearbySharingServiceImplTest, DisableNearbyShutdownConnections) { TEST_F(NearbySharingServiceImplTest, DisableNearbyShutdownConnections) {
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
prefs_.SetBoolean(prefs::kNearbySharingEnabledPrefName, false); prefs_.SetBoolean(prefs::kNearbySharingEnabledPrefName, false);
service_->FlushMojoForTesting(); service_->FlushMojoForTesting();
EXPECT_TRUE(fake_nearby_connections_manager_->IsShutdown()); EXPECT_TRUE(fake_nearby_connections_manager_->IsShutdown());
} }
TEST_F(NearbySharingServiceImplTest, StartFastInitiationAdvertising) { TEST_F(NearbySharingServiceImplTest, StartFastInitiationAdvertising) {
EXPECT_EQ(NearbySharingService::StatusCodes::kOk, ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
service_->RegisterSendSurface( SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
/*transfer_callback=*/nullptr, MockTransferUpdateCallback transfer_callback;
/*discovery_callback=*/nullptr, MockShareTargetDiscoveredCallback discovery_callback;
NearbySharingService::SendSurfaceState::kForeground)); EXPECT_EQ(
NearbySharingService::StatusCodes::kOk,
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kForeground));
EXPECT_EQ(1u, fast_initiation_manager_factory_->StartAdvertisingCount()); EXPECT_EQ(1u, fast_initiation_manager_factory_->StartAdvertisingCount());
// Call RegisterSendSurface() a second time and make sure StartAdvertising is // Call RegisterSendSurface a second time and make sure StartAdvertising is
// not called again. // not called again.
EXPECT_EQ(NearbySharingService::StatusCodes::kOk, EXPECT_EQ(
service_->RegisterSendSurface( NearbySharingService::StatusCodes::kError,
/*transfer_callback=*/nullptr, service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
/*discovery_callback=*/nullptr, SendSurfaceState::kForeground));
NearbySharingService::SendSurfaceState::kForeground));
EXPECT_EQ(1u, fast_initiation_manager_factory_->StartAdvertisingCount()); EXPECT_EQ(1u, fast_initiation_manager_factory_->StartAdvertisingCount());
} }
TEST_F(NearbySharingServiceImplTest, StartFastInitiationAdvertisingError) { TEST_F(NearbySharingServiceImplTest, StartFastInitiationAdvertisingError) {
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
SetFakeFastInitiationManagerFactory(/*should_succeed_on_start=*/false); SetFakeFastInitiationManagerFactory(/*should_succeed_on_start=*/false);
EXPECT_EQ(NearbySharingService::StatusCodes::kOk, MockTransferUpdateCallback transfer_callback;
service_->RegisterSendSurface( MockShareTargetDiscoveredCallback discovery_callback;
/*transfer_callback=*/nullptr, EXPECT_EQ(
/*discovery_callback=*/nullptr, NearbySharingService::StatusCodes::kOk,
NearbySharingService::SendSurfaceState::kForeground)); service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kForeground));
}
TEST_F(NearbySharingServiceImplTest,
BackgroundStartFastInitiationAdvertisingError) {
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
MockTransferUpdateCallback transfer_callback;
MockShareTargetDiscoveredCallback discovery_callback;
EXPECT_EQ(
NearbySharingService::StatusCodes::kOk,
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kBackground));
EXPECT_EQ(0u, fast_initiation_manager_factory_->StartAdvertisingCount());
} }
TEST_F(NearbySharingServiceImplTest, TEST_F(NearbySharingServiceImplTest,
StartFastInitiationAdvertising_BluetoothNotPresent) { StartFastInitiationAdvertising_BluetoothNotPresent) {
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
is_bluetooth_present_ = false; is_bluetooth_present_ = false;
EXPECT_EQ(NearbySharingService::StatusCodes::kOk, MockTransferUpdateCallback transfer_callback;
service_->RegisterSendSurface( MockShareTargetDiscoveredCallback discovery_callback;
/*transfer_callback=*/nullptr, EXPECT_EQ(
/*discovery_callback=*/nullptr, NearbySharingService::StatusCodes::kOk,
NearbySharingService::SendSurfaceState::kForeground)); service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kForeground));
} }
TEST_F(NearbySharingServiceImplTest, TEST_F(NearbySharingServiceImplTest,
StartFastInitiationAdvertising_BluetoothNotPowered) { StartFastInitiationAdvertising_BluetoothNotPowered) {
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
is_bluetooth_powered_ = false; is_bluetooth_powered_ = false;
EXPECT_EQ(NearbySharingService::StatusCodes::kOk, MockTransferUpdateCallback transfer_callback;
service_->RegisterSendSurface( MockShareTargetDiscoveredCallback discovery_callback;
/*transfer_callback=*/nullptr, EXPECT_EQ(
/*discovery_callback=*/nullptr, NearbySharingService::StatusCodes::kOk,
NearbySharingService::SendSurfaceState::kForeground)); service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kForeground));
} }
TEST_F(NearbySharingServiceImplTest, StopFastInitiationAdvertising) { TEST_F(NearbySharingServiceImplTest, StopFastInitiationAdvertising) {
EXPECT_EQ(NearbySharingService::StatusCodes::kOk, ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
service_->RegisterSendSurface( SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
/*transfer_callback=*/nullptr, MockTransferUpdateCallback transfer_callback;
/*discovery_callback=*/nullptr, MockShareTargetDiscoveredCallback discovery_callback;
NearbySharingService::SendSurfaceState::kForeground)); EXPECT_EQ(
NearbySharingService::StatusCodes::kOk,
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kForeground));
EXPECT_EQ(1u, fast_initiation_manager_factory_->StartAdvertisingCount()); EXPECT_EQ(1u, fast_initiation_manager_factory_->StartAdvertisingCount());
EXPECT_EQ(NearbySharingService::StatusCodes::kOk, EXPECT_EQ(
service_->UnregisterSendSurface(/*transfer_callback=*/nullptr, NearbySharingService::StatusCodes::kOk,
/*discovery_callback=*/nullptr)); service_->UnregisterSendSurface(&transfer_callback, &discovery_callback));
EXPECT_TRUE(fast_initiation_manager_factory_ EXPECT_TRUE(fast_initiation_manager_factory_
->StopAdvertisingCalledAndManagerDestroyed()); ->StopAdvertisingCalledAndManagerDestroyed());
} }
TEST_F(NearbySharingServiceImplTest, TEST_F(NearbySharingServiceImplTest,
StopFastInitiationAdvertising_BluetoothBecomesNotPresent) { StopFastInitiationAdvertising_BluetoothBecomesNotPresent) {
EXPECT_EQ(NearbySharingService::StatusCodes::kOk, ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
service_->RegisterSendSurface( SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
/*transfer_callback=*/nullptr, MockTransferUpdateCallback transfer_callback;
/*discovery_callback=*/nullptr, MockShareTargetDiscoveredCallback discovery_callback;
NearbySharingService::SendSurfaceState::kForeground)); EXPECT_EQ(
NearbySharingService::StatusCodes::kOk,
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kForeground));
adapter_observer_->AdapterPresentChanged(mock_bluetooth_adapter_.get(), adapter_observer_->AdapterPresentChanged(mock_bluetooth_adapter_.get(),
false); false);
EXPECT_TRUE(fast_initiation_manager_factory_ EXPECT_TRUE(fast_initiation_manager_factory_
...@@ -353,17 +460,300 @@ TEST_F(NearbySharingServiceImplTest, ...@@ -353,17 +460,300 @@ TEST_F(NearbySharingServiceImplTest,
TEST_F(NearbySharingServiceImplTest, TEST_F(NearbySharingServiceImplTest,
StopFastInitiationAdvertising_BluetoothBecomesNotPowered) { StopFastInitiationAdvertising_BluetoothBecomesNotPowered) {
EXPECT_EQ(NearbySharingService::StatusCodes::kOk, ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
service_->RegisterSendSurface( SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
/*transfer_callback=*/nullptr, MockTransferUpdateCallback transfer_callback;
/*discovery_callback=*/nullptr, MockShareTargetDiscoveredCallback discovery_callback;
NearbySharingService::SendSurfaceState::kForeground)); EXPECT_EQ(
NearbySharingService::StatusCodes::kOk,
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kForeground));
adapter_observer_->AdapterPoweredChanged(mock_bluetooth_adapter_.get(), adapter_observer_->AdapterPoweredChanged(mock_bluetooth_adapter_.get(),
false); false);
EXPECT_TRUE(fast_initiation_manager_factory_ EXPECT_TRUE(fast_initiation_manager_factory_
->StopAdvertisingCalledAndManagerDestroyed()); ->StopAdvertisingCalledAndManagerDestroyed());
} }
TEST_F(NearbySharingServiceImplTest,
RegisterSendSurfaceNoActiveProfilesNotDiscovering) {
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
NearbyProcessManager& process_manager = NearbyProcessManager::GetInstance();
process_manager.ClearActiveProfile();
MockTransferUpdateCallback transfer_callback;
MockShareTargetDiscoveredCallback discovery_callback;
EXPECT_EQ(
NearbySharingService::StatusCodes::kError,
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kForeground));
}
TEST_F(NearbySharingServiceImplTest,
ForegroundRegisterSendSurfaceStartsDiscovering) {
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
MockTransferUpdateCallback transfer_callback;
MockShareTargetDiscoveredCallback discovery_callback;
EXPECT_EQ(
NearbySharingService::StatusCodes::kOk,
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kForeground));
EXPECT_TRUE(fake_nearby_connections_manager_->IsDiscovering());
}
TEST_F(NearbySharingServiceImplTest,
ForegroundRegisterSendSurfaceTwiceKeepsDiscovering) {
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
MockTransferUpdateCallback transfer_callback;
MockShareTargetDiscoveredCallback discovery_callback;
EXPECT_EQ(
NearbySharingService::StatusCodes::kOk,
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kForeground));
EXPECT_TRUE(fake_nearby_connections_manager_->IsDiscovering());
EXPECT_EQ(
NearbySharingService::StatusCodes::kError,
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kForeground));
EXPECT_TRUE(fake_nearby_connections_manager_->IsDiscovering());
}
TEST_F(NearbySharingServiceImplTest,
RegisterSendSurfaceAlreadyReceivingNotDiscovering) {
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
// TODO(himanshujaju) is_receiving_files_ should be set to true when
// receiving. Test that WHEN receiving files, THEN below passes.
// EXPECT_EQ(NearbySharingService::StatusCodes::kTransferAlreadyInProgress,
// RegisterSendSurface(SendSurfaceState::kForeground));
// EXPECT_FALSE(fake_nearby_connections_manager_->IsDiscovering());
// EXPECT_FALSE(fake_nearby_connections_manager_->IsShutdown());
}
TEST_F(NearbySharingServiceImplTest,
BackgroundRegisterSendSurfaceNotDiscovering) {
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
MockTransferUpdateCallback transfer_callback;
MockShareTargetDiscoveredCallback discovery_callback;
EXPECT_EQ(
NearbySharingService::StatusCodes::kOk,
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kBackground));
EXPECT_FALSE(fake_nearby_connections_manager_->IsDiscovering());
EXPECT_FALSE(fake_nearby_connections_manager_->IsShutdown());
}
TEST_F(NearbySharingServiceImplTest,
DifferentSurfaceRegisterSendSurfaceTwiceKeepsDiscovering) {
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
MockTransferUpdateCallback transfer_callback;
MockShareTargetDiscoveredCallback discovery_callback;
EXPECT_EQ(
NearbySharingService::StatusCodes::kOk,
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kForeground));
EXPECT_TRUE(fake_nearby_connections_manager_->IsDiscovering());
EXPECT_EQ(
NearbySharingService::StatusCodes::kError,
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kBackground));
EXPECT_TRUE(fake_nearby_connections_manager_->IsDiscovering());
}
TEST_F(NearbySharingServiceImplTest,
RegisterSendSurfaceEndpointFoundDiscoveryCallbackNotified) {
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
// Ensure decoder parses a valid endpoint advertisement.
NiceMock<MockNearbySharingDecoder> mock_decoder;
std::vector<uint8_t> endpoint_info(kEndpointInfo,
kEndpointInfo + kEndpointInfoSize);
std::vector<uint8_t> metadata_encryption_key(
kMetadataEncryptionKeyHashByte,
kMetadataEncryptionKeyHashByte +
sharing::Advertisement::kMetadataEncryptionKeyHashByteSize);
std::vector<uint8_t> salt(kSalt, kSalt + sharing::Advertisement::kSaltSize);
EXPECT_CALL(mock_decoder,
DecodeAdvertisement(testing::Eq(endpoint_info), testing::_))
.WillOnce(testing::Invoke(
[&salt, &metadata_encryption_key](
const std::vector<uint8_t>& data,
MockNearbySharingDecoder::DecodeAdvertisementCallback callback) {
sharing::mojom::AdvertisementPtr mojo_adv =
sharing::mojom::Advertisement::New(
salt, metadata_encryption_key, kDeviceName);
std::move(callback).Run(std::move(mojo_adv));
}));
EXPECT_CALL(mock_nearby_process_manager(),
GetOrStartNearbySharingDecoder(testing::_))
.WillRepeatedly(testing::Return(&mock_decoder));
// Start discovering, to ensure a discovery listener is registered.
base::RunLoop run_loop;
MockTransferUpdateCallback transfer_callback;
NiceMock<MockShareTargetDiscoveredCallback> discovery_callback;
EXPECT_EQ(
NearbySharingService::StatusCodes::kOk,
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kForeground));
EXPECT_TRUE(fake_nearby_connections_manager_->IsDiscovering());
// Discover a new endpoint.
EXPECT_CALL(discovery_callback, OnShareTargetDiscovered)
.WillOnce([&run_loop](ShareTarget share_target) {
EXPECT_EQ(kDeviceName, share_target.device_name);
run_loop.Quit();
});
fake_nearby_connections_manager_->OnEndpointFound(
kEndpointId,
location::nearby::connections::mojom::DiscoveredEndpointInfo::New(
endpoint_info, kServiceId));
run_loop.Run();
// Register another send surface, which will automatically catch up discovered
// endpoints.
base::RunLoop run_loop2;
MockTransferUpdateCallback transfer_callback2;
NiceMock<MockShareTargetDiscoveredCallback> discovery_callback2;
EXPECT_CALL(discovery_callback2, OnShareTargetDiscovered)
.WillOnce([&run_loop2](ShareTarget share_target) {
EXPECT_EQ(kDeviceName, share_target.device_name);
run_loop2.Quit();
});
EXPECT_EQ(
NearbySharingService::StatusCodes::kOk,
service_->RegisterSendSurface(&transfer_callback2, &discovery_callback2,
SendSurfaceState::kForeground));
run_loop2.Run();
}
TEST_P(NearbySharingServiceImplValidSendTest,
RegisterSendSurfaceIsDiscovering) {
ui::ScopedSetIdleState idle_state(GetParam().idle_state);
is_bluetooth_present_ = GetParam().bluetooth_enabled;
SetConnectionType(GetParam().connection_type);
MockTransferUpdateCallback transfer_callback;
MockShareTargetDiscoveredCallback discovery_callback;
EXPECT_EQ(
NearbySharingService::StatusCodes::kOk,
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kForeground));
EXPECT_TRUE(fake_nearby_connections_manager_->IsDiscovering());
}
INSTANTIATE_TEST_SUITE_P(NearbySharingServiceImplTest,
NearbySharingServiceImplValidSendTest,
testing::ValuesIn(kValidSendSurfaceTestData));
TEST_P(NearbySharingServiceImplInvalidSendTest,
RegisterSendSurfaceNotDiscovering) {
ui::ScopedSetIdleState idle_state(GetParam().idle_state);
is_bluetooth_present_ = GetParam().bluetooth_enabled;
SetConnectionType(GetParam().connection_type);
MockTransferUpdateCallback transfer_callback;
MockShareTargetDiscoveredCallback discovery_callback;
EXPECT_FALSE(fake_nearby_connections_manager_->IsDiscovering());
EXPECT_EQ(
NearbySharingService::StatusCodes::kOk,
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kForeground));
EXPECT_FALSE(fake_nearby_connections_manager_->IsDiscovering());
EXPECT_FALSE(fake_nearby_connections_manager_->IsShutdown());
}
INSTANTIATE_TEST_SUITE_P(NearbySharingServiceImplTest,
NearbySharingServiceImplInvalidSendTest,
testing::ValuesIn(kInvalidSendSurfaceTestData));
TEST_F(NearbySharingServiceImplTest, DisableFeatureSendSurfaceNotDiscovering) {
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
prefs_.SetBoolean(prefs::kNearbySharingEnabledPrefName, false);
service_->FlushMojoForTesting();
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
MockTransferUpdateCallback transfer_callback;
MockShareTargetDiscoveredCallback discovery_callback;
EXPECT_EQ(
NearbySharingService::StatusCodes::kOk,
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kForeground));
EXPECT_FALSE(fake_nearby_connections_manager_->IsDiscovering());
EXPECT_TRUE(fake_nearby_connections_manager_->IsShutdown());
}
TEST_F(NearbySharingServiceImplTest,
DisableFeatureSendSurfaceStopsDiscovering) {
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
MockTransferUpdateCallback transfer_callback;
MockShareTargetDiscoveredCallback discovery_callback;
EXPECT_EQ(
NearbySharingService::StatusCodes::kOk,
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kForeground));
EXPECT_TRUE(fake_nearby_connections_manager_->IsDiscovering());
prefs_.SetBoolean(prefs::kNearbySharingEnabledPrefName, false);
service_->FlushMojoForTesting();
EXPECT_FALSE(fake_nearby_connections_manager_->IsDiscovering());
EXPECT_TRUE(fake_nearby_connections_manager_->IsShutdown());
}
TEST_F(NearbySharingServiceImplTest, UnregisterSendSurfaceStopsDiscovering) {
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
MockTransferUpdateCallback transfer_callback;
MockShareTargetDiscoveredCallback discovery_callback;
EXPECT_EQ(
NearbySharingService::StatusCodes::kOk,
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kForeground));
EXPECT_TRUE(fake_nearby_connections_manager_->IsDiscovering());
EXPECT_EQ(
NearbySharingService::StatusCodes::kOk,
service_->UnregisterSendSurface(&transfer_callback, &discovery_callback));
EXPECT_FALSE(fake_nearby_connections_manager_->IsDiscovering());
EXPECT_FALSE(fake_nearby_connections_manager_->IsShutdown());
}
TEST_F(NearbySharingServiceImplTest,
UnregisterSendSurfaceDifferentCallbackKeepDiscovering) {
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
MockTransferUpdateCallback transfer_callback;
MockShareTargetDiscoveredCallback discovery_callback;
EXPECT_EQ(
NearbySharingService::StatusCodes::kOk,
service_->RegisterSendSurface(&transfer_callback, &discovery_callback,
SendSurfaceState::kForeground));
EXPECT_TRUE(fake_nearby_connections_manager_->IsDiscovering());
MockTransferUpdateCallback transfer_callback2;
MockShareTargetDiscoveredCallback discovery_callback2;
EXPECT_EQ(NearbySharingService::StatusCodes::kError,
service_->UnregisterSendSurface(&transfer_callback2,
&discovery_callback2));
EXPECT_TRUE(fake_nearby_connections_manager_->IsDiscovering());
}
TEST_F(NearbySharingServiceImplTest, UnregisterSendSurfaceNeverRegistered) {
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
MockTransferUpdateCallback transfer_callback;
MockShareTargetDiscoveredCallback discovery_callback;
EXPECT_EQ(
NearbySharingService::StatusCodes::kError,
service_->UnregisterSendSurface(&transfer_callback, &discovery_callback));
EXPECT_FALSE(fake_nearby_connections_manager_->IsDiscovering());
}
TEST_F(NearbySharingServiceImplTest, TEST_F(NearbySharingServiceImplTest,
ForegroundRegisterReceiveSurfaceIsAdvertising) { ForegroundRegisterReceiveSurfaceIsAdvertising) {
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE); ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
......
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