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