1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
|
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMEOS_ASH_COMPONENTS_PHONEHUB_TETHER_CONTROLLER_IMPL_H_
#define CHROMEOS_ASH_COMPONENTS_PHONEHUB_TETHER_CONTROLLER_IMPL_H_
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chromeos/ash/components/phonehub/phone_model.h"
#include "chromeos/ash/components/phonehub/tether_controller.h"
#include "chromeos/ash/services/multidevice_setup/public/cpp/multidevice_setup_client.h"
#include "chromeos/services/network_config/public/cpp/cros_network_config_observer.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
namespace ash::phonehub {
class UserActionRecorder;
// TetherController implementation which utilizes MultiDeviceSetupClient and
// CrosNetworkConfig in order to interact with Instant Tethering. If Instant
// Tethering is user disabled, AttemptConnection() will first enable the feature
// via the MultiDeviceSetupClient, then scan for an eligible phone via
// CrosNetworkConfig, and finally connect to the phone via CrosNetworkConfig. If
// Instant Tethering is enabled, but there is no visible Tether network,
// AttemptConnection() will first scan for an eligible phone via
// CrosNetworkConfig, and connect to the phone via CrosNetworkConfig. If Instant
// Tethering is enabled and there is a visible Tether Network previously fetched
// from observing CrosNetworkConfig, AttemptConnection() will just connect to
// the phone via CrosNetworkConfig. Disconnect() disconnects the Tether network
// if one exists.
class TetherControllerImpl
: public TetherController,
public PhoneModel::Observer,
public multidevice_setup::MultiDeviceSetupClient::Observer,
public chromeos::network_config::CrosNetworkConfigObserver {
public:
TetherControllerImpl(
PhoneModel* phone_model,
UserActionRecorder* user_action_recorder,
multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client);
~TetherControllerImpl() override;
// TetherController:
Status GetStatus() const override;
void ScanForAvailableConnection() override;
void AttemptConnection() override;
void Disconnect() override;
private:
friend class TetherControllerImplTest;
// Used to track AttemptConnection() and Disconnect() calls.
enum class ConnectDisconnectStatus {
// No AttemptConnection or Disconnect is in progress. The class still
// observes changes in the Tether network initiated externally (e.g in OS
// Settings), and causes changes to the |status_|.
kIdle = 0,
// Used in AttemptConnection flow. Enabling the InstantTethering feature as
// it was previously disabled.
kTurningOnInstantTethering = 1,
// Used in AttemptConnection flow. Requesting a scan has has no callback, so
// this state is changed upon observing tether network changes or device
// changes. If a visible Tether network is observed, the
// |connect_disconnect_status_| will change to kConnectingToEligiblePhone.
// If a visible Tether network is not observed by the time the Tether device
// stops scanning, the |connect_disconnect_status_| will change back to
// kIdle.
// Note: Calling ScanForAvailableConnection() will not set the
// |connect_disconnect_status_| to this value.
kScanningForEligiblePhone = 2,
// Used in AttemptConnection flow. In the process of connecting to a Tether
// Network.
kConnectingToEligiblePhone = 3,
// Used in Disconnect flow. Disconnects from the tether network.
kDisconnecting = 4,
};
// Connector that uses CrosNetworkConfig to connect, disconnect, and get the
// network state list. This class is used for testing purposes.
class TetherNetworkConnector {
public:
using StartConnectCallback = base::OnceCallback<void(
chromeos::network_config::mojom::StartConnectResult result,
const std::string& message)>;
using StartDisconnectCallback = base::OnceCallback<void(bool)>;
using GetNetworkStateListCallback = base::OnceCallback<void(
std::vector<
chromeos::network_config::mojom::NetworkStatePropertiesPtr>)>;
TetherNetworkConnector();
TetherNetworkConnector(const TetherNetworkConnector&) = delete;
TetherNetworkConnector& operator=(const TetherNetworkConnector&) = delete;
virtual ~TetherNetworkConnector();
virtual void StartConnect(const std::string& guid,
StartConnectCallback callback);
virtual void StartDisconnect(const std::string& guid,
StartDisconnectCallback callback);
virtual void GetNetworkStateList(
chromeos::network_config::mojom::NetworkFilterPtr filter,
GetNetworkStateListCallback callback);
private:
mojo::Remote<chromeos::network_config::mojom::CrosNetworkConfig>
cros_network_config_;
};
// Two parameter constructor made available for testing purposes. The one
// parameter constructor calls this constructor.
TetherControllerImpl(
PhoneModel* phone_model,
UserActionRecorder* user_action_recorder,
multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client,
std::unique_ptr<TetherControllerImpl::TetherNetworkConnector> connector);
// PhoneModel::Observer:
void OnModelChanged() override;
// multidevice_setup::MultiDeviceSetupClient::Observer:
void OnFeatureStatesChanged(
const multidevice_setup::MultiDeviceSetupClient::FeatureStatesMap&
feature_states_map) override;
// CrosNetworkConfigObserver:
void OnActiveNetworksChanged(
std::vector<chromeos::network_config::mojom::NetworkStatePropertiesPtr>
networks) override;
void OnNetworkStateListChanged() override;
void OnDeviceStateListChanged() override;
void AttemptTurningOnTethering();
void OnSetFeatureEnabled(bool success);
void PerformConnectionAttempt();
void StartConnect();
void OnStartConnectCompleted(
chromeos::network_config::mojom::StartConnectResult result,
const std::string& message);
void OnDisconnectCompleted(bool success);
void FetchVisibleTetherNetwork();
void OnGetDeviceStateList(
std::vector<chromeos::network_config::mojom::DeviceStatePropertiesPtr>
devices);
void OnVisibleTetherNetworkFetched(
std::vector<chromeos::network_config::mojom::NetworkStatePropertiesPtr>
networks);
void SetConnectDisconnectStatus(
ConnectDisconnectStatus connect_disconnect_status);
void UpdateStatus();
TetherController::Status ComputeStatus() const;
raw_ptr<PhoneModel> phone_model_;
raw_ptr<UserActionRecorder> user_action_recorder_;
raw_ptr<multidevice_setup::MultiDeviceSetupClient> multidevice_setup_client_;
ConnectDisconnectStatus connect_disconnect_status_ =
ConnectDisconnectStatus::kIdle;
Status status_ = Status::kIneligibleForFeature;
// Whether this class is attempting a tether connection.
bool is_attempting_connection_ = false;
chromeos::network_config::mojom::NetworkStatePropertiesPtr tether_network_;
std::unique_ptr<TetherNetworkConnector> connector_;
mojo::Receiver<chromeos::network_config::mojom::CrosNetworkConfigObserver>
receiver_{this};
mojo::Remote<chromeos::network_config::mojom::CrosNetworkConfig>
cros_network_config_;
base::WeakPtrFactory<TetherControllerImpl> weak_ptr_factory_{this};
};
} // namespace ash::phonehub
#endif // CHROMEOS_ASH_COMPONENTS_PHONEHUB_TETHER_CONTROLLER_IMPL_H_
|