Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / webui / chromeos / choose_mobile_network_ui.cc
blob3db332eb49f556f9a8235be1bff539b6a5a96eea
1 // Copyright (c) 2012 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.
5 #include "chrome/browser/ui/webui/chromeos/choose_mobile_network_ui.h"
7 #include <set>
8 #include <string>
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/location.h"
13 #include "base/logging.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_piece.h"
16 #include "base/values.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/common/url_constants.h"
19 #include "chrome/grit/generated_resources.h"
20 #include "chromeos/network/device_state.h"
21 #include "chromeos/network/network_device_handler.h"
22 #include "chromeos/network/network_event_log.h"
23 #include "chromeos/network/network_state_handler.h"
24 #include "chromeos/network/network_state_handler_observer.h"
25 #include "content/public/browser/web_contents.h"
26 #include "content/public/browser/web_ui.h"
27 #include "content/public/browser/web_ui_data_source.h"
28 #include "content/public/browser/web_ui_message_handler.h"
29 #include "grit/browser_resources.h"
30 #include "third_party/cros_system_api/dbus/service_constants.h"
32 using content::WebContents;
33 using content::WebUIMessageHandler;
35 namespace chromeos {
37 namespace {
39 // JS API callbacks names.
40 const char kJsApiCancel[] = "cancel";
41 const char kJsApiConnect[] = "connect";
42 const char kJsApiPageReady[] = "pageReady";
44 // Page JS API function names.
45 const char kJsApiShowNetworks[] = "mobile.ChooseNetwork.showNetworks";
46 const char kJsApiShowScanning[] = "mobile.ChooseNetwork.showScanning";
48 // Network properties.
49 const char kNetworkIdProperty[] = "networkId";
50 const char kOperatorNameProperty[] = "operatorName";
51 const char kStatusProperty[] = "status";
52 const char kTechnologyProperty[] = "technology";
54 content::WebUIDataSource* CreateChooseMobileNetworkUIHTMLSource() {
55 content::WebUIDataSource* source = content::WebUIDataSource::Create(
56 chrome::kChromeUIChooseMobileNetworkHost);
58 source->AddLocalizedString("chooseNetworkTitle",
59 IDS_NETWORK_CHOOSE_MOBILE_NETWORK);
60 source->AddLocalizedString("scanningMsgLine1",
61 IDS_NETWORK_SCANNING_FOR_MOBILE_NETWORKS);
62 source->AddLocalizedString("scanningMsgLine2",
63 IDS_NETWORK_SCANNING_THIS_MAY_TAKE_A_MINUTE);
64 source->AddLocalizedString("noMobileNetworks",
65 IDS_NETWORK_NO_MOBILE_NETWORKS);
66 source->AddLocalizedString("connect", IDS_OPTIONS_SETTINGS_CONNECT);
67 source->AddLocalizedString("cancel", IDS_CANCEL);
69 source->SetJsonPath("strings.js");
70 source->AddResourcePath("choose_mobile_network.js",
71 IDR_CHOOSE_MOBILE_NETWORK_JS);
72 source->SetDefaultResource(IDR_CHOOSE_MOBILE_NETWORK_HTML);
73 return source;
76 chromeos::NetworkDeviceHandler* GetNetworkDeviceHandler() {
77 return chromeos::NetworkHandler::Get()->network_device_handler();
80 chromeos::NetworkStateHandler* GetNetworkStateHandler() {
81 return chromeos::NetworkHandler::Get()->network_state_handler();
84 void NetworkOperationErrorCallback(
85 const std::string& operation_name,
86 const std::string& error_name,
87 scoped_ptr<base::DictionaryValue> error_data) {
88 NET_LOG_ERROR("Operation failed: " + error_name, operation_name);
91 class ChooseMobileNetworkHandler
92 : public WebUIMessageHandler,
93 public NetworkStateHandlerObserver {
94 public:
95 ChooseMobileNetworkHandler();
96 ~ChooseMobileNetworkHandler() override;
98 // WebUIMessageHandler implementation.
99 void RegisterMessages() override;
101 // NetworkStateHandlerObserver implementation.
102 void DeviceListChanged() override;
104 private:
105 // Handlers for JS WebUI messages.
106 void HandleCancel(const base::ListValue* args);
107 void HandleConnect(const base::ListValue* args);
108 void HandlePageReady(const base::ListValue* args);
110 std::string device_path_;
111 base::ListValue networks_list_;
112 bool is_page_ready_;
113 bool scanning_;
114 bool has_pending_results_;
116 DISALLOW_COPY_AND_ASSIGN(ChooseMobileNetworkHandler);
119 // ChooseMobileNetworkHandler implementation.
121 ChooseMobileNetworkHandler::ChooseMobileNetworkHandler()
122 : is_page_ready_(false),
123 scanning_(false),
124 has_pending_results_(false) {
125 NetworkStateHandler* handler = GetNetworkStateHandler();
126 const DeviceState* cellular =
127 handler->GetDeviceStateByType(NetworkTypePattern::Cellular());
128 if (!cellular) {
129 NET_LOG_ERROR(
130 "A cellular device is not available.",
131 "Cannot initiate a cellular network scan without a cellular device.");
132 return;
134 handler->AddObserver(this, FROM_HERE);
135 device_path_ = cellular->path();
136 GetNetworkDeviceHandler()->ProposeScan(
137 device_path_,
138 base::Bind(&base::DoNothing),
139 base::Bind(&NetworkOperationErrorCallback, "ProposeScan"));
142 ChooseMobileNetworkHandler::~ChooseMobileNetworkHandler() {
143 GetNetworkStateHandler()->RemoveObserver(this, FROM_HERE);
146 void ChooseMobileNetworkHandler::RegisterMessages() {
147 web_ui()->RegisterMessageCallback(
148 kJsApiCancel,
149 base::Bind(&ChooseMobileNetworkHandler::HandleCancel,
150 base::Unretained(this)));
151 web_ui()->RegisterMessageCallback(
152 kJsApiConnect,
153 base::Bind(&ChooseMobileNetworkHandler::HandleConnect,
154 base::Unretained(this)));
155 web_ui()->RegisterMessageCallback(
156 kJsApiPageReady,
157 base::Bind(&ChooseMobileNetworkHandler::HandlePageReady,
158 base::Unretained(this)));
161 void ChooseMobileNetworkHandler::DeviceListChanged() {
162 const DeviceState* cellular = GetNetworkStateHandler()->GetDeviceState(
163 device_path_);
164 networks_list_.Clear();
165 if (!cellular) {
166 LOG(WARNING) << "Cellular device with path '" << device_path_
167 << "' disappeared.";
168 return;
170 if (cellular->scanning()) {
171 NET_LOG_EVENT("ChooseMobileNetwork", "Device is scanning for networks.");
172 scanning_ = true;
173 if (is_page_ready_)
174 web_ui()->CallJavascriptFunction(kJsApiShowScanning);
175 return;
177 scanning_ = false;
178 const DeviceState::CellularScanResults& scan_results =
179 cellular->scan_results();
180 std::set<std::string> network_ids;
181 for (DeviceState::CellularScanResults::const_iterator it =
182 scan_results.begin(); it != scan_results.end(); ++it) {
183 // We need to remove duplicates from the list because same network with
184 // different technologies are listed multiple times. But ModemManager
185 // Register API doesn't allow technology to be specified so just show unique
186 // network in UI.
187 if (network_ids.insert(it->network_id).second) {
188 base::DictionaryValue* network = new base::DictionaryValue();
189 network->SetString(kNetworkIdProperty, it->network_id);
190 if (!it->long_name.empty())
191 network->SetString(kOperatorNameProperty, it->long_name);
192 else if (!it->short_name.empty())
193 network->SetString(kOperatorNameProperty, it->short_name);
194 else
195 network->SetString(kOperatorNameProperty, it->network_id);
196 network->SetString(kStatusProperty, it->status);
197 network->SetString(kTechnologyProperty, it->technology);
198 networks_list_.Append(network);
201 if (is_page_ready_) {
202 web_ui()->CallJavascriptFunction(kJsApiShowNetworks, networks_list_);
203 networks_list_.Clear();
204 has_pending_results_ = false;
205 } else {
206 has_pending_results_ = true;
210 void ChooseMobileNetworkHandler::HandleCancel(const base::ListValue* args) {
211 const size_t kConnectParamCount = 0;
212 if (args->GetSize() != kConnectParamCount) {
213 NOTREACHED();
214 return;
217 // Switch to automatic mode.
218 GetNetworkDeviceHandler()->RegisterCellularNetwork(
219 device_path_,
220 "", // An empty string is for registration with the home network.
221 base::Bind(&base::DoNothing),
222 base::Bind(&NetworkOperationErrorCallback,
223 "Register in automatic mode."));
226 void ChooseMobileNetworkHandler::HandleConnect(const base::ListValue* args) {
227 std::string network_id;
228 const size_t kConnectParamCount = 1;
229 if (args->GetSize() != kConnectParamCount ||
230 !args->GetString(0, &network_id)) {
231 NOTREACHED();
232 return;
235 GetNetworkDeviceHandler()->RegisterCellularNetwork(
236 device_path_,
237 network_id,
238 base::Bind(&base::DoNothing),
239 base::Bind(&NetworkOperationErrorCallback,
240 std::string("Register to network: ") + network_id));
243 void ChooseMobileNetworkHandler::HandlePageReady(const base::ListValue* args) {
244 const size_t kConnectParamCount = 0;
245 if (args->GetSize() != kConnectParamCount) {
246 NOTREACHED();
247 return;
250 if (has_pending_results_) {
251 web_ui()->CallJavascriptFunction(kJsApiShowNetworks, networks_list_);
252 networks_list_.Clear();
253 has_pending_results_ = false;
254 } else if (scanning_) {
255 web_ui()->CallJavascriptFunction(kJsApiShowScanning);
257 is_page_ready_ = true;
260 } // namespace
262 ChooseMobileNetworkUI::ChooseMobileNetworkUI(content::WebUI* web_ui)
263 : WebUIController(web_ui) {
264 ChooseMobileNetworkHandler* handler = new ChooseMobileNetworkHandler();
265 web_ui->AddMessageHandler(handler);
266 // Set up the "chrome://choose-mobile-network" source.
267 Profile* profile = Profile::FromWebUI(web_ui);
268 content::WebUIDataSource::Add(
269 profile, CreateChooseMobileNetworkUIHTMLSource());
272 } // namespace chromeos