Commit 9c51ffbd authored by James Vecore's avatar James Vecore Committed by Commit Bot

[Nearby] Add observation interface to service

This CL adds an observer interface to allow clients of the service to
be notified when high visibility state changes as well query the current
state. Previously, high-visibility was not part of the api. It was an
implied state when a foreground receive surface was registered and
advertising was is started successfully with a device name in the
end-point info. This change makes it possible to query and monitor high
visibility so UI surfaces can be in sync with the service state.

Additional methods will be added to the observer interface in follow up
CLs (i.e. Shutdown).

Change-Id: I40b718fb9fb1ab185ef45a4ff0085d4c59c8bad5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2401851
Commit-Queue: James Vecore <vecore@google.com>
Reviewed-by: default avatarRyan Hansberry <hansberry@chromium.org>
Cr-Commit-Position: refs/heads/master@{#805888}
parent 9ad236a9
...@@ -3411,6 +3411,7 @@ static_library("browser") { ...@@ -3411,6 +3411,7 @@ static_library("browser") {
"nearby_sharing/nearby_connection.h", "nearby_sharing/nearby_connection.h",
"nearby_sharing/nearby_connection_impl.cc", "nearby_sharing/nearby_connection_impl.cc",
"nearby_sharing/nearby_connection_impl.h", "nearby_sharing/nearby_connection_impl.h",
"nearby_sharing/nearby_connections_manager.cc",
"nearby_sharing/nearby_connections_manager.h", "nearby_sharing/nearby_connections_manager.h",
"nearby_sharing/nearby_connections_manager_impl.cc", "nearby_sharing/nearby_connections_manager_impl.cc",
"nearby_sharing/nearby_connections_manager_impl.h", "nearby_sharing/nearby_connections_manager_impl.h",
......
...@@ -25,6 +25,8 @@ void FakeNearbyConnectionsManager::StartAdvertising( ...@@ -25,6 +25,8 @@ void FakeNearbyConnectionsManager::StartAdvertising(
advertising_data_usage_ = data_usage; advertising_data_usage_ = data_usage;
advertising_power_level_ = power_level; advertising_power_level_ = power_level;
adverting_endpoint_info_ = std::move(endpoint_info); adverting_endpoint_info_ = std::move(endpoint_info);
std::move(callback).Run(
NearbyConnectionsManager::ConnectionsStatus::kSuccess);
} }
void FakeNearbyConnectionsManager::StopAdvertising() { void FakeNearbyConnectionsManager::StopAdvertising() {
......
...@@ -14,6 +14,11 @@ class MockNearbySharingService : public NearbySharingService { ...@@ -14,6 +14,11 @@ class MockNearbySharingService : public NearbySharingService {
~MockNearbySharingService() override; ~MockNearbySharingService() override;
// NearbySharingService: // NearbySharingService:
MOCK_METHOD(void, AddObserver, (NearbySharingService::Observer*), (override));
MOCK_METHOD(void,
RemoveObserver,
(NearbySharingService::Observer*),
(override));
MOCK_METHOD(StatusCodes, MOCK_METHOD(StatusCodes,
RegisterSendSurface, RegisterSendSurface,
(TransferUpdateCallback*, (TransferUpdateCallback*,
...@@ -32,6 +37,7 @@ class MockNearbySharingService : public NearbySharingService { ...@@ -32,6 +37,7 @@ class MockNearbySharingService : public NearbySharingService {
UnregisterReceiveSurface, UnregisterReceiveSurface,
(TransferUpdateCallback*), (TransferUpdateCallback*),
(override)); (override));
MOCK_METHOD(bool, IsInHighVisibility, (), (override));
MOCK_METHOD(StatusCodes, MOCK_METHOD(StatusCodes,
SendAttachments, SendAttachments,
(const ShareTarget&, std::vector<std::unique_ptr<Attachment>>), (const ShareTarget&, std::vector<std::unique_ptr<Attachment>>),
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/nearby_sharing/nearby_connections_manager.h"
// static
std::string NearbyConnectionsManager::ConnectionsStatusToString(
ConnectionsStatus status) {
switch (status) {
case ConnectionsStatus::kSuccess:
return "kSuccess";
case ConnectionsStatus::kError:
return "kError";
case ConnectionsStatus::kOutOfOrderApiCall:
return "kOutOfOrderApiCall";
case ConnectionsStatus::kAlreadyHaveActiveStrategy:
return "kAlreadyHaveActiveStrategy";
case ConnectionsStatus::kAlreadyAdvertising:
return "kAlreadyAdvertising";
case ConnectionsStatus::kAlreadyDiscovering:
return "kAlreadyDiscovering";
case ConnectionsStatus::kEndpointIOError:
return "kEndpointIOError";
case ConnectionsStatus::kEndpointUnknown:
return "kEndpointUnknown";
case ConnectionsStatus::kConnectionRejected:
return "kConnectionRejected";
case ConnectionsStatus::kAlreadyConnectedToEndpoint:
return "kAlreadyConnectedToEndpoint";
case ConnectionsStatus::kNotConnectedToEndpoint:
return "kNotConnectedToEndpoint";
case ConnectionsStatus::kBluetoothError:
return "kBluetoothError";
case ConnectionsStatus::kBleError:
return "kBleError";
case ConnectionsStatus::kWifiLanError:
return "kWifiLanError";
case ConnectionsStatus::kPayloadUnknown:
return "kPayloadUnknown";
}
}
...@@ -64,6 +64,9 @@ class NearbyConnectionsManager { ...@@ -64,6 +64,9 @@ class NearbyConnectionsManager {
virtual void OnStatusUpdate(PayloadTransferUpdatePtr update) = 0; virtual void OnStatusUpdate(PayloadTransferUpdatePtr update) = 0;
}; };
// Converts the status to a logging-friendly string.
static std::string ConnectionsStatusToString(ConnectionsStatus status);
virtual ~NearbyConnectionsManager() = default; virtual ~NearbyConnectionsManager() = default;
// Disconnects from all endpoints and shut down Nearby Connections. // Disconnects from all endpoints and shut down Nearby Connections.
......
...@@ -47,43 +47,6 @@ bool ShouldEnableWebRtc(DataUsage data_usage, PowerLevel power_level) { ...@@ -47,43 +47,6 @@ bool ShouldEnableWebRtc(DataUsage data_usage, PowerLevel power_level) {
} // namespace } // namespace
// static
std::string NearbyConnectionsManagerImpl::ConnectionsStatusToString(
ConnectionsStatus status) {
switch (status) {
case ConnectionsStatus::kSuccess:
return "kSuccess";
case ConnectionsStatus::kError:
return "kError";
case ConnectionsStatus::kOutOfOrderApiCall:
return "kOutOfOrderApiCall";
case ConnectionsStatus::kAlreadyHaveActiveStrategy:
return "kAlreadyHaveActiveStrategy";
case ConnectionsStatus::kAlreadyAdvertising:
return "kAlreadyAdvertising";
case ConnectionsStatus::kAlreadyDiscovering:
return "kAlreadyDiscovering";
case ConnectionsStatus::kEndpointIOError:
return "kEndpointIOError";
case ConnectionsStatus::kEndpointUnknown:
return "kEndpointUnknown";
case ConnectionsStatus::kConnectionRejected:
return "kConnectionRejected";
case ConnectionsStatus::kAlreadyConnectedToEndpoint:
return "kAlreadyConnectedToEndpoint";
case ConnectionsStatus::kNotConnectedToEndpoint:
return "kNotConnectedToEndpoint";
case ConnectionsStatus::kBluetoothError:
return "kBluetoothError";
case ConnectionsStatus::kBleError:
return "kBleError";
case ConnectionsStatus::kWifiLanError:
return "kWifiLanError";
case ConnectionsStatus::kPayloadUnknown:
return "kPayloadUnknown";
}
}
NearbyConnectionsManagerImpl::NearbyConnectionsManagerImpl( NearbyConnectionsManagerImpl::NearbyConnectionsManagerImpl(
NearbyProcessManager* process_manager, NearbyProcessManager* process_manager,
Profile* profile) Profile* profile)
......
...@@ -69,9 +69,6 @@ class NearbyConnectionsManagerImpl ...@@ -69,9 +69,6 @@ class NearbyConnectionsManagerImpl
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;
// Converts the status to a logging-friendly string.
static std::string ConnectionsStatusToString(ConnectionsStatus status);
private: private:
using AdvertisingOptions = using AdvertisingOptions =
location::nearby::connections::mojom::AdvertisingOptions; location::nearby::connections::mojom::AdvertisingOptions;
......
...@@ -62,11 +62,19 @@ class NearbySharingService : public KeyedService { ...@@ -62,11 +62,19 @@ class NearbySharingService : public KeyedService {
kForeground, kForeground,
}; };
class Observer : public base::CheckedObserver {
public:
virtual void OnHighVisibilityChanged(bool in_high_visibility) = 0;
};
using StatusCodesCallback = using StatusCodesCallback =
base::OnceCallback<void(StatusCodes status_codes)>; base::OnceCallback<void(StatusCodes status_codes)>;
~NearbySharingService() override = default; ~NearbySharingService() override = default;
virtual void AddObserver(Observer* observer) = 0;
virtual void RemoveObserver(Observer* observer) = 0;
// Registers a send surface for handling payload transfer status and device // Registers a send surface for handling payload transfer status and device
// discovery. // discovery.
virtual StatusCodes RegisterSendSurface( virtual StatusCodes RegisterSendSurface(
...@@ -84,10 +92,13 @@ class NearbySharingService : public KeyedService { ...@@ -84,10 +92,13 @@ class NearbySharingService : public KeyedService {
TransferUpdateCallback* transfer_callback, TransferUpdateCallback* transfer_callback,
ReceiveSurfaceState state) = 0; ReceiveSurfaceState state) = 0;
// Unregistesrs the current receive surface. // Unregisters the current receive surface.
virtual StatusCodes UnregisterReceiveSurface( virtual StatusCodes UnregisterReceiveSurface(
TransferUpdateCallback* transfer_callback) = 0; TransferUpdateCallback* transfer_callback) = 0;
// Returns true if a foreground receive surface is registered.
virtual bool IsInHighVisibility() = 0;
// Sends |attachments| to the remote |share_target|. // Sends |attachments| to the remote |share_target|.
virtual StatusCodes SendAttachments( virtual StatusCodes SendAttachments(
const ShareTarget& share_target, const ShareTarget& share_target,
......
...@@ -303,6 +303,16 @@ void NearbySharingServiceImpl::Shutdown() { ...@@ -303,6 +303,16 @@ void NearbySharingServiceImpl::Shutdown() {
profile_ = nullptr; profile_ = nullptr;
} }
void NearbySharingServiceImpl::AddObserver(
NearbySharingService::Observer* observer) {
observers_.AddObserver(observer);
}
void NearbySharingServiceImpl::RemoveObserver(
NearbySharingService::Observer* observer) {
observers_.RemoveObserver(observer);
}
NearbySharingService::StatusCodes NearbySharingServiceImpl::RegisterSendSurface( NearbySharingService::StatusCodes NearbySharingServiceImpl::RegisterSendSurface(
TransferUpdateCallback* transfer_callback, TransferUpdateCallback* transfer_callback,
ShareTargetDiscoveredCallback* discovery_callback, ShareTargetDiscoveredCallback* discovery_callback,
...@@ -524,6 +534,10 @@ NearbySharingServiceImpl::UnregisterReceiveSurface( ...@@ -524,6 +534,10 @@ NearbySharingServiceImpl::UnregisterReceiveSurface(
return StatusCodes::kOk; return StatusCodes::kOk;
} }
bool NearbySharingServiceImpl::IsInHighVisibility() {
return in_high_visibility;
}
void NearbySharingServiceImpl::Accept( void NearbySharingServiceImpl::Accept(
const ShareTarget& share_target, const ShareTarget& share_target,
StatusCodesCallback status_codes_callback) { StatusCodesCallback status_codes_callback) {
...@@ -1203,23 +1217,36 @@ void NearbySharingServiceImpl::InvalidateAdvertisingState() { ...@@ -1203,23 +1217,36 @@ void NearbySharingServiceImpl::InvalidateAdvertisingState() {
nearby_connections_manager_->StartAdvertising( nearby_connections_manager_->StartAdvertising(
*endpoint_info, *endpoint_info,
/* listener= */ this, power_level, data_usage, /* listener= */ this, power_level, data_usage,
base::BindOnce([](NearbyConnectionsManager::ConnectionsStatus status) { base::BindOnce(&NearbySharingServiceImpl::OnStartAdvertisingResult,
NS_LOG(VERBOSE) weak_ptr_factory_.GetWeakPtr(), device_name.has_value()));
<< __func__
<< ": Advertising attempted over Nearby Connections with result "
<< status;
}));
advertising_power_level_ = power_level; advertising_power_level_ = power_level;
NS_LOG(VERBOSE) << __func__ NS_LOG(VERBOSE) << __func__
<< ": Advertising has started over Nearby Connections: " << ": StartAdvertising requested over Nearby Connections: "
<< " power level " << PowerLevelToString(power_level) << " power level: " << PowerLevelToString(power_level)
<< " visibility " << settings_.GetVisibility() << " visibility: " << settings_.GetVisibility()
<< " data usage " << data_usage; << " data usage: " << data_usage << " device name: "
<< device_name.value_or("** no device name **");
return; return;
} }
void NearbySharingServiceImpl::OnStartAdvertisingResult(
bool used_device_name,
NearbyConnectionsManager::ConnectionsStatus status) {
if (status == NearbyConnectionsManager::ConnectionsStatus::kSuccess) {
NS_LOG(VERBOSE)
<< "StartAdvertising over Nearby Connections was successful.";
SetInHighVisibility(used_device_name);
} else {
NS_LOG(ERROR) << "StartAdvertising over Nearby Connections failed: "
<< NearbyConnectionsManager::ConnectionsStatusToString(
status);
SetInHighVisibility(false);
}
}
void NearbySharingServiceImpl::StopAdvertising() { void NearbySharingServiceImpl::StopAdvertising() {
SetInHighVisibility(false);
if (advertising_power_level_ == PowerLevel::kUnknown) { if (advertising_power_level_ == PowerLevel::kUnknown) {
NS_LOG(VERBOSE) NS_LOG(VERBOSE)
<< __func__ << __func__
...@@ -3110,3 +3137,14 @@ base::Optional<int64_t> NearbySharingServiceImpl::GetAttachmentPayloadId( ...@@ -3110,3 +3137,14 @@ base::Optional<int64_t> NearbySharingServiceImpl::GetAttachmentPayloadId(
return it->second.payload_id; return it->second.payload_id;
} }
void NearbySharingServiceImpl::SetInHighVisibility(
bool new_in_high_visibility) {
if (in_high_visibility == new_in_high_visibility)
return;
in_high_visibility = new_in_high_visibility;
for (auto& observer : observers_) {
observer.OnHighVisibilityChanged(in_high_visibility);
}
}
...@@ -69,6 +69,8 @@ class NearbySharingServiceImpl ...@@ -69,6 +69,8 @@ class NearbySharingServiceImpl
// NearbySharingService: // NearbySharingService:
void Shutdown() override; void Shutdown() override;
void AddObserver(NearbySharingService::Observer* observer) override;
void RemoveObserver(NearbySharingService::Observer* observer) override;
StatusCodes RegisterSendSurface( StatusCodes RegisterSendSurface(
TransferUpdateCallback* transfer_callback, TransferUpdateCallback* transfer_callback,
ShareTargetDiscoveredCallback* discovery_callback, ShareTargetDiscoveredCallback* discovery_callback,
...@@ -78,9 +80,9 @@ class NearbySharingServiceImpl ...@@ -78,9 +80,9 @@ class NearbySharingServiceImpl
ShareTargetDiscoveredCallback* discovery_callback) override; ShareTargetDiscoveredCallback* discovery_callback) override;
StatusCodes RegisterReceiveSurface(TransferUpdateCallback* transfer_callback, StatusCodes RegisterReceiveSurface(TransferUpdateCallback* transfer_callback,
ReceiveSurfaceState state) override; ReceiveSurfaceState state) override;
StatusCodes UnregisterReceiveSurface( StatusCodes UnregisterReceiveSurface(
TransferUpdateCallback* transfer_callback) override; TransferUpdateCallback* transfer_callback) override;
bool IsInHighVisibility() override;
StatusCodes SendAttachments( StatusCodes SendAttachments(
const ShareTarget& share_target, const ShareTarget& share_target,
std::vector<std::unique_ptr<Attachment>> attachments) override; std::vector<std::unique_ptr<Attachment>> attachments) override;
...@@ -290,6 +292,11 @@ class NearbySharingServiceImpl ...@@ -290,6 +292,11 @@ class NearbySharingServiceImpl
base::Optional<int64_t> GetAttachmentPayloadId(int64_t attachment_id); base::Optional<int64_t> GetAttachmentPayloadId(int64_t attachment_id);
void UnregisterShareTarget(const ShareTarget& share_target); void UnregisterShareTarget(const ShareTarget& share_target);
void OnStartAdvertisingResult(
bool used_device_name,
NearbyConnectionsManager::ConnectionsStatus status);
void SetInHighVisibility(bool in_high_visibility);
Profile* profile_; Profile* profile_;
NearbyShareSettings settings_; NearbyShareSettings settings_;
std::unique_ptr<NearbyConnectionsManager> nearby_connections_manager_; std::unique_ptr<NearbyConnectionsManager> nearby_connections_manager_;
...@@ -306,6 +313,8 @@ class NearbySharingServiceImpl ...@@ -306,6 +313,8 @@ class NearbySharingServiceImpl
std::unique_ptr<NearbyShareCertificateManager> certificate_manager_; std::unique_ptr<NearbyShareCertificateManager> certificate_manager_;
NearbyFileHandler file_handler_; NearbyFileHandler file_handler_;
// A list of service observers.
base::ObserverList<NearbySharingService::Observer> observers_;
// A list of foreground receivers. // A list of foreground receivers.
base::ObserverList<TransferUpdateCallback> foreground_receive_callbacks_; base::ObserverList<TransferUpdateCallback> foreground_receive_callbacks_;
// A list of foreground receivers. // A list of foreground receivers.
...@@ -376,6 +385,8 @@ class NearbySharingServiceImpl ...@@ -376,6 +385,8 @@ class NearbySharingServiceImpl
bool is_connecting_ = false; bool is_connecting_ = false;
// The time scanning began. // The time scanning began.
base::Time scanning_start_timestamp_; base::Time scanning_start_timestamp_;
// True when we are advertising with a device name visible to everyone.
bool in_high_visibility = false;
// Available free disk space for testing. Using real disk space can introduce // Available free disk space for testing. Using real disk space can introduce
// flakiness in tests. // flakiness in tests.
......
...@@ -920,6 +920,15 @@ class NearbySharingServiceImplSendFailureTest ...@@ -920,6 +920,15 @@ class NearbySharingServiceImplSendFailureTest
: public NearbySharingServiceImplTest, : public NearbySharingServiceImplTest,
public testing::WithParamInterface<SendFailureTestData> {}; public testing::WithParamInterface<SendFailureTestData> {};
class TestObserver : public NearbySharingService::Observer {
public:
void OnHighVisibilityChanged(bool in_high_visibility) override {
in_high_visibility_ = in_high_visibility;
}
bool in_high_visibility_ = false;
};
} // namespace } // namespace
TEST_F(NearbySharingServiceImplTest, AddsNearbyProcessObserver) { TEST_F(NearbySharingServiceImplTest, AddsNearbyProcessObserver) {
...@@ -3420,3 +3429,36 @@ TEST_F(NearbySharingServiceImplTest, ProfileChangedControlsAdvertising) { ...@@ -3420,3 +3429,36 @@ TEST_F(NearbySharingServiceImplTest, ProfileChangedControlsAdvertising) {
service_->OnNearbyProfileChanged(/*profile=*/nullptr); service_->OnNearbyProfileChanged(/*profile=*/nullptr);
EXPECT_TRUE(fake_nearby_connections_manager_->IsAdvertising()); EXPECT_TRUE(fake_nearby_connections_manager_->IsAdvertising());
} }
TEST_F(NearbySharingServiceImplTest,
RegisterForegroundReceiveSurfaceEntersHighVisibility) {
TestObserver observer;
NiceMock<MockTransferUpdateCallback> callback;
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
SetVisibility(nearby_share::mojom::Visibility::kAllContacts);
local_device_data_manager()->SetDeviceName(kDeviceName);
service_->AddObserver(&observer);
// To start, we should not be in high visibility state.
EXPECT_FALSE(service_->IsInHighVisibility());
// If we register a foreground surface we should end up in high visibility
// state.
SetUpForegroundReceiveSurface(callback);
// At this point we should have a new high visibility state and the observer
// should have been called as well.
EXPECT_TRUE(service_->IsInHighVisibility());
EXPECT_TRUE(observer.in_high_visibility_);
// If we unregister the foreground receive surface we should no longer be in
// high visibility and the observer should be notified.
EXPECT_EQ(NearbySharingService::StatusCodes::kOk,
service_->UnregisterReceiveSurface(&callback));
EXPECT_FALSE(service_->IsInHighVisibility());
EXPECT_FALSE(observer.in_high_visibility_);
service_->RemoveObserver(&observer);
}
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