blob: 38937f6bd9fe73ad3ede42e1698f825a89a8be14 [file] [log] [blame]
// Copyright 2017 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 "base/callback_forward.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process_impl.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "content/public/browser/network_connection_tracker.h"
#include "content/public/common/service_manager_connection.h"
#include "content/public/common/service_names.mojom.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "net/base/network_change_notifier.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/mojom/network_service_test.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
namespace content {
namespace {
class TestNetworkConnectionObserver
: public NetworkConnectionTracker::NetworkConnectionObserver {
public:
explicit TestNetworkConnectionObserver(NetworkConnectionTracker* tracker)
: num_notifications_(0),
tracker_(tracker),
connection_type_(network::mojom::ConnectionType::CONNECTION_UNKNOWN) {
tracker_->AddNetworkConnectionObserver(this);
}
~TestNetworkConnectionObserver() override {
tracker_->RemoveNetworkConnectionObserver(this);
}
// NetworkConnectionObserver implementation:
void OnConnectionChanged(network::mojom::ConnectionType type) override {
network::mojom::ConnectionType queried_type;
bool sync = tracker_->GetConnectionType(
&queried_type,
base::BindOnce([](network::mojom::ConnectionType type) {}));
EXPECT_TRUE(sync);
EXPECT_EQ(type, queried_type);
num_notifications_++;
connection_type_ = type;
run_loop_.Quit();
}
void WaitForNotification() { run_loop_.Run(); }
size_t num_notifications() const { return num_notifications_; }
network::mojom::ConnectionType connection_type() const {
return connection_type_;
}
private:
size_t num_notifications_;
NetworkConnectionTracker* tracker_;
base::RunLoop run_loop_;
network::mojom::ConnectionType connection_type_;
DISALLOW_COPY_AND_ASSIGN(TestNetworkConnectionObserver);
};
} // namespace
class NetworkConnectionTrackerBrowserTest
: public InProcessBrowserTest,
public testing::WithParamInterface<bool> {
public:
NetworkConnectionTrackerBrowserTest() : network_service_enabled_(GetParam()) {
if (network_service_enabled_) {
scoped_feature_list_.InitAndEnableFeature(
network::features::kNetworkService);
} else {
scoped_feature_list_.InitAndDisableFeature(
network::features::kNetworkService);
}
}
~NetworkConnectionTrackerBrowserTest() override {}
// Simulates a network connection change.
void SimulateNetworkChange(network::mojom::ConnectionType type) {
if (network_service_enabled_ &&
!content::IsNetworkServiceRunningInProcess()) {
network::mojom::NetworkServiceTestPtr network_service_test;
ServiceManagerConnection::GetForProcess()->GetConnector()->BindInterface(
mojom::kNetworkServiceName, &network_service_test);
base::RunLoop run_loop;
network_service_test->SimulateNetworkChange(
type, base::Bind([](base::RunLoop* run_loop) { run_loop->Quit(); },
base::Unretained(&run_loop)));
run_loop.Run();
return;
}
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::ConnectionType(type));
}
bool network_service_enabled() const { return network_service_enabled_; }
private:
base::test::ScopedFeatureList scoped_feature_list_;
const bool network_service_enabled_;
};
// Basic test to make sure NetworkConnectionTracker is set up.
IN_PROC_BROWSER_TEST_P(NetworkConnectionTrackerBrowserTest,
NetworkConnectionTracker) {
#if defined(OS_CHROMEOS) || defined(OS_MACOSX)
// NetworkService on ChromeOS doesn't yet have a NetworkChangeManager
// implementation. OSX uses a separate binary for service processes and
// browser test fixture doesn't have NetworkServiceTest mojo code.
if (network_service_enabled())
return;
#endif
NetworkConnectionTracker* tracker =
g_browser_process->network_connection_tracker();
EXPECT_NE(nullptr, tracker);
// Issue a GetConnectionType() request to make sure NetworkService has been
// started up. This way, NetworkService will receive the broadcast when
// SimulateNetworkChange() is called.
base::RunLoop run_loop;
network::mojom::ConnectionType ignored_type;
bool sync = tracker->GetConnectionType(
&ignored_type,
base::BindOnce(
[](base::RunLoop* run_loop, network::mojom::ConnectionType type) {
run_loop->Quit();
},
base::Unretained(&run_loop)));
if (!sync)
run_loop.Run();
TestNetworkConnectionObserver network_connection_observer(tracker);
SimulateNetworkChange(network::mojom::ConnectionType::CONNECTION_3G);
network_connection_observer.WaitForNotification();
EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_3G,
network_connection_observer.connection_type());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, network_connection_observer.num_notifications());
}
INSTANTIATE_TEST_CASE_P(/* no prefix */,
NetworkConnectionTrackerBrowserTest,
testing::Bool());
} // namespace content