network_detailed_view_controller.cc 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. // Copyright 2022 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. #include "ash/system/network/network_detailed_view_controller.h"
  5. #include "ash/constants/ash_features.h"
  6. #include "ash/public/cpp/system_tray_client.h"
  7. #include "ash/session/session_controller_impl.h"
  8. #include "ash/shell.h"
  9. #include "ash/strings/grit/ash_strings.h"
  10. #include "ash/system/machine_learning/user_settings_event_logger.h"
  11. #include "ash/system/model/system_tray_model.h"
  12. #include "ash/system/network/network_detailed_network_view.h"
  13. #include "ash/system/network/network_list_view_controller.h"
  14. #include "ash/system/network/network_utils.h"
  15. #include "ash/system/network/tray_network_state_model.h"
  16. #include "ash/system/tray/detailed_view_delegate.h"
  17. #include "base/metrics/user_metrics.h"
  18. #include "chromeos/ash/components/network/network_connect.h"
  19. #include "chromeos/services/network_config/public/cpp/cros_network_config_util.h"
  20. #include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h"
  21. #include "ui/base/l10n/l10n_util.h"
  22. #include "ui/views/view.h"
  23. namespace ash {
  24. namespace {
  25. using base::UserMetricsAction;
  26. using chromeos::network_config::NetworkTypeMatchesType;
  27. using chromeos::network_config::mojom::ActivationStateType;
  28. using chromeos::network_config::mojom::CellularStateProperties;
  29. using chromeos::network_config::mojom::ConnectionStateType;
  30. using chromeos::network_config::mojom::DeviceStateProperties;
  31. using chromeos::network_config::mojom::DeviceStateType;
  32. using chromeos::network_config::mojom::NetworkStateProperties;
  33. using chromeos::network_config::mojom::NetworkStatePropertiesPtr;
  34. using chromeos::network_config::mojom::NetworkType;
  35. using chromeos::bluetooth_config::mojom::BluetoothSystemPropertiesPtr;
  36. using chromeos::bluetooth_config::mojom::BluetoothSystemState;
  37. void LogUserNetworkEvent(const NetworkStateProperties& network) {
  38. auto* const logger = ml::UserSettingsEventLogger::Get();
  39. if (logger) {
  40. logger->LogNetworkUkmEvent(network);
  41. }
  42. }
  43. bool IsSecondaryUser() {
  44. SessionControllerImpl* session_controller =
  45. Shell::Get()->session_controller();
  46. return session_controller->IsActiveUserSessionStarted() &&
  47. !session_controller->IsUserPrimary();
  48. }
  49. bool NetworkTypeIsConfigurable(NetworkType type) {
  50. switch (type) {
  51. case NetworkType::kVPN:
  52. case NetworkType::kWiFi:
  53. return true;
  54. case NetworkType::kAll:
  55. case NetworkType::kCellular:
  56. case NetworkType::kEthernet:
  57. case NetworkType::kMobile:
  58. case NetworkType::kTether:
  59. case NetworkType::kWireless:
  60. return false;
  61. }
  62. NOTREACHED();
  63. return false;
  64. }
  65. bool IsNetworkConnectable(const NetworkStatePropertiesPtr& network_properties) {
  66. // The network must not already be connected to be able to be connected to.
  67. if (network_properties->connection_state !=
  68. ConnectionStateType::kNotConnected) {
  69. return false;
  70. }
  71. if (NetworkTypeMatchesType(network_properties->type,
  72. NetworkType::kCellular)) {
  73. // Cellular networks must be activated, uninhibited, and have an unlocked
  74. // SIM to be able to be connected to.
  75. const CellularStateProperties* cellular =
  76. network_properties->type_state->get_cellular().get();
  77. if (cellular->activation_state == ActivationStateType::kNotActivated &&
  78. !cellular->eid.empty()) {
  79. return false;
  80. }
  81. if (cellular->activation_state == ActivationStateType::kActivated) {
  82. return true;
  83. }
  84. }
  85. // The network can be connected to if the network is connectable.
  86. if (network_properties->connectable) {
  87. return true;
  88. }
  89. // Network can be connected to if the active user is the primary user and the
  90. // network is configurable.
  91. if (!IsSecondaryUser() &&
  92. NetworkTypeIsConfigurable(network_properties->type)) {
  93. return true;
  94. }
  95. return false;
  96. }
  97. bool IsCellularSimLocked() {
  98. const DeviceStateProperties* cellular_device =
  99. Shell::Get()->system_tray_model()->network_state_model()->GetDevice(
  100. NetworkType::kCellular);
  101. return cellular_device &&
  102. !cellular_device->sim_lock_status->lock_type.empty();
  103. }
  104. } // namespace
  105. NetworkDetailedViewController::NetworkDetailedViewController(
  106. UnifiedSystemTrayController* tray_controller)
  107. : model_(Shell::Get()->system_tray_model()->network_state_model()),
  108. detailed_view_delegate_(
  109. std::make_unique<DetailedViewDelegate>(tray_controller)) {
  110. DCHECK(ash::features::IsQuickSettingsNetworkRevampEnabled());
  111. DCHECK(ash::features::IsBluetoothRevampEnabled());
  112. GetBluetoothConfigService(
  113. remote_cros_bluetooth_config_.BindNewPipeAndPassReceiver());
  114. remote_cros_bluetooth_config_->ObserveSystemProperties(
  115. cros_system_properties_observer_receiver_.BindNewPipeAndPassRemote());
  116. }
  117. NetworkDetailedViewController::~NetworkDetailedViewController() = default;
  118. views::View* NetworkDetailedViewController::CreateView() {
  119. DCHECK(!network_detailed_view_);
  120. std::unique_ptr<NetworkDetailedNetworkView> view =
  121. NetworkDetailedNetworkView::Factory::Create(detailed_view_delegate_.get(),
  122. /*delegate=*/this);
  123. network_detailed_view_ = view.get();
  124. network_list_view_controller_ =
  125. NetworkListViewController::Factory::Create(view.get());
  126. // We are expected to return an unowned pointer that the caller is responsible
  127. // for deleting.
  128. return view.release()->GetAsView();
  129. }
  130. std::u16string NetworkDetailedViewController::GetAccessibleName() const {
  131. return l10n_util::GetStringUTF16(
  132. IDS_ASH_QUICK_SETTINGS_BUBBLE_NETWORK_SETTINGS_ACCESSIBLE_DESCRIPTION);
  133. }
  134. void NetworkDetailedViewController::OnNetworkListItemSelected(
  135. const NetworkStatePropertiesPtr& network) {
  136. if (Shell::Get()->session_controller()->login_status() == LoginStatus::LOCKED)
  137. return;
  138. if (network) {
  139. // If the network is locked and is cellular show SIM unlock dialog in OS
  140. // Settings.
  141. if (network->type == NetworkType::kCellular &&
  142. network->type_state->get_cellular()->sim_locked) {
  143. if (!Shell::Get()->session_controller()->ShouldEnableSettings()) {
  144. return;
  145. }
  146. RecordNetworkRowClickedAction(
  147. NetworkRowClickedAction::kOpenSimUnlockDialog);
  148. Shell::Get()->system_tray_model()->client()->ShowSettingsSimUnlock();
  149. return;
  150. }
  151. if (IsNetworkConnectable(network)) {
  152. base::RecordAction(
  153. UserMetricsAction("StatusArea_Network_ConnectConfigured"));
  154. LogUserNetworkEvent(*network.get());
  155. RecordNetworkRowClickedAction(NetworkRowClickedAction::kConnectToNetwork);
  156. NetworkConnect::Get()->ConnectToNetworkId(network->guid);
  157. return;
  158. }
  159. }
  160. // If the network is no longer available or not connectable or configurable,
  161. // show the Settings UI.
  162. base::RecordAction(UserMetricsAction("StatusArea_Network_ConnectionDetails"));
  163. RecordNetworkRowClickedAction(
  164. NetworkRowClickedAction::kOpenNetworkSettingsPage);
  165. Shell::Get()->system_tray_model()->client()->ShowNetworkSettings(
  166. network ? network->guid : std::string());
  167. }
  168. void NetworkDetailedViewController::OnMobileToggleClicked(bool new_state) {
  169. RecordNetworkTypeToggled(NetworkType::kMobile, new_state);
  170. const DeviceStateType cellular_state =
  171. model_->GetDeviceState(NetworkType::kCellular);
  172. // When Cellular is available, the toggle controls Cellular enabled state.
  173. if (cellular_state != DeviceStateType::kUnavailable) {
  174. if (new_state && IsCellularSimLocked()) {
  175. Shell::Get()->system_tray_model()->client()->ShowSettingsSimUnlock();
  176. return;
  177. }
  178. model_->SetNetworkTypeEnabledState(NetworkType::kCellular, new_state);
  179. return;
  180. }
  181. const DeviceStateType tether_state =
  182. model_->GetDeviceState(NetworkType::kTether);
  183. DCHECK(tether_state != DeviceStateType::kUnavailable);
  184. // If Tether is available but uninitialized, we expect Bluetooth to be off.
  185. // Enable Bluetooth so that Tether will be initialized.
  186. if (tether_state == DeviceStateType::kUninitialized) {
  187. if (new_state &&
  188. (bluetooth_system_state_ == BluetoothSystemState::kDisabled ||
  189. bluetooth_system_state_ == BluetoothSystemState::kDisabling)) {
  190. remote_cros_bluetooth_config_->SetBluetoothEnabledState(true);
  191. waiting_to_initialize_bluetooth_ = true;
  192. }
  193. return;
  194. }
  195. // Otherwise the toggle controls the Tether enabled state.
  196. model_->SetNetworkTypeEnabledState(NetworkType::kTether, new_state);
  197. }
  198. void NetworkDetailedViewController::OnWifiToggleClicked(bool new_state) {
  199. RecordNetworkTypeToggled(NetworkType::kWiFi, new_state);
  200. model_->SetNetworkTypeEnabledState(NetworkType::kWiFi, new_state);
  201. }
  202. void NetworkDetailedViewController::OnPropertiesUpdated(
  203. BluetoothSystemPropertiesPtr properties) {
  204. bluetooth_system_state_ = properties->system_state;
  205. // We enabled Bluetooth so Tether is now initialized, but it was not
  206. // enabled so enable it.
  207. if (waiting_to_initialize_bluetooth_ &&
  208. bluetooth_system_state_ == BluetoothSystemState::kEnabled) {
  209. waiting_to_initialize_bluetooth_ = false;
  210. model_->SetNetworkTypeEnabledState(NetworkType::kTether,
  211. /*enabled=*/true);
  212. }
  213. }
  214. } // namespace ash