Commit 1a84bb65 authored by Kyle Horimoto's avatar Kyle Horimoto Committed by Commit Bot

[CrOS Tether] Show the "Enable Bluetooth" notification when appropriate.

The notification can be shown during two point in time: when the user logs in,
and when the user disconnects from the Internet. In order for the notification
to be shown, Bluetooth must be disabled, the device must be disconnected from
the Internet, and there must be nothing besides Bluetooth preventing a Tether
scan from beginning.

This CL also changes the ownership of TetherNotificationPresenter. Now, one
instance is created and owned by TetherService and is passed through to the
Tether component when needed. Previously, the instance was owned by the Tether
component, but this no longer worked due to the fact that TetherService needed
to be able to display the "enable Bluetooth" notification when Tether was left
uninitialized (due to Bluetooth being disabled).

Lastly, now TetherService only sets Tether's TechnologyState to
UNINITIALIZED when Bluetooth is disabled, which fixes an issue in which
an "enable Bluetooth" message is shown in Quick Settings when Bluetooth
is on but Cellular is disabled.

Bug: 672263, 740635
Change-Id: Id19a847a9efb7a31d23d2ffb6308fad7d46ca948
Reviewed-on: https://chromium-review.googlesource.com/580349
Commit-Queue: Kyle Horimoto <khorimoto@chromium.org>
Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#488488}
parent 35502e8f
...@@ -876,8 +876,6 @@ int GetMobileUninitializedMsg() { ...@@ -876,8 +876,6 @@ int GetMobileUninitializedMsg() {
static int s_uninitialized_msg(0); static int s_uninitialized_msg(0);
NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
// TODO(lesliewatkins): Only return this message when Tether is uninitialized
// due to no Bluetooth (dependent on codereview.chromium.org/2969493002/).
if (handler->GetTechnologyState(NetworkTypePattern::Tether()) == if (handler->GetTechnologyState(NetworkTypePattern::Tether()) ==
NetworkStateHandler::TECHNOLOGY_UNINITIALIZED) { NetworkStateHandler::TECHNOLOGY_UNINITIALIZED) {
s_uninitialized_msg = IDS_ASH_STATUS_TRAY_ENABLE_BLUETOOTH; s_uninitialized_msg = IDS_ASH_STATUS_TRAY_ENABLE_BLUETOOTH;
......
...@@ -1946,6 +1946,7 @@ source_set("unit_tests") { ...@@ -1946,6 +1946,7 @@ source_set("unit_tests") {
"//ash/resources", "//ash/resources",
"//base", "//base",
"//chrome/common", "//chrome/common",
"//chromeos/components/tether:test_support",
"//chromeos/ime:gencode", "//chromeos/ime:gencode",
"//components/cryptauth:test_support", "//components/cryptauth:test_support",
"//components/drive", "//components/drive",
......
...@@ -173,11 +173,7 @@ void TetherNotificationPresenter::NotifyMultiplePotentialHotspotsNearby() { ...@@ -173,11 +173,7 @@ void TetherNotificationPresenter::NotifyMultiplePotentialHotspotsNearby() {
} }
void TetherNotificationPresenter::RemovePotentialHotspotNotification() { void TetherNotificationPresenter::RemovePotentialHotspotNotification() {
PA_LOG(INFO) << "Removing \"potential hotspot nearby\" dialog. " RemoveNotificationIfVisible(kPotentialHotspotNotificationId);
<< "Notification ID = " << kPotentialHotspotNotificationId;
message_center_->RemoveNotification(kPotentialHotspotNotificationId,
false /* by_user */);
} }
void TetherNotificationPresenter::NotifySetupRequired( void TetherNotificationPresenter::NotifySetupRequired(
...@@ -194,11 +190,7 @@ void TetherNotificationPresenter::NotifySetupRequired( ...@@ -194,11 +190,7 @@ void TetherNotificationPresenter::NotifySetupRequired(
} }
void TetherNotificationPresenter::RemoveSetupRequiredNotification() { void TetherNotificationPresenter::RemoveSetupRequiredNotification() {
PA_LOG(INFO) << "Removing \"setup required\" dialog. " RemoveNotificationIfVisible(kSetupRequiredNotificationId);
<< "Notification ID = " << kSetupRequiredNotificationId;
message_center_->RemoveNotification(kSetupRequiredNotificationId,
false /* by_user */);
} }
void TetherNotificationPresenter::NotifyConnectionToHostFailed() { void TetherNotificationPresenter::NotifyConnectionToHostFailed() {
...@@ -214,11 +206,7 @@ void TetherNotificationPresenter::NotifyConnectionToHostFailed() { ...@@ -214,11 +206,7 @@ void TetherNotificationPresenter::NotifyConnectionToHostFailed() {
} }
void TetherNotificationPresenter::RemoveConnectionToHostFailedNotification() { void TetherNotificationPresenter::RemoveConnectionToHostFailedNotification() {
PA_LOG(INFO) << "Removing \"connection attempt failed\" dialog. " RemoveNotificationIfVisible(kActiveHostNotificationId);
<< "Notification ID = " << kActiveHostNotificationId;
message_center_->RemoveNotification(kActiveHostNotificationId,
false /* by_user */);
} }
void TetherNotificationPresenter::NotifyEnableBluetooth() { void TetherNotificationPresenter::NotifyEnableBluetooth() {
...@@ -232,11 +220,7 @@ void TetherNotificationPresenter::NotifyEnableBluetooth() { ...@@ -232,11 +220,7 @@ void TetherNotificationPresenter::NotifyEnableBluetooth() {
} }
void TetherNotificationPresenter::RemoveEnableBluetoothNotification() { void TetherNotificationPresenter::RemoveEnableBluetoothNotification() {
PA_LOG(INFO) << "Removing \"enable Bluetooth\" notification. " RemoveNotificationIfVisible(kEnableBluetoothNotificationId);
<< "Notification ID = " << kEnableBluetoothNotificationId;
message_center_->RemoveNotification(kEnableBluetoothNotificationId,
false /* by_user */);
} }
void TetherNotificationPresenter::OnNotificationClicked( void TetherNotificationPresenter::OnNotificationClicked(
...@@ -303,6 +287,16 @@ void TetherNotificationPresenter::OpenSettingsAndRemoveNotification( ...@@ -303,6 +287,16 @@ void TetherNotificationPresenter::OpenSettingsAndRemoveNotification(
message_center_->RemoveNotification(notification_id, true /* by_user */); message_center_->RemoveNotification(notification_id, true /* by_user */);
} }
void TetherNotificationPresenter::RemoveNotificationIfVisible(
const std::string& notification_id) {
if (!message_center_->FindVisibleNotificationById(notification_id))
return;
PA_LOG(INFO) << "Removing notification with ID \"" << notification_id
<< "\".";
message_center_->RemoveNotification(notification_id, false /* by_user */);
}
} // namespace tether } // namespace tether
} // namespace chromeos } // namespace chromeos
...@@ -102,6 +102,7 @@ class TetherNotificationPresenter ...@@ -102,6 +102,7 @@ class TetherNotificationPresenter
std::unique_ptr<message_center::Notification> notification); std::unique_ptr<message_center::Notification> notification);
void OpenSettingsAndRemoveNotification(const std::string& settings_subpage, void OpenSettingsAndRemoveNotification(const std::string& settings_subpage,
const std::string& notification_id); const std::string& notification_id);
void RemoveNotificationIfVisible(const std::string& notification_id);
Profile* profile_; Profile* profile_;
message_center::MessageCenter* message_center_; message_center::MessageCenter* message_center_;
......
...@@ -48,8 +48,7 @@ bool TetherService::IsFeatureFlagEnabled() { ...@@ -48,8 +48,7 @@ bool TetherService::IsFeatureFlagEnabled() {
void TetherService::InitializerDelegate::InitializeTether( void TetherService::InitializerDelegate::InitializeTether(
cryptauth::CryptAuthService* cryptauth_service, cryptauth::CryptAuthService* cryptauth_service,
std::unique_ptr<chromeos::tether::NotificationPresenter> chromeos::tether::NotificationPresenter* notification_presenter,
notification_presenter,
PrefService* pref_service, PrefService* pref_service,
ProfileOAuth2TokenService* token_service, ProfileOAuth2TokenService* token_service,
chromeos::NetworkStateHandler* network_state_handler, chromeos::NetworkStateHandler* network_state_handler,
...@@ -80,6 +79,11 @@ TetherService::TetherService( ...@@ -80,6 +79,11 @@ TetherService::TetherService(
cryptauth_service_(cryptauth_service), cryptauth_service_(cryptauth_service),
network_state_handler_(network_state_handler), network_state_handler_(network_state_handler),
initializer_delegate_(base::MakeUnique<InitializerDelegate>()), initializer_delegate_(base::MakeUnique<InitializerDelegate>()),
notification_presenter_(
base::MakeUnique<chromeos::tether::TetherNotificationPresenter>(
profile_,
message_center::MessageCenter::Get(),
chromeos::NetworkConnect::Get())),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
power_manager_client_->AddObserver(this); power_manager_client_->AddObserver(this);
session_manager_client_->AddObserver(this); session_manager_client_->AddObserver(this);
...@@ -111,13 +115,8 @@ void TetherService::StartTetherIfEnabled() { ...@@ -111,13 +115,8 @@ void TetherService::StartTetherIfEnabled() {
return; return;
} }
auto notification_presenter =
base::MakeUnique<chromeos::tether::TetherNotificationPresenter>(
profile_, message_center::MessageCenter::Get(),
chromeos::NetworkConnect::Get());
initializer_delegate_->InitializeTether( initializer_delegate_->InitializeTether(
cryptauth_service_, std::move(notification_presenter), cryptauth_service_, notification_presenter_.get(), profile_->GetPrefs(),
profile_->GetPrefs(),
ProfileOAuth2TokenServiceFactory::GetForProfile(profile_), ProfileOAuth2TokenServiceFactory::GetForProfile(profile_),
network_state_handler_, network_state_handler_,
chromeos::NetworkHandler::Get()->managed_network_configuration_handler(), chromeos::NetworkHandler::Get()->managed_network_configuration_handler(),
...@@ -144,6 +143,7 @@ void TetherService::Shutdown() { ...@@ -144,6 +143,7 @@ void TetherService::Shutdown() {
if (adapter_) if (adapter_)
adapter_->RemoveObserver(this); adapter_->RemoveObserver(this);
registrar_.RemoveAll(); registrar_.RemoveAll();
notification_presenter_.reset();
// Shut down the feature. Note that this does not change Tether's technology // Shut down the feature. Note that this does not change Tether's technology
// state in NetworkStateHandler because doing so could cause visual jank just // state in NetworkStateHandler because doing so could cause visual jank just
...@@ -186,6 +186,18 @@ void TetherService::AdapterPoweredChanged(device::BluetoothAdapter* adapter, ...@@ -186,6 +186,18 @@ void TetherService::AdapterPoweredChanged(device::BluetoothAdapter* adapter,
UpdateTetherTechnologyState(); UpdateTetherTechnologyState();
} }
void TetherService::DefaultNetworkChanged(
const chromeos::NetworkState* network) {
if (CanEnableBluetoothNotificationBeShown()) {
// If the device has just been disconnected from the Internet, the user may
// be looking for a way to find a connection. If Bluetooth is disabled and
// is preventing Tether connections from being found, alert the user.
notification_presenter_->NotifyEnableBluetooth();
} else {
notification_presenter_->RemoveEnableBluetoothNotification();
}
}
void TetherService::DeviceListChanged() { void TetherService::DeviceListChanged() {
bool was_pref_enabled = IsEnabledbyPreference(); bool was_pref_enabled = IsEnabledbyPreference();
chromeos::NetworkStateHandler::TechnologyState tether_technology_state = chromeos::NetworkStateHandler::TechnologyState tether_technology_state =
...@@ -237,21 +249,24 @@ void TetherService::UpdateTetherTechnologyState() { ...@@ -237,21 +249,24 @@ void TetherService::UpdateTetherTechnologyState() {
} else { } else {
StopTether(); StopTether();
} }
if (!CanEnableBluetoothNotificationBeShown())
notification_presenter_->RemoveEnableBluetoothNotification();
} }
chromeos::NetworkStateHandler::TechnologyState chromeos::NetworkStateHandler::TechnologyState
TetherService::GetTetherTechnologyState() { TetherService::GetTetherTechnologyState() {
if (shut_down_ || suspended_ || session_manager_client_->IsScreenLocked() || if (shut_down_ || suspended_ || session_manager_client_->IsScreenLocked() ||
!HasSyncedTetherHosts()) { !HasSyncedTetherHosts() || IsCellularAvailableButNotEnabled()) {
// If Cellular technology is available, then Tether technology is treated
// as a subset of Cellular, and it should only be enabled when Cellular
// technology is enabled.
return chromeos::NetworkStateHandler::TechnologyState:: return chromeos::NetworkStateHandler::TechnologyState::
TECHNOLOGY_UNAVAILABLE; TECHNOLOGY_UNAVAILABLE;
} else if (!IsAllowedByPolicy()) { } else if (!IsAllowedByPolicy()) {
return chromeos::NetworkStateHandler::TechnologyState:: return chromeos::NetworkStateHandler::TechnologyState::
TECHNOLOGY_PROHIBITED; TECHNOLOGY_PROHIBITED;
} else if (!IsBluetoothAvailable() || IsCellularAvailableButNotEnabled()) { } else if (!IsBluetoothAvailable()) {
// If Cellular technology is available, then Tether technology is treated
// as a subset of Cellular, and it should only be enabled when Cellular
// technology is enabled.
// TODO (hansberry): When !IsBluetoothAvailable(), this results in a weird // TODO (hansberry): When !IsBluetoothAvailable(), this results in a weird
// UI state for Settings where the toggle is clickable but immediately // UI state for Settings where the toggle is clickable but immediately
// becomes disabled after enabling it. Possible solution: grey out the // becomes disabled after enabling it. Possible solution: grey out the
...@@ -269,9 +284,16 @@ void TetherService::OnBluetoothAdapterFetched( ...@@ -269,9 +284,16 @@ void TetherService::OnBluetoothAdapterFetched(
scoped_refptr<device::BluetoothAdapter> adapter) { scoped_refptr<device::BluetoothAdapter> adapter) {
if (shut_down_) if (shut_down_)
return; return;
adapter_ = adapter; adapter_ = adapter;
adapter_->AddObserver(this); adapter_->AddObserver(this);
UpdateTetherTechnologyState(); UpdateTetherTechnologyState();
// The user has just logged in; display the "enable Bluetooth" notification if
// applicable.
if (CanEnableBluetoothNotificationBeShown())
notification_presenter_->NotifyEnableBluetooth();
} }
bool TetherService::IsBluetoothAvailable() const { bool TetherService::IsBluetoothAvailable() const {
...@@ -293,7 +315,34 @@ bool TetherService::IsEnabledbyPreference() const { ...@@ -293,7 +315,34 @@ bool TetherService::IsEnabledbyPreference() const {
return profile_->GetPrefs()->GetBoolean(prefs::kInstantTetheringEnabled); return profile_->GetPrefs()->GetBoolean(prefs::kInstantTetheringEnabled);
} }
bool TetherService::CanEnableBluetoothNotificationBeShown() {
if (!IsEnabledbyPreference() || IsBluetoothAvailable() ||
GetTetherTechnologyState() !=
chromeos::NetworkStateHandler::TechnologyState::
TECHNOLOGY_UNINITIALIZED) {
// Cannot be shown unless Tether is uninitialized.
return false;
}
const chromeos::NetworkState* network =
network_state_handler_->DefaultNetwork();
if (network &&
(network->IsConnectingState() || network->IsConnectedState())) {
// If an Internet connection is available, there is no need to show a
// notification which helps the user find an Internet connection.
return false;
}
return true;
}
void TetherService::SetInitializerDelegateForTest( void TetherService::SetInitializerDelegateForTest(
std::unique_ptr<InitializerDelegate> initializer_delegate) { std::unique_ptr<InitializerDelegate> initializer_delegate) {
initializer_delegate_ = std::move(initializer_delegate); initializer_delegate_ = std::move(initializer_delegate);
} }
void TetherService::SetNotificationPresenterForTest(
std::unique_ptr<chromeos::tether::NotificationPresenter>
notification_presenter) {
notification_presenter_ = std::move(notification_presenter);
}
...@@ -74,8 +74,7 @@ class TetherService : public KeyedService, ...@@ -74,8 +74,7 @@ class TetherService : public KeyedService,
public: public:
virtual void InitializeTether( virtual void InitializeTether(
cryptauth::CryptAuthService* cryptauth_service, cryptauth::CryptAuthService* cryptauth_service,
std::unique_ptr<chromeos::tether::NotificationPresenter> chromeos::tether::NotificationPresenter* notification_presenter,
notification_presenter,
PrefService* pref_service, PrefService* pref_service,
ProfileOAuth2TokenService* token_service, ProfileOAuth2TokenService* token_service,
chromeos::NetworkStateHandler* network_state_handler, chromeos::NetworkStateHandler* network_state_handler,
...@@ -108,6 +107,7 @@ class TetherService : public KeyedService, ...@@ -108,6 +107,7 @@ class TetherService : public KeyedService,
bool powered) override; bool powered) override;
// chromeos::NetworkStateHandlerObserver: // chromeos::NetworkStateHandlerObserver:
void DefaultNetworkChanged(const chromeos::NetworkState* network) override;
void DeviceListChanged() override; void DeviceListChanged() override;
// Callback when the controlling pref changes. // Callback when the controlling pref changes.
...@@ -126,6 +126,7 @@ class TetherService : public KeyedService, ...@@ -126,6 +126,7 @@ class TetherService : public KeyedService,
private: private:
friend class TetherServiceTest; friend class TetherServiceTest;
FRIEND_TEST_ALL_PREFIXES(TetherServiceTest, TestFeatureFlagEnabled); FRIEND_TEST_ALL_PREFIXES(TetherServiceTest, TestFeatureFlagEnabled);
FRIEND_TEST_ALL_PREFIXES(TetherServiceTest, TestBluetoothNotification);
void OnBluetoothAdapterFetched( void OnBluetoothAdapterFetched(
scoped_refptr<device::BluetoothAdapter> adapter); scoped_refptr<device::BluetoothAdapter> adapter);
...@@ -142,8 +143,15 @@ class TetherService : public KeyedService, ...@@ -142,8 +143,15 @@ class TetherService : public KeyedService,
// Whether Tether is enabled. // Whether Tether is enabled.
bool IsEnabledbyPreference() const; bool IsEnabledbyPreference() const;
// Returns whether the "enable Bluetooth" notification can be shown under the
// current conditions.
bool CanEnableBluetoothNotificationBeShown();
void SetInitializerDelegateForTest( void SetInitializerDelegateForTest(
std::unique_ptr<InitializerDelegate> initializer_delegate); std::unique_ptr<InitializerDelegate> initializer_delegate);
void SetNotificationPresenterForTest(
std::unique_ptr<chromeos::tether::NotificationPresenter>
notification_presenter);
// Whether the service has been shut down. // Whether the service has been shut down.
bool shut_down_ = false; bool shut_down_ = false;
...@@ -158,6 +166,8 @@ class TetherService : public KeyedService, ...@@ -158,6 +166,8 @@ class TetherService : public KeyedService,
cryptauth::CryptAuthService* cryptauth_service_; cryptauth::CryptAuthService* cryptauth_service_;
chromeos::NetworkStateHandler* network_state_handler_; chromeos::NetworkStateHandler* network_state_handler_;
std::unique_ptr<InitializerDelegate> initializer_delegate_; std::unique_ptr<InitializerDelegate> initializer_delegate_;
std::unique_ptr<chromeos::tether::NotificationPresenter>
notification_presenter_;
PrefChangeRegistrar registrar_; PrefChangeRegistrar registrar_;
scoped_refptr<device::BluetoothAdapter> adapter_; scoped_refptr<device::BluetoothAdapter> adapter_;
......
...@@ -12,13 +12,16 @@ ...@@ -12,13 +12,16 @@
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/test/scoped_feature_list.h" #include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h" #include "base/test/scoped_task_environment.h"
#include "chrome/browser/chromeos/net/tether_notification_presenter.h"
#include "chrome/common/chrome_features.h" #include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile.h"
#include "chromeos/chromeos_switches.h" #include "chromeos/chromeos_switches.h"
#include "chromeos/components/tether/fake_notification_presenter.h"
#include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_power_manager_client.h" #include "chromeos/dbus/fake_power_manager_client.h"
#include "chromeos/dbus/fake_session_manager_client.h" #include "chromeos/dbus/fake_session_manager_client.h"
#include "chromeos/dbus/fake_shill_manager_client.h"
#include "chromeos/dbus/power_manager_client.h" #include "chromeos/dbus/power_manager_client.h"
#include "chromeos/dbus/session_manager_client.h" #include "chromeos/dbus/session_manager_client.h"
#include "chromeos/network/network_connect.h" #include "chromeos/network/network_connect.h"
...@@ -37,6 +40,7 @@ ...@@ -37,6 +40,7 @@
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "ui/message_center/message_center.h" #include "ui/message_center/message_center.h"
using testing::Invoke;
using testing::NiceMock; using testing::NiceMock;
using testing::Return; using testing::Return;
...@@ -75,6 +79,7 @@ class TestTetherService : public TetherService { ...@@ -75,6 +79,7 @@ class TestTetherService : public TetherService {
session_manager_client, session_manager_client,
cryptauth_service, cryptauth_service,
network_state_handler) {} network_state_handler) {}
~TestTetherService() override {}
int updated_technology_state_count() { int updated_technology_state_count() {
return updated_technology_state_count_; return updated_technology_state_count_;
...@@ -97,8 +102,7 @@ class TestInitializerDelegate : public TetherService::InitializerDelegate { ...@@ -97,8 +102,7 @@ class TestInitializerDelegate : public TetherService::InitializerDelegate {
// TetherService::InitializerDelegate: // TetherService::InitializerDelegate:
void InitializeTether( void InitializeTether(
cryptauth::CryptAuthService* cryptauth_service, cryptauth::CryptAuthService* cryptauth_service,
std::unique_ptr<chromeos::tether::NotificationPresenter> chromeos::tether::NotificationPresenter* notification_presenter,
notification_presenter,
PrefService* pref_service, PrefService* pref_service,
ProfileOAuth2TokenService* token_service, ProfileOAuth2TokenService* token_service,
chromeos::NetworkStateHandler* network_state_handler, chromeos::NetworkStateHandler* network_state_handler,
...@@ -152,8 +156,10 @@ class TetherServiceTest : public chromeos::NetworkStateTest { ...@@ -152,8 +156,10 @@ class TetherServiceTest : public chromeos::NetworkStateTest {
mock_adapter_ = mock_adapter_ =
make_scoped_refptr(new NiceMock<device::MockBluetoothAdapter>()); make_scoped_refptr(new NiceMock<device::MockBluetoothAdapter>());
is_adapter_powered_ = true;
ON_CALL(*mock_adapter_, IsPresent()).WillByDefault(Return(true)); ON_CALL(*mock_adapter_, IsPresent()).WillByDefault(Return(true));
ON_CALL(*mock_adapter_, IsPowered()).WillByDefault(Return(true)); ON_CALL(*mock_adapter_, IsPowered())
.WillByDefault(Invoke(this, &TetherServiceTest::IsBluetoothPowered));
device::BluetoothAdapterFactory::SetAdapterForTesting(mock_adapter_); device::BluetoothAdapterFactory::SetAdapterForTesting(mock_adapter_);
} }
...@@ -170,14 +176,20 @@ class TetherServiceTest : public chromeos::NetworkStateTest { ...@@ -170,14 +176,20 @@ class TetherServiceTest : public chromeos::NetworkStateTest {
} }
void CreateTetherService() { void CreateTetherService() {
test_initializer_delegate_ = new TestInitializerDelegate();
tether_service_ = base::WrapUnique(new TestTetherService( tether_service_ = base::WrapUnique(new TestTetherService(
profile_.get(), fake_power_manager_client_.get(), profile_.get(), fake_power_manager_client_.get(),
fake_session_manager_client_.get(), fake_cryptauth_service_.get(), fake_session_manager_client_.get(), fake_cryptauth_service_.get(),
network_state_handler())); network_state_handler()));
test_initializer_delegate_ = new TestInitializerDelegate();
tether_service_->SetInitializerDelegateForTest( tether_service_->SetInitializerDelegateForTest(
base::WrapUnique(test_initializer_delegate_)); base::WrapUnique(test_initializer_delegate_));
fake_notification_presenter_ =
new chromeos::tether::FakeNotificationPresenter();
tether_service_->SetNotificationPresenterForTest(
base::WrapUnique(fake_notification_presenter_));
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
} }
...@@ -209,7 +221,17 @@ class TetherServiceTest : public chromeos::NetworkStateTest { ...@@ -209,7 +221,17 @@ class TetherServiceTest : public chromeos::NetworkStateTest {
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
} }
content::TestBrowserThreadBundle thread_bundle_; bool IsBluetoothPowered() { return is_adapter_powered_; }
void DisconnectDefaultShillNetworks() {
const chromeos::NetworkState* default_state;
while ((default_state = network_state_handler()->DefaultNetwork())) {
SetServiceProperty(default_state->path(), shill::kStateProperty,
base::Value(shill::kStateIdle));
}
}
const content::TestBrowserThreadBundle thread_bundle_;
std::unique_ptr<TestingProfile> profile_; std::unique_ptr<TestingProfile> profile_;
std::unique_ptr<chromeos::FakePowerManagerClient> fake_power_manager_client_; std::unique_ptr<chromeos::FakePowerManagerClient> fake_power_manager_client_;
...@@ -219,8 +241,12 @@ class TetherServiceTest : public chromeos::NetworkStateTest { ...@@ -219,8 +241,12 @@ class TetherServiceTest : public chromeos::NetworkStateTest {
std::unique_ptr<NiceMock<MockCryptAuthDeviceManager>> std::unique_ptr<NiceMock<MockCryptAuthDeviceManager>>
mock_cryptauth_device_manager_; mock_cryptauth_device_manager_;
TestInitializerDelegate* test_initializer_delegate_; TestInitializerDelegate* test_initializer_delegate_;
chromeos::tether::FakeNotificationPresenter* fake_notification_presenter_;
std::unique_ptr<cryptauth::FakeCryptAuthService> fake_cryptauth_service_; std::unique_ptr<cryptauth::FakeCryptAuthService> fake_cryptauth_service_;
scoped_refptr<device::MockBluetoothAdapter> mock_adapter_; scoped_refptr<device::MockBluetoothAdapter> mock_adapter_;
bool is_adapter_powered_;
std::unique_ptr<TestTetherService> tether_service_; std::unique_ptr<TestTetherService> tether_service_;
private: private:
...@@ -292,6 +318,7 @@ TEST_F(TetherServiceTest, TestFeatureFlagEnabled) { ...@@ -292,6 +318,7 @@ TEST_F(TetherServiceTest, TestFeatureFlagEnabled) {
TetherService* tether_service = TetherService::Get(profile_.get()); TetherService* tether_service = TetherService::Get(profile_.get());
ASSERT_TRUE(tether_service); ASSERT_TRUE(tether_service);
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
tether_service->Shutdown(); tether_service->Shutdown();
} }
...@@ -322,7 +349,7 @@ TEST_F(TetherServiceTest, TestProhibitedByPolicy) { ...@@ -322,7 +349,7 @@ TEST_F(TetherServiceTest, TestProhibitedByPolicy) {
} }
TEST_F(TetherServiceTest, TestBluetoothIsNotPowered) { TEST_F(TetherServiceTest, TestBluetoothIsNotPowered) {
ON_CALL(*mock_adapter_, IsPowered()).WillByDefault(Return(false)); is_adapter_powered_ = false;
CreateTetherService(); CreateTetherService();
...@@ -374,14 +401,14 @@ TEST_F(TetherServiceTest, TestCellularIsAvailable) { ...@@ -374,14 +401,14 @@ TEST_F(TetherServiceTest, TestCellularIsAvailable) {
SetTetherTechnologyStateEnabled(false); SetTetherTechnologyStateEnabled(false);
EXPECT_EQ( EXPECT_EQ(
chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNINITIALIZED, chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE,
network_state_handler()->GetTechnologyState( network_state_handler()->GetTechnologyState(
chromeos::NetworkTypePattern::Tether())); chromeos::NetworkTypePattern::Tether()));
EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); EXPECT_FALSE(test_initializer_delegate_->is_tether_running());
SetTetherTechnologyStateEnabled(true); SetTetherTechnologyStateEnabled(true);
EXPECT_EQ( EXPECT_EQ(
chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNINITIALIZED, chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE,
network_state_handler()->GetTechnologyState( network_state_handler()->GetTechnologyState(
chromeos::NetworkTypePattern::Tether())); chromeos::NetworkTypePattern::Tether()));
EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); EXPECT_FALSE(test_initializer_delegate_->is_tether_running());
...@@ -460,3 +487,59 @@ TEST_F(TetherServiceTest, TestEnabledMultipleChanges) { ...@@ -460,3 +487,59 @@ TEST_F(TetherServiceTest, TestEnabledMultipleChanges) {
EXPECT_EQ(updated_technology_state_count, EXPECT_EQ(updated_technology_state_count,
tether_service_->updated_technology_state_count()); tether_service_->updated_technology_state_count());
} }
TEST_F(TetherServiceTest, TestBluetoothNotification) {
is_adapter_powered_ = false;
CreateTetherService();
DisconnectDefaultShillNetworks();
// The notification should be visible since there is no active network and
// Bluetooth is disabled when the service started up.
EXPECT_TRUE(
fake_notification_presenter_->is_enable_bluetooth_notification_shown());
// Now, simulate the adapter being turned off. The notification should no
// longer be visible.
is_adapter_powered_ = true;
tether_service_->AdapterPoweredChanged(mock_adapter_.get(),
true /* powered */);
EXPECT_FALSE(
fake_notification_presenter_->is_enable_bluetooth_notification_shown());
// Now, simulate the adapter being turned back on. The notification should
// still *not* be available. It should only be shown when the service starts
// up or when the network has been disconnected.
is_adapter_powered_ = false;
tether_service_->AdapterPoweredChanged(mock_adapter_.get(),
false /* powered */);
EXPECT_FALSE(
fake_notification_presenter_->is_enable_bluetooth_notification_shown());
// Now, connect to the default Ethernet network. The notification still should
// not be shown.
SetServiceProperty(
network_state_handler()
->GetNetworkStateFromGuid(
chromeos::FakeShillManagerClient::kFakeEthernetNetworkGuid)
->path(),
shill::kStateProperty, base::Value(shill::kStateOnline));
EXPECT_FALSE(
fake_notification_presenter_->is_enable_bluetooth_notification_shown());
// Now, disconnect. The notification should be shown again.
SetServiceProperty(
network_state_handler()
->GetNetworkStateFromGuid(
chromeos::FakeShillManagerClient::kFakeEthernetNetworkGuid)
->path(),
shill::kStateProperty, base::Value(shill::kStateIdle));
EXPECT_TRUE(
fake_notification_presenter_->is_enable_bluetooth_notification_shown());
// Now, disable the Tether preference. The notification should be hidden
// again.
SetTetherTechnologyStateEnabled(false);
EXPECT_FALSE(
fake_notification_presenter_->is_enable_bluetooth_notification_shown());
}
...@@ -60,7 +60,7 @@ Initializer* Initializer::instance_ = nullptr; ...@@ -60,7 +60,7 @@ Initializer* Initializer::instance_ = nullptr;
// static // static
void Initializer::Init( void Initializer::Init(
cryptauth::CryptAuthService* cryptauth_service, cryptauth::CryptAuthService* cryptauth_service,
std::unique_ptr<NotificationPresenter> notification_presenter, NotificationPresenter* notification_presenter,
PrefService* pref_service, PrefService* pref_service,
ProfileOAuth2TokenService* token_service, ProfileOAuth2TokenService* token_service,
NetworkStateHandler* network_state_handler, NetworkStateHandler* network_state_handler,
...@@ -105,7 +105,7 @@ void Initializer::RegisterProfilePrefs(PrefRegistrySimple* registry) { ...@@ -105,7 +105,7 @@ void Initializer::RegisterProfilePrefs(PrefRegistrySimple* registry) {
Initializer::Initializer( Initializer::Initializer(
cryptauth::CryptAuthService* cryptauth_service, cryptauth::CryptAuthService* cryptauth_service,
std::unique_ptr<NotificationPresenter> notification_presenter, NotificationPresenter* notification_presenter,
PrefService* pref_service, PrefService* pref_service,
ProfileOAuth2TokenService* token_service, ProfileOAuth2TokenService* token_service,
NetworkStateHandler* network_state_handler, NetworkStateHandler* network_state_handler,
...@@ -113,7 +113,7 @@ Initializer::Initializer( ...@@ -113,7 +113,7 @@ Initializer::Initializer(
NetworkConnect* network_connect, NetworkConnect* network_connect,
NetworkConnectionHandler* network_connection_handler) NetworkConnectionHandler* network_connection_handler)
: cryptauth_service_(cryptauth_service), : cryptauth_service_(cryptauth_service),
notification_presenter_(std::move(notification_presenter)), notification_presenter_(notification_presenter),
pref_service_(pref_service), pref_service_(pref_service),
token_service_(token_service), token_service_(token_service),
network_state_handler_(network_state_handler), network_state_handler_(network_state_handler),
...@@ -220,7 +220,7 @@ void Initializer::OnBluetoothAdapterAdvertisingIntervalSet( ...@@ -220,7 +220,7 @@ void Initializer::OnBluetoothAdapterAdvertisingIntervalSet(
host_scanner_ = base::MakeUnique<HostScanner>( host_scanner_ = base::MakeUnique<HostScanner>(
tether_host_fetcher_.get(), ble_connection_manager_.get(), tether_host_fetcher_.get(), ble_connection_manager_.get(),
host_scan_device_prioritizer_.get(), tether_host_response_recorder_.get(), host_scan_device_prioritizer_.get(), tether_host_response_recorder_.get(),
notification_presenter_.get(), device_id_tether_network_guid_map_.get(), notification_presenter_, device_id_tether_network_guid_map_.get(),
master_host_scan_cache_.get(), clock_.get()); master_host_scan_cache_.get(), clock_.get());
host_scan_scheduler_ = base::MakeUnique<HostScanScheduler>( host_scan_scheduler_ = base::MakeUnique<HostScanScheduler>(
network_state_handler_, host_scanner_.get()); network_state_handler_, host_scanner_.get());
...@@ -231,7 +231,7 @@ void Initializer::OnBluetoothAdapterAdvertisingIntervalSet( ...@@ -231,7 +231,7 @@ void Initializer::OnBluetoothAdapterAdvertisingIntervalSet(
tether_host_fetcher_.get(), ble_connection_manager_.get(), tether_host_fetcher_.get(), ble_connection_manager_.get(),
tether_host_response_recorder_.get(), tether_host_response_recorder_.get(),
device_id_tether_network_guid_map_.get(), master_host_scan_cache_.get(), device_id_tether_network_guid_map_.get(), master_host_scan_cache_.get(),
notification_presenter_.get(), host_connection_metrics_logger_.get()); notification_presenter_, host_connection_metrics_logger_.get());
network_configuration_remover_ = network_configuration_remover_ =
base::MakeUnique<NetworkConfigurationRemover>( base::MakeUnique<NetworkConfigurationRemover>(
network_state_handler_, managed_network_configuration_handler_); network_state_handler_, managed_network_configuration_handler_);
......
...@@ -64,7 +64,7 @@ class Initializer : public OAuth2TokenService::Observer { ...@@ -64,7 +64,7 @@ class Initializer : public OAuth2TokenService::Observer {
// initialized, this function is a no-op. // initialized, this function is a no-op.
static void Init( static void Init(
cryptauth::CryptAuthService* cryptauth_service, cryptauth::CryptAuthService* cryptauth_service,
std::unique_ptr<NotificationPresenter> notification_presenter, NotificationPresenter* notification_presenter,
PrefService* pref_service, PrefService* pref_service,
ProfileOAuth2TokenService* token_service, ProfileOAuth2TokenService* token_service,
NetworkStateHandler* network_state_handler, NetworkStateHandler* network_state_handler,
...@@ -85,7 +85,7 @@ class Initializer : public OAuth2TokenService::Observer { ...@@ -85,7 +85,7 @@ class Initializer : public OAuth2TokenService::Observer {
Initializer( Initializer(
cryptauth::CryptAuthService* cryptauth_service, cryptauth::CryptAuthService* cryptauth_service,
std::unique_ptr<NotificationPresenter> notification_presenter, NotificationPresenter* notification_presenter,
PrefService* pref_service, PrefService* pref_service,
ProfileOAuth2TokenService* token_service, ProfileOAuth2TokenService* token_service,
NetworkStateHandler* network_state_handler, NetworkStateHandler* network_state_handler,
...@@ -107,7 +107,7 @@ class Initializer : public OAuth2TokenService::Observer { ...@@ -107,7 +107,7 @@ class Initializer : public OAuth2TokenService::Observer {
void OnPreCrashStateRestored(); void OnPreCrashStateRestored();
cryptauth::CryptAuthService* cryptauth_service_; cryptauth::CryptAuthService* cryptauth_service_;
std::unique_ptr<NotificationPresenter> notification_presenter_; NotificationPresenter* notification_presenter_;
PrefService* pref_service_; PrefService* pref_service_;
ProfileOAuth2TokenService* token_service_; ProfileOAuth2TokenService* token_service_;
NetworkStateHandler* network_state_handler_; NetworkStateHandler* network_state_handler_;
......
...@@ -140,7 +140,7 @@ class InitializerTest : public NetworkStateTest { ...@@ -140,7 +140,7 @@ class InitializerTest : public NetworkStateTest {
void InitializeAndDestroy( void InitializeAndDestroy(
cryptauth::CryptAuthService* cryptauth_service, cryptauth::CryptAuthService* cryptauth_service,
std::unique_ptr<NotificationPresenter> notification_presenter, NotificationPresenter* notification_presenter,
PrefService* pref_service, PrefService* pref_service,
ProfileOAuth2TokenService* token_service, ProfileOAuth2TokenService* token_service,
NetworkStateHandler* network_state_handler, NetworkStateHandler* network_state_handler,
...@@ -148,11 +148,10 @@ class InitializerTest : public NetworkStateTest { ...@@ -148,11 +148,10 @@ class InitializerTest : public NetworkStateTest {
NetworkConnect* network_connect, NetworkConnect* network_connect,
NetworkConnectionHandler* network_connection_handler, NetworkConnectionHandler* network_connection_handler,
scoped_refptr<device::BluetoothAdapter> adapter) { scoped_refptr<device::BluetoothAdapter> adapter) {
Initializer* initializer = Initializer* initializer = new Initializer(
new Initializer(cryptauth_service, std::move(notification_presenter), cryptauth_service, notification_presenter, pref_service, token_service,
pref_service, token_service, network_state_handler, network_state_handler, managed_network_configuration_handler,
managed_network_configuration_handler, network_connect, network_connect, network_connection_handler);
network_connection_handler);
initializer->OnBluetoothAdapterAdvertisingIntervalSet(adapter); initializer->OnBluetoothAdapterAdvertisingIntervalSet(adapter);
delete initializer; delete initializer;
} }
...@@ -189,6 +188,9 @@ TEST_F(InitializerTest, TestCreateAndDestroy) { ...@@ -189,6 +188,9 @@ TEST_F(InitializerTest, TestCreateAndDestroy) {
fake_cryptauth_service->set_cryptauth_enrollment_manager( fake_cryptauth_service->set_cryptauth_enrollment_manager(
mock_enrollment_manager.get()); mock_enrollment_manager.get());
std::unique_ptr<FakeNotificationPresenter> fake_notification_presenter =
base::MakeUnique<FakeNotificationPresenter>();
std::unique_ptr<TestingPrefServiceSimple> test_pref_service = std::unique_ptr<TestingPrefServiceSimple> test_pref_service =
base::MakeUnique<TestingPrefServiceSimple>(); base::MakeUnique<TestingPrefServiceSimple>();
...@@ -212,11 +214,11 @@ TEST_F(InitializerTest, TestCreateAndDestroy) { ...@@ -212,11 +214,11 @@ TEST_F(InitializerTest, TestCreateAndDestroy) {
// here because the friend relationship between Initializer and // here because the friend relationship between Initializer and
// InitializerTest only applies to the class itself, not these test functions. // InitializerTest only applies to the class itself, not these test functions.
InitializeAndDestroy( InitializeAndDestroy(
fake_cryptauth_service.get(), fake_cryptauth_service.get(), fake_notification_presenter.get(),
base::MakeUnique<FakeNotificationPresenter>(), test_pref_service_.get(), test_pref_service_.get(), fake_token_service.get(),
fake_token_service.get(), network_state_handler(), network_state_handler(), managed_network_configuration_handler.get(),
managed_network_configuration_handler.get(), mock_network_connect.get(), mock_network_connect.get(), network_connection_handler_.get(),
network_connection_handler_.get(), mock_adapter); mock_adapter);
} }
} // namespace tether } // namespace tether
......
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