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") {
"nearby_sharing/nearby_connection.h",
"nearby_sharing/nearby_connection_impl.cc",
"nearby_sharing/nearby_connection_impl.h",
"nearby_sharing/nearby_connections_manager.cc",
"nearby_sharing/nearby_connections_manager.h",
"nearby_sharing/nearby_connections_manager_impl.cc",
"nearby_sharing/nearby_connections_manager_impl.h",
......
......@@ -25,6 +25,8 @@ void FakeNearbyConnectionsManager::StartAdvertising(
advertising_data_usage_ = data_usage;
advertising_power_level_ = power_level;
adverting_endpoint_info_ = std::move(endpoint_info);
std::move(callback).Run(
NearbyConnectionsManager::ConnectionsStatus::kSuccess);
}
void FakeNearbyConnectionsManager::StopAdvertising() {
......
......@@ -14,6 +14,11 @@ class MockNearbySharingService : public NearbySharingService {
~MockNearbySharingService() override;
// NearbySharingService:
MOCK_METHOD(void, AddObserver, (NearbySharingService::Observer*), (override));
MOCK_METHOD(void,
RemoveObserver,
(NearbySharingService::Observer*),
(override));
MOCK_METHOD(StatusCodes,
RegisterSendSurface,
(TransferUpdateCallback*,
......@@ -32,6 +37,7 @@ class MockNearbySharingService : public NearbySharingService {
UnregisterReceiveSurface,
(TransferUpdateCallback*),
(override));
MOCK_METHOD(bool, IsInHighVisibility, (), (override));
MOCK_METHOD(StatusCodes,
SendAttachments,
(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 {
virtual void OnStatusUpdate(PayloadTransferUpdatePtr update) = 0;
};
// Converts the status to a logging-friendly string.
static std::string ConnectionsStatusToString(ConnectionsStatus status);
virtual ~NearbyConnectionsManager() = default;
// Disconnects from all endpoints and shut down Nearby Connections.
......
......@@ -47,43 +47,6 @@ bool ShouldEnableWebRtc(DataUsage data_usage, PowerLevel power_level) {
} // 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(
NearbyProcessManager* process_manager,
Profile* profile)
......
......@@ -69,9 +69,6 @@ class NearbyConnectionsManagerImpl
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:
using AdvertisingOptions =
location::nearby::connections::mojom::AdvertisingOptions;
......
......@@ -62,11 +62,19 @@ class NearbySharingService : public KeyedService {
kForeground,
};
class Observer : public base::CheckedObserver {
public:
virtual void OnHighVisibilityChanged(bool in_high_visibility) = 0;
};
using StatusCodesCallback =
base::OnceCallback<void(StatusCodes status_codes)>;
~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
// discovery.
virtual StatusCodes RegisterSendSurface(
......@@ -84,10 +92,13 @@ class NearbySharingService : public KeyedService {
TransferUpdateCallback* transfer_callback,
ReceiveSurfaceState state) = 0;
// Unregistesrs the current receive surface.
// Unregisters the current receive surface.
virtual StatusCodes UnregisterReceiveSurface(
TransferUpdateCallback* transfer_callback) = 0;
// Returns true if a foreground receive surface is registered.
virtual bool IsInHighVisibility() = 0;
// Sends |attachments| to the remote |share_target|.
virtual StatusCodes SendAttachments(
const ShareTarget& share_target,
......
......@@ -303,6 +303,16 @@ void NearbySharingServiceImpl::Shutdown() {
profile_ = nullptr;
}
void NearbySharingServiceImpl::AddObserver(
NearbySharingService::Observer* observer) {
observers_.AddObserver(observer);
}
void NearbySharingServiceImpl::RemoveObserver(
NearbySharingService::Observer* observer) {
observers_.RemoveObserver(observer);
}
NearbySharingService::StatusCodes NearbySharingServiceImpl::RegisterSendSurface(
TransferUpdateCallback* transfer_callback,
ShareTargetDiscoveredCallback* discovery_callback,
......@@ -524,6 +534,10 @@ NearbySharingServiceImpl::UnregisterReceiveSurface(
return StatusCodes::kOk;
}
bool NearbySharingServiceImpl::IsInHighVisibility() {
return in_high_visibility;
}
void NearbySharingServiceImpl::Accept(
const ShareTarget& share_target,
StatusCodesCallback status_codes_callback) {
......@@ -1203,23 +1217,36 @@ void NearbySharingServiceImpl::InvalidateAdvertisingState() {
nearby_connections_manager_->StartAdvertising(
*endpoint_info,
/* listener= */ this, power_level, data_usage,
base::BindOnce([](NearbyConnectionsManager::ConnectionsStatus status) {
NS_LOG(VERBOSE)
<< __func__
<< ": Advertising attempted over Nearby Connections with result "
<< status;
}));
base::BindOnce(&NearbySharingServiceImpl::OnStartAdvertisingResult,
weak_ptr_factory_.GetWeakPtr(), device_name.has_value()));
advertising_power_level_ = power_level;
NS_LOG(VERBOSE) << __func__
<< ": Advertising has started over Nearby Connections: "
<< " power level " << PowerLevelToString(power_level)
<< " visibility " << settings_.GetVisibility()
<< " data usage " << data_usage;
<< ": StartAdvertising requested over Nearby Connections: "
<< " power level: " << PowerLevelToString(power_level)
<< " visibility: " << settings_.GetVisibility()
<< " data usage: " << data_usage << " device name: "
<< device_name.value_or("** no device name **");
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() {
SetInHighVisibility(false);
if (advertising_power_level_ == PowerLevel::kUnknown) {
NS_LOG(VERBOSE)
<< __func__
......@@ -3110,3 +3137,14 @@ base::Optional<int64_t> NearbySharingServiceImpl::GetAttachmentPayloadId(
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
// NearbySharingService:
void Shutdown() override;
void AddObserver(NearbySharingService::Observer* observer) override;
void RemoveObserver(NearbySharingService::Observer* observer) override;
StatusCodes RegisterSendSurface(
TransferUpdateCallback* transfer_callback,
ShareTargetDiscoveredCallback* discovery_callback,
......@@ -78,9 +80,9 @@ class NearbySharingServiceImpl
ShareTargetDiscoveredCallback* discovery_callback) override;
StatusCodes RegisterReceiveSurface(TransferUpdateCallback* transfer_callback,
ReceiveSurfaceState state) override;
StatusCodes UnregisterReceiveSurface(
TransferUpdateCallback* transfer_callback) override;
bool IsInHighVisibility() override;
StatusCodes SendAttachments(
const ShareTarget& share_target,
std::vector<std::unique_ptr<Attachment>> attachments) override;
......@@ -290,6 +292,11 @@ class NearbySharingServiceImpl
base::Optional<int64_t> GetAttachmentPayloadId(int64_t attachment_id);
void UnregisterShareTarget(const ShareTarget& share_target);
void OnStartAdvertisingResult(
bool used_device_name,
NearbyConnectionsManager::ConnectionsStatus status);
void SetInHighVisibility(bool in_high_visibility);
Profile* profile_;
NearbyShareSettings settings_;
std::unique_ptr<NearbyConnectionsManager> nearby_connections_manager_;
......@@ -306,6 +313,8 @@ class NearbySharingServiceImpl
std::unique_ptr<NearbyShareCertificateManager> certificate_manager_;
NearbyFileHandler file_handler_;
// A list of service observers.
base::ObserverList<NearbySharingService::Observer> observers_;
// A list of foreground receivers.
base::ObserverList<TransferUpdateCallback> foreground_receive_callbacks_;
// A list of foreground receivers.
......@@ -376,6 +385,8 @@ class NearbySharingServiceImpl
bool is_connecting_ = false;
// The time scanning began.
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
// flakiness in tests.
......
......@@ -920,6 +920,15 @@ class NearbySharingServiceImplSendFailureTest
: public NearbySharingServiceImplTest,
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
TEST_F(NearbySharingServiceImplTest, AddsNearbyProcessObserver) {
......@@ -3420,3 +3429,36 @@ TEST_F(NearbySharingServiceImplTest, ProfileChangedControlsAdvertising) {
service_->OnNearbyProfileChanged(/*profile=*/nullptr);
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