blob: 75b89c4e3a2819ea4d9c6f16ec625346e2ce1888 [file] [log] [blame]
// Copyright 2016 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 "chromeos/components/tether/initializer.h"
#include "base/bind.h"
#include "chromeos/components/tether/active_host.h"
#include "chromeos/components/tether/active_host_network_state_updater.h"
#include "chromeos/components/tether/ble_connection_manager.h"
#include "chromeos/components/tether/device_id_tether_network_guid_map.h"
#include "chromeos/components/tether/host_scan_cache.h"
#include "chromeos/components/tether/host_scan_device_prioritizer_impl.h"
#include "chromeos/components/tether/host_scan_scheduler.h"
#include "chromeos/components/tether/host_scanner.h"
#include "chromeos/components/tether/keep_alive_scheduler.h"
#include "chromeos/components/tether/network_configuration_remover.h"
#include "chromeos/components/tether/network_connection_handler_tether_delegate.h"
#include "chromeos/components/tether/notification_presenter.h"
#include "chromeos/components/tether/tether_connector.h"
#include "chromeos/components/tether/tether_disconnector_impl.h"
#include "chromeos/components/tether/tether_host_fetcher.h"
#include "chromeos/components/tether/tether_host_response_recorder.h"
#include "chromeos/components/tether/tether_network_disconnection_handler.h"
#include "chromeos/components/tether/wifi_hotspot_connector.h"
#include "chromeos/network/managed_network_configuration_handler.h"
#include "chromeos/network/network_connect.h"
#include "chromeos/network/network_connection_handler.h"
#include "chromeos/network/network_state_handler.h"
#include "components/cryptauth/bluetooth_throttler_impl.h"
#include "components/cryptauth/cryptauth_service.h"
#include "components/cryptauth/local_device_data_provider.h"
#include "components/cryptauth/remote_beacon_seed_fetcher.h"
#include "components/prefs/pref_service.h"
#include "components/proximity_auth/logging/logging.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
namespace chromeos {
namespace tether {
namespace {
// TODO (hansberry): Experiment with intervals to determine ideal advertising
// interval parameters.
constexpr int64_t kMinAdvertisingIntervalMilliseconds = 100;
constexpr int64_t kMaxAdvertisingIntervalMilliseconds = 100;
} // namespace
// static
Initializer* Initializer::instance_ = nullptr;
// static
void Initializer::Init(
cryptauth::CryptAuthService* cryptauth_service,
std::unique_ptr<NotificationPresenter> notification_presenter,
PrefService* pref_service,
ProfileOAuth2TokenService* token_service,
NetworkStateHandler* network_state_handler,
ManagedNetworkConfigurationHandler* managed_network_configuration_handler,
NetworkConnect* network_connect,
NetworkConnectionHandler* network_connection_handler) {
if (!device::BluetoothAdapterFactory::IsBluetoothSupported()) {
PA_LOG(WARNING) << "Bluetooth is not supported on this device; cannot "
<< "initialize Tether feature.";
return;
}
if (instance_) {
// The Tether feature has already been initialized. No need to do anything.
return;
}
PA_LOG(INFO) << "Initializing Tether feature.";
instance_ =
new Initializer(cryptauth_service, std::move(notification_presenter),
pref_service, token_service, network_state_handler,
managed_network_configuration_handler, network_connect,
network_connection_handler);
}
// static
void Initializer::Shutdown() {
if (instance_) {
PA_LOG(INFO) << "Shutting down Tether feature.";
delete instance_;
instance_ = nullptr;
}
}
// static
void Initializer::RegisterProfilePrefs(PrefRegistrySimple* registry) {
ActiveHost::RegisterPrefs(registry);
TetherHostResponseRecorder::RegisterPrefs(registry);
TetherDisconnectorImpl::RegisterPrefs(registry);
}
Initializer::Initializer(
cryptauth::CryptAuthService* cryptauth_service,
std::unique_ptr<NotificationPresenter> notification_presenter,
PrefService* pref_service,
ProfileOAuth2TokenService* token_service,
NetworkStateHandler* network_state_handler,
ManagedNetworkConfigurationHandler* managed_network_configuration_handler,
NetworkConnect* network_connect,
NetworkConnectionHandler* network_connection_handler)
: cryptauth_service_(cryptauth_service),
notification_presenter_(std::move(notification_presenter)),
pref_service_(pref_service),
token_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),
weak_ptr_factory_(this) {
if (!token_service_->RefreshTokenIsAvailable(
cryptauth_service_->GetAccountId())) {
PA_LOG(INFO) << "Refresh token not yet available; "
<< "waiting for valid token to initializing tether feature.";
token_service_->AddObserver(this);
return;
}
PA_LOG(INFO) << "Refresh token is available; initializing tether feature.";
FetchBluetoothAdapter();
}
Initializer::~Initializer() {
token_service_->RemoveObserver(this);
network_state_handler_->set_tether_sort_delegate(nullptr);
}
void Initializer::FetchBluetoothAdapter() {
device::BluetoothAdapterFactory::GetAdapter(base::Bind(
&Initializer::OnBluetoothAdapterFetched, weak_ptr_factory_.GetWeakPtr()));
}
void Initializer::OnRefreshTokensLoaded() {
if (!token_service_->RefreshTokenIsAvailable(
cryptauth_service_->GetAccountId())) {
// If a token for the active account is still not available, continue
// waiting for a new token.
return;
}
PA_LOG(INFO) << "Refresh token has loaded; initializing tether feature.";
token_service_->RemoveObserver(this);
FetchBluetoothAdapter();
}
void Initializer::OnBluetoothAdapterFetched(
scoped_refptr<device::BluetoothAdapter> adapter) {
PA_LOG(INFO) << "Successfully fetched Bluetooth adapter. Setting advertising "
<< "interval.";
adapter->SetAdvertisingInterval(
base::TimeDelta::FromMilliseconds(kMinAdvertisingIntervalMilliseconds),
base::TimeDelta::FromMilliseconds(kMaxAdvertisingIntervalMilliseconds),
base::Bind(&Initializer::OnBluetoothAdapterAdvertisingIntervalSet,
weak_ptr_factory_.GetWeakPtr(), adapter),
base::Bind(&Initializer::OnBluetoothAdapterAdvertisingIntervalError,
weak_ptr_factory_.GetWeakPtr()));
}
void Initializer::OnBluetoothAdapterAdvertisingIntervalSet(
scoped_refptr<device::BluetoothAdapter> adapter) {
PA_LOG(INFO) << "Successfully set Bluetooth advertisement interval. "
<< "Initializing tether feature.";
tether_host_fetcher_ =
base::MakeUnique<TetherHostFetcher>(cryptauth_service_);
local_device_data_provider_ =
base::MakeUnique<cryptauth::LocalDeviceDataProvider>(cryptauth_service_);
remote_beacon_seed_fetcher_ =
base::MakeUnique<cryptauth::RemoteBeaconSeedFetcher>(
cryptauth_service_->GetCryptAuthDeviceManager());
ble_connection_manager_ = base::MakeUnique<BleConnectionManager>(
cryptauth_service_, adapter, local_device_data_provider_.get(),
remote_beacon_seed_fetcher_.get(),
cryptauth::BluetoothThrottlerImpl::GetInstance());
tether_host_response_recorder_ =
base::MakeUnique<TetherHostResponseRecorder>(pref_service_);
device_id_tether_network_guid_map_ =
base::MakeUnique<DeviceIdTetherNetworkGuidMap>();
host_scan_device_prioritizer_ =
base::MakeUnique<HostScanDevicePrioritizerImpl>(
tether_host_response_recorder_.get(),
device_id_tether_network_guid_map_.get());
network_state_handler_->set_tether_sort_delegate(
host_scan_device_prioritizer_.get());
wifi_hotspot_connector_ = base::MakeUnique<WifiHotspotConnector>(
network_state_handler_, network_connect_);
active_host_ =
base::MakeUnique<ActiveHost>(tether_host_fetcher_.get(), pref_service_);
active_host_network_state_updater_ =
base::MakeUnique<ActiveHostNetworkStateUpdater>(active_host_.get(),
network_state_handler_);
host_scan_cache_ = base::MakeUnique<HostScanCache>(
network_state_handler_, active_host_.get(),
tether_host_response_recorder_.get(),
device_id_tether_network_guid_map_.get());
keep_alive_scheduler_ = base::MakeUnique<KeepAliveScheduler>(
active_host_.get(), ble_connection_manager_.get(), host_scan_cache_.get(),
device_id_tether_network_guid_map_.get());
clock_ = base::MakeUnique<base::DefaultClock>();
host_scanner_ = base::MakeUnique<HostScanner>(
tether_host_fetcher_.get(), ble_connection_manager_.get(),
host_scan_device_prioritizer_.get(), tether_host_response_recorder_.get(),
notification_presenter_.get(), device_id_tether_network_guid_map_.get(),
host_scan_cache_.get(), clock_.get());
host_scan_scheduler_ = base::MakeUnique<HostScanScheduler>(
network_state_handler_, host_scanner_.get());
tether_connector_ = base::MakeUnique<TetherConnector>(
network_state_handler_, wifi_hotspot_connector_.get(), active_host_.get(),
tether_host_fetcher_.get(), ble_connection_manager_.get(),
tether_host_response_recorder_.get(),
device_id_tether_network_guid_map_.get(), host_scan_cache_.get(),
notification_presenter_.get());
network_configuration_remover_ =
base::MakeUnique<NetworkConfigurationRemover>(
network_state_handler_, managed_network_configuration_handler_);
tether_disconnector_ = base::MakeUnique<TetherDisconnectorImpl>(
network_connection_handler_, network_state_handler_, active_host_.get(),
ble_connection_manager_.get(), network_configuration_remover_.get(),
tether_connector_.get(), device_id_tether_network_guid_map_.get(),
tether_host_fetcher_.get(), pref_service_);
tether_network_disconnection_handler_ =
base::MakeUnique<TetherNetworkDisconnectionHandler>(
active_host_.get(), network_state_handler_,
network_configuration_remover_.get());
network_connection_handler_tether_delegate_ =
base::MakeUnique<NetworkConnectionHandlerTetherDelegate>(
network_connection_handler_, tether_connector_.get(),
tether_disconnector_.get());
// Because Initializer is created on each user log in, it's appropriate to
// call this method now.
host_scan_scheduler_->UserLoggedIn();
}
void Initializer::OnBluetoothAdapterAdvertisingIntervalError(
device::BluetoothAdvertisement::ErrorCode status) {
PA_LOG(ERROR) << "Failed to set Bluetooth advertisement interval; "
<< "cannot use tether feature. Error code: " << status;
}
} // namespace tether
} // namespace chromeos