Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / webui / chromeos / mobile_setup_ui.cc
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.
4
5 #include "chrome/browser/ui/webui/chromeos/mobile_setup_ui.h"
6
7 #include <algorithm>
8 #include <map>
9 #include <string>
10
11 #include "base/bind.h"
12 #include "base/bind_helpers.h"
13 #include "base/json/json_writer.h"
14 #include "base/logging.h"
15 #include "base/memory/ref_counted_memory.h"
16 #include "base/memory/weak_ptr.h"
17 #include "base/message_loop/message_loop.h"
18 #include "base/metrics/histogram.h"
19 #include "base/strings/string_piece.h"
20 #include "base/strings/string_util.h"
21 #include "base/strings/utf_string_conversions.h"
22 #include "base/values.h"
23 #include "chrome/browser/chromeos/mobile/mobile_activator.h"
24 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/ui/browser_list.h"
26 #include "chrome/common/pref_names.h"
27 #include "chrome/common/render_messages.h"
28 #include "chrome/common/url_constants.h"
29 #include "chromeos/network/device_state.h"
30 #include "chromeos/network/network_configuration_handler.h"
31 #include "chromeos/network/network_event_log.h"
32 #include "chromeos/network/network_state.h"
33 #include "chromeos/network/network_state_handler.h"
34 #include "chromeos/network/network_state_handler_observer.h"
35 #include "content/public/browser/browser_thread.h"
36 #include "content/public/browser/render_frame_host.h"
37 #include "content/public/browser/url_data_source.h"
38 #include "content/public/browser/web_contents.h"
39 #include "content/public/browser/web_ui.h"
40 #include "content/public/browser/web_ui_message_handler.h"
41 #include "grit/browser_resources.h"
42 #include "grit/chromium_strings.h"
43 #include "grit/generated_resources.h"
44 #include "grit/locale_settings.h"
45 #include "third_party/cros_system_api/dbus/service_constants.h"
46 #include "ui/base/l10n/l10n_util.h"
47 #include "ui/base/resource/resource_bundle.h"
48 #include "ui/base/webui/jstemplate_builder.h"
49 #include "ui/base/webui/web_ui_util.h"
50 #include "url/gurl.h"
51
52 using chromeos::MobileActivator;
53 using chromeos::NetworkHandler;
54 using chromeos::NetworkState;
55 using content::BrowserThread;
56 using content::RenderViewHost;
57 using content::WebContents;
58 using content::WebUIMessageHandler;
59
60 namespace {
61
62 // Host page JS API function names.
63 const char kJsApiStartActivation[] = "startActivation";
64 const char kJsApiSetTransactionStatus[] = "setTransactionStatus";
65 const char kJsApiPaymentPortalLoad[] = "paymentPortalLoad";
66 const char kJsGetDeviceInfo[] = "getDeviceInfo";
67 const char kJsApiResultOK[] = "ok";
68
69 const char kJsDeviceStatusChangedCallback[] =
70     "mobile.MobileSetup.deviceStateChanged";
71 const char kJsPortalFrameLoadFailedCallback[] =
72     "mobile.MobileSetup.portalFrameLoadError";
73 const char kJsPortalFrameLoadCompletedCallback[] =
74     "mobile.MobileSetup.portalFrameLoadCompleted";
75 const char kJsGetDeviceInfoCallback[] =
76     "mobile.MobileSetupPortal.onGotDeviceInfo";
77 const char kJsConnectivityChangedCallback[] =
78     "mobile.MobileSetupPortal.onConnectivityChanged";
79
80 void DataRequestFailed(
81     const std::string& service_path,
82     const content::URLDataSource::GotDataCallback& callback) {
83   NET_LOG_ERROR("Data Request Failed for Mobile Setup", service_path);
84   scoped_refptr<base::RefCountedBytes> html_bytes(new base::RefCountedBytes);
85   callback.Run(html_bytes.get());
86 }
87
88 // Converts the network properties into a JS object.
89 void GetDeviceInfo(const base::DictionaryValue& properties,
90                    base::DictionaryValue* value) {
91   std::string name;
92   properties.GetStringWithoutPathExpansion(shill::kNameProperty, &name);
93   std::string activation_type;
94   properties.GetStringWithoutPathExpansion(
95       shill::kActivationTypeProperty,
96       &activation_type);
97   const base::DictionaryValue* payment_dict;
98   std::string payment_url, post_method, post_data;
99   if (properties.GetDictionaryWithoutPathExpansion(
100           shill::kPaymentPortalProperty, &payment_dict)) {
101     payment_dict->GetStringWithoutPathExpansion(
102         shill::kPaymentPortalURL, &payment_url);
103     payment_dict->GetStringWithoutPathExpansion(
104         shill::kPaymentPortalMethod, &post_method);
105     payment_dict->GetStringWithoutPathExpansion(
106         shill::kPaymentPortalPostData, &post_data);
107   }
108
109   value->SetString("activation_type", activation_type);
110   value->SetString("carrier", name);
111   value->SetString("payment_url", payment_url);
112   if (LowerCaseEqualsASCII(post_method, "post") && !post_data.empty())
113     value->SetString("post_data", post_data);
114
115   // Use the cached DeviceState properties.
116   std::string device_path;
117   if (!properties.GetStringWithoutPathExpansion(
118           shill::kDeviceProperty, &device_path) ||
119       device_path.empty()) {
120     return;
121   }
122   const chromeos::DeviceState* device =
123       NetworkHandler::Get()->network_state_handler()->GetDeviceState(
124           device_path);
125   if (!device)
126     return;
127
128   value->SetString("MEID", device->meid());
129   value->SetString("IMEI", device->imei());
130   value->SetString("MDN", device->mdn());
131 }
132
133 void SetActivationStateAndError(MobileActivator::PlanActivationState state,
134                                 const std::string& error_description,
135                                 base::DictionaryValue* value) {
136   value->SetInteger("state", state);
137   if (!error_description.empty())
138     value->SetString("error", error_description);
139 }
140
141 }  // namespace
142
143 class MobileSetupUIHTMLSource : public content::URLDataSource {
144  public:
145   MobileSetupUIHTMLSource();
146
147   // content::URLDataSource implementation.
148   virtual std::string GetSource() const OVERRIDE;
149   virtual void StartDataRequest(
150       const std::string& path,
151       int render_process_id,
152       int render_frame_id,
153       const content::URLDataSource::GotDataCallback& callback) OVERRIDE;
154   virtual std::string GetMimeType(const std::string&) const OVERRIDE {
155     return "text/html";
156   }
157   virtual bool ShouldAddContentSecurityPolicy() const OVERRIDE {
158     return false;
159   }
160
161  private:
162   virtual ~MobileSetupUIHTMLSource() {}
163
164   void GetPropertiesAndStartDataRequest(
165       const content::URLDataSource::GotDataCallback& callback,
166       const std::string& service_path,
167       const base::DictionaryValue& properties);
168   void GetPropertiesFailure(
169       const content::URLDataSource::GotDataCallback& callback,
170       const std::string& service_path,
171       const std::string& error_name,
172       scoped_ptr<base::DictionaryValue> error_data);
173
174   base::WeakPtrFactory<MobileSetupUIHTMLSource> weak_ptr_factory_;
175
176   DISALLOW_COPY_AND_ASSIGN(MobileSetupUIHTMLSource);
177 };
178
179 // The handler for Javascript messages related to the "register" view.
180 class MobileSetupHandler
181   : public WebUIMessageHandler,
182     public MobileActivator::Observer,
183     public chromeos::NetworkStateHandlerObserver,
184     public base::SupportsWeakPtr<MobileSetupHandler> {
185  public:
186   MobileSetupHandler();
187   virtual ~MobileSetupHandler();
188
189   // WebUIMessageHandler implementation.
190   virtual void RegisterMessages() OVERRIDE;
191
192  private:
193   enum Type {
194     TYPE_UNDETERMINED,
195     // The network is not yet activated, and the webui is in activation flow.
196     TYPE_ACTIVATION,
197     // The network is activated, the webui displays network portal.
198     TYPE_PORTAL,
199     // Same as TYPE_PORTAL, but the network technology is LTE. The webui is
200     // additionally aware of network manager state and whether the portal can be
201     // reached.
202     TYPE_PORTAL_LTE
203   };
204
205   // MobileActivator::Observer.
206   virtual void OnActivationStateChanged(
207       const NetworkState* network,
208       MobileActivator::PlanActivationState new_state,
209       const std::string& error_description) OVERRIDE;
210
211   // Callbacks for NetworkConfigurationHandler::GetProperties.
212   void GetPropertiesAndCallStatusChanged(
213       MobileActivator::PlanActivationState state,
214       const std::string& error_description,
215       const std::string& service_path,
216       const base::DictionaryValue& properties);
217   void GetPropertiesAndCallGetDeviceInfo(
218       const std::string& service_path,
219       const base::DictionaryValue& properties);
220   void GetPropertiesFailure(
221       const std::string& service_path,
222       const std::string& callback_name,
223       const std::string& error_name,
224       scoped_ptr<base::DictionaryValue> error_data);
225
226   // Handlers for JS WebUI messages.
227   void HandleSetTransactionStatus(const base::ListValue* args);
228   void HandleStartActivation(const base::ListValue* args);
229   void HandlePaymentPortalLoad(const base::ListValue* args);
230   void HandleGetDeviceInfo(const base::ListValue* args);
231
232   // NetworkStateHandlerObserver implementation.
233   virtual void NetworkConnectionStateChanged(
234       const NetworkState* network) OVERRIDE;
235   virtual void DefaultNetworkChanged(
236       const NetworkState* default_network) OVERRIDE;
237
238   // Updates |lte_portal_reachable_| for lte network |network| and notifies
239   // webui of the new state if the reachability changed or |force_notification|
240   // is set.
241   void UpdatePortalReachability(const NetworkState* network,
242                                 bool force_notification);
243
244   // Sends message to host registration page with system/user info data.
245   void SendDeviceInfo();
246
247   // Type of the mobilesetup webui deduced from received messages.
248   Type type_;
249   // Whether portal page for lte networks can be reached in current network
250   // connection state. This value is reflected in portal webui for lte networks.
251   // Initial value is true.
252   bool lte_portal_reachable_;
253   base::WeakPtrFactory<MobileSetupHandler> weak_ptr_factory_;
254
255   DISALLOW_COPY_AND_ASSIGN(MobileSetupHandler);
256 };
257
258 ////////////////////////////////////////////////////////////////////////////////
259 //
260 // MobileSetupUIHTMLSource
261 //
262 ////////////////////////////////////////////////////////////////////////////////
263
264 MobileSetupUIHTMLSource::MobileSetupUIHTMLSource()
265     : weak_ptr_factory_(this) {
266 }
267
268 std::string MobileSetupUIHTMLSource::GetSource() const {
269   return chrome::kChromeUIMobileSetupHost;
270 }
271
272 void MobileSetupUIHTMLSource::StartDataRequest(
273     const std::string& path,
274     int render_process_id,
275     int render_frame_id,
276     const content::URLDataSource::GotDataCallback& callback) {
277   NetworkHandler::Get()->network_configuration_handler()->GetProperties(
278       path,
279       base::Bind(&MobileSetupUIHTMLSource::GetPropertiesAndStartDataRequest,
280                  weak_ptr_factory_.GetWeakPtr(),
281                  callback),
282       base::Bind(&MobileSetupUIHTMLSource::GetPropertiesFailure,
283                  weak_ptr_factory_.GetWeakPtr(),
284                  callback, path));
285 }
286
287 void MobileSetupUIHTMLSource::GetPropertiesAndStartDataRequest(
288     const content::URLDataSource::GotDataCallback& callback,
289     const std::string& service_path,
290     const base::DictionaryValue& properties) {
291   const base::DictionaryValue* payment_dict;
292   std::string name, usage_url, activation_state, payment_url;
293   if (!properties.GetStringWithoutPathExpansion(
294           shill::kNameProperty, &name) ||
295       !properties.GetStringWithoutPathExpansion(
296           shill::kUsageURLProperty, &usage_url) ||
297       !properties.GetStringWithoutPathExpansion(
298           shill::kActivationStateProperty, &activation_state) ||
299       !properties.GetDictionaryWithoutPathExpansion(
300           shill::kPaymentPortalProperty, &payment_dict) ||
301       !payment_dict->GetStringWithoutPathExpansion(
302           shill::kPaymentPortalURL, &payment_url)) {
303     DataRequestFailed(service_path, callback);
304     return;
305   }
306
307   if (payment_url.empty() && usage_url.empty() &&
308       activation_state != shill::kActivationStateActivated) {
309     DataRequestFailed(service_path, callback);
310     return;
311   }
312
313   NET_LOG_EVENT("Starting mobile setup", service_path);
314   base::DictionaryValue strings;
315
316   strings.SetString("connecting_header",
317                     l10n_util::GetStringFUTF16(IDS_MOBILE_CONNECTING_HEADER,
318                                                base::UTF8ToUTF16(name)));
319   strings.SetString("error_header",
320                     l10n_util::GetStringUTF16(IDS_MOBILE_ERROR_HEADER));
321   strings.SetString("activating_header",
322                     l10n_util::GetStringUTF16(IDS_MOBILE_ACTIVATING_HEADER));
323   strings.SetString("completed_header",
324                     l10n_util::GetStringUTF16(IDS_MOBILE_COMPLETED_HEADER));
325   strings.SetString("please_wait",
326                     l10n_util::GetStringUTF16(IDS_MOBILE_PLEASE_WAIT));
327   strings.SetString("completed_text",
328                     l10n_util::GetStringUTF16(IDS_MOBILE_COMPLETED_TEXT));
329   strings.SetString("portal_unreachable_header",
330                     l10n_util::GetStringUTF16(IDS_MOBILE_NO_CONNECTION_HEADER));
331   strings.SetString("invalid_device_info_header",
332       l10n_util::GetStringUTF16(IDS_MOBILE_INVALID_DEVICE_INFO_HEADER));
333   strings.SetString("title", l10n_util::GetStringUTF16(IDS_MOBILE_SETUP_TITLE));
334   strings.SetString("close_button",
335                     l10n_util::GetStringUTF16(IDS_CLOSE));
336   strings.SetString("cancel_button",
337                     l10n_util::GetStringUTF16(IDS_CANCEL));
338   strings.SetString("ok_button",
339                     l10n_util::GetStringUTF16(IDS_OK));
340   webui::SetFontAndTextDirection(&strings);
341
342   // The webui differs based on whether the network is activated or not. If the
343   // network is activated, the webui goes straight to portal. Otherwise the
344   // webui is used for activation flow.
345   std::string full_html;
346   if (activation_state == shill::kActivationStateActivated) {
347     static const base::StringPiece html_for_activated(
348         ResourceBundle::GetSharedInstance().GetRawDataResource(
349             IDR_MOBILE_SETUP_PORTAL_PAGE_HTML));
350     full_html = webui::GetI18nTemplateHtml(html_for_activated, &strings);
351   } else {
352     static const base::StringPiece html_for_non_activated(
353         ResourceBundle::GetSharedInstance().GetRawDataResource(
354             IDR_MOBILE_SETUP_PAGE_HTML));
355     full_html = webui::GetI18nTemplateHtml(html_for_non_activated, &strings);
356   }
357
358   callback.Run(base::RefCountedString::TakeString(&full_html));
359 }
360
361 void MobileSetupUIHTMLSource::GetPropertiesFailure(
362     const content::URLDataSource::GotDataCallback& callback,
363     const std::string& service_path,
364     const std::string& error_name,
365     scoped_ptr<base::DictionaryValue> error_data) {
366   DataRequestFailed(service_path, callback);
367 }
368
369 ////////////////////////////////////////////////////////////////////////////////
370 //
371 // MobileSetupHandler
372 //
373 ////////////////////////////////////////////////////////////////////////////////
374 MobileSetupHandler::MobileSetupHandler()
375     : type_(TYPE_UNDETERMINED),
376       lte_portal_reachable_(true),
377       weak_ptr_factory_(this) {
378 }
379
380 MobileSetupHandler::~MobileSetupHandler() {
381   if (type_ == TYPE_ACTIVATION) {
382     MobileActivator::GetInstance()->RemoveObserver(this);
383     MobileActivator::GetInstance()->TerminateActivation();
384   } else if (type_ == TYPE_PORTAL_LTE) {
385     NetworkHandler::Get()->network_state_handler()->RemoveObserver(this,
386                                                                    FROM_HERE);
387   }
388 }
389
390 void MobileSetupHandler::OnActivationStateChanged(
391     const NetworkState* network,
392     MobileActivator::PlanActivationState state,
393     const std::string& error_description) {
394   DCHECK_EQ(TYPE_ACTIVATION, type_);
395   if (!web_ui())
396     return;
397
398   if (!network) {
399     base::DictionaryValue device_dict;
400     SetActivationStateAndError(state, error_description, &device_dict);
401     web_ui()->CallJavascriptFunction(kJsDeviceStatusChangedCallback,
402                                      device_dict);
403     return;
404   }
405
406   NetworkHandler::Get()->network_configuration_handler()->GetProperties(
407       network->path(),
408       base::Bind(&MobileSetupHandler::GetPropertiesAndCallStatusChanged,
409                  weak_ptr_factory_.GetWeakPtr(),
410                  state,
411                  error_description),
412       base::Bind(&MobileSetupHandler::GetPropertiesFailure,
413                  weak_ptr_factory_.GetWeakPtr(),
414                  network->path(),
415                  kJsDeviceStatusChangedCallback));
416 }
417
418 void MobileSetupHandler::GetPropertiesAndCallStatusChanged(
419     MobileActivator::PlanActivationState state,
420     const std::string& error_description,
421     const std::string& service_path,
422     const base::DictionaryValue& properties) {
423   base::DictionaryValue device_dict;
424   GetDeviceInfo(properties, &device_dict);
425   SetActivationStateAndError(state, error_description, &device_dict);
426   web_ui()->CallJavascriptFunction(kJsDeviceStatusChangedCallback, device_dict);
427 }
428
429 void MobileSetupHandler::RegisterMessages() {
430   web_ui()->RegisterMessageCallback(kJsApiStartActivation,
431       base::Bind(&MobileSetupHandler::HandleStartActivation,
432                  base::Unretained(this)));
433   web_ui()->RegisterMessageCallback(kJsApiSetTransactionStatus,
434       base::Bind(&MobileSetupHandler::HandleSetTransactionStatus,
435                  base::Unretained(this)));
436   web_ui()->RegisterMessageCallback(kJsApiPaymentPortalLoad,
437       base::Bind(&MobileSetupHandler::HandlePaymentPortalLoad,
438                  base::Unretained(this)));
439   web_ui()->RegisterMessageCallback(kJsGetDeviceInfo,
440       base::Bind(&MobileSetupHandler::HandleGetDeviceInfo,
441                  base::Unretained(this)));
442 }
443
444 void MobileSetupHandler::HandleStartActivation(const base::ListValue* args) {
445   DCHECK_EQ(TYPE_UNDETERMINED, type_);
446
447   if (!web_ui())
448     return;
449
450   std::string path = web_ui()->GetWebContents()->GetURL().path();
451   if (!path.size())
452     return;
453
454   LOG(WARNING) << "Starting activation for service " << path;
455
456   type_ = TYPE_ACTIVATION;
457   MobileActivator::GetInstance()->AddObserver(this);
458   MobileActivator::GetInstance()->InitiateActivation(path.substr(1));
459 }
460
461 void MobileSetupHandler::HandleSetTransactionStatus(
462     const base::ListValue* args) {
463   DCHECK_EQ(TYPE_ACTIVATION, type_);
464   if (!web_ui())
465     return;
466
467   const size_t kSetTransactionStatusParamCount = 1;
468   if (args->GetSize() != kSetTransactionStatusParamCount)
469     return;
470   // Get change callback function name.
471   std::string status;
472   if (!args->GetString(0, &status))
473     return;
474
475   MobileActivator::GetInstance()->OnSetTransactionStatus(
476       LowerCaseEqualsASCII(status, kJsApiResultOK));
477 }
478
479 void MobileSetupHandler::HandlePaymentPortalLoad(const base::ListValue* args) {
480   // Only activation flow webui is interested in these events.
481   if (type_ != TYPE_ACTIVATION || !web_ui())
482     return;
483
484   const size_t kPaymentPortalLoadParamCount = 1;
485   if (args->GetSize() != kPaymentPortalLoadParamCount)
486     return;
487   // Get change callback function name.
488   std::string result;
489   if (!args->GetString(0, &result))
490     return;
491
492   MobileActivator::GetInstance()->OnPortalLoaded(
493       LowerCaseEqualsASCII(result, kJsApiResultOK));
494 }
495
496 void MobileSetupHandler::HandleGetDeviceInfo(const base::ListValue* args) {
497   DCHECK_NE(TYPE_ACTIVATION, type_);
498   if (!web_ui())
499     return;
500
501   std::string path = web_ui()->GetWebContents()->GetURL().path();
502   if (path.empty())
503     return;
504
505   chromeos::NetworkStateHandler* nsh =
506       NetworkHandler::Get()->network_state_handler();
507   // TODO: Figure out why the path has an extra '/' in the front. (e.g. It is
508   // '//service/5' instead of '/service/5'.
509   const NetworkState* network = nsh->GetNetworkState(path.substr(1));
510   if (!network) {
511     web_ui()->GetWebContents()->Close();
512     return;
513   }
514
515   // If this is the initial call, update the network status and start observing
516   // network changes, but only for LTE networks. The other networks should
517   // ignore network status.
518   if (type_ == TYPE_UNDETERMINED) {
519     if (network->network_technology() == shill::kNetworkTechnologyLte ||
520         network->network_technology() == shill::kNetworkTechnologyLteAdvanced) {
521       type_ = TYPE_PORTAL_LTE;
522       nsh->AddObserver(this, FROM_HERE);
523       // Update the network status and notify the webui. This is the initial
524       // network state so the webui should be notified no matter what.
525       UpdatePortalReachability(network,
526                                true /* force notification */);
527     } else {
528       type_ = TYPE_PORTAL;
529       // For non-LTE networks network state is ignored, so report the portal is
530       // reachable, so it gets shown.
531       web_ui()->CallJavascriptFunction(kJsConnectivityChangedCallback,
532                                        base::FundamentalValue(true));
533     }
534   }
535
536   NetworkHandler::Get()->network_configuration_handler()->GetProperties(
537       network->path(),
538       base::Bind(&MobileSetupHandler::GetPropertiesAndCallGetDeviceInfo,
539                  weak_ptr_factory_.GetWeakPtr()),
540       base::Bind(&MobileSetupHandler::GetPropertiesFailure,
541                  weak_ptr_factory_.GetWeakPtr(),
542                  network->path(),
543                  kJsGetDeviceInfoCallback));
544 }
545
546 void MobileSetupHandler::GetPropertiesAndCallGetDeviceInfo(
547     const std::string& service_path,
548     const base::DictionaryValue& properties) {
549   base::DictionaryValue device_info;
550   GetDeviceInfo(properties, &device_info);
551   web_ui()->CallJavascriptFunction(kJsGetDeviceInfoCallback, device_info);
552 }
553
554 void MobileSetupHandler::GetPropertiesFailure(
555     const std::string& service_path,
556     const std::string& callback_name,
557     const std::string& error_name,
558     scoped_ptr<base::DictionaryValue> error_data) {
559   NET_LOG_ERROR("MobileActivator GetProperties Failed: " + error_name,
560                 service_path);
561   // Invoke |callback_name| with an empty dictionary.
562   base::DictionaryValue device_dict;
563   web_ui()->CallJavascriptFunction(callback_name, device_dict);
564 }
565
566 void MobileSetupHandler::DefaultNetworkChanged(
567     const NetworkState* default_network) {
568   if (!web_ui())
569     return;
570
571   std::string path = web_ui()->GetWebContents()->GetURL().path().substr(1);
572   if (path.empty())
573     return;
574
575   const NetworkState* network =
576       NetworkHandler::Get()->network_state_handler()->GetNetworkState(path);
577   if (!network) {
578     LOG(ERROR) << "Service path lost";
579     web_ui()->GetWebContents()->Close();
580     return;
581   }
582
583   UpdatePortalReachability(network, false /* do not force notification */);
584 }
585
586 void MobileSetupHandler::NetworkConnectionStateChanged(
587     const NetworkState* network) {
588   if (!web_ui())
589     return;
590
591   std::string path = web_ui()->GetWebContents()->GetURL().path().substr(1);
592   if (path.empty() || path != network->path())
593     return;
594
595   UpdatePortalReachability(network, false /* do not force notification */);
596 }
597
598 void MobileSetupHandler::UpdatePortalReachability(
599     const NetworkState* network,
600     bool force_notification) {
601   DCHECK(web_ui());
602
603   DCHECK_EQ(type_, TYPE_PORTAL_LTE);
604
605   chromeos::NetworkStateHandler* nsh =
606       NetworkHandler::Get()->network_state_handler();
607   bool portal_reachable =
608       (network->IsConnectedState() ||
609        (nsh->DefaultNetwork() &&
610         nsh->DefaultNetwork()->connection_state() == shill::kStateOnline));
611
612   if (force_notification || portal_reachable != lte_portal_reachable_) {
613     web_ui()->CallJavascriptFunction(kJsConnectivityChangedCallback,
614                                      base::FundamentalValue(portal_reachable));
615   }
616
617   lte_portal_reachable_ = portal_reachable;
618 }
619
620 ////////////////////////////////////////////////////////////////////////////////
621 //
622 // MobileSetupUI
623 //
624 ////////////////////////////////////////////////////////////////////////////////
625
626 MobileSetupUI::MobileSetupUI(content::WebUI* web_ui)
627     : WebUIController(web_ui) {
628   web_ui->AddMessageHandler(new MobileSetupHandler());
629   MobileSetupUIHTMLSource* html_source = new MobileSetupUIHTMLSource();
630
631   // Set up the chrome://mobilesetup/ source.
632   Profile* profile = Profile::FromWebUI(web_ui);
633   content::URLDataSource::Add(profile, html_source);
634
635   content::WebContentsObserver::Observe(web_ui->GetWebContents());
636 }
637
638 void MobileSetupUI::DidCommitProvisionalLoadForFrame(
639     content::RenderFrameHost* render_frame_host,
640     const GURL& url,
641     content::PageTransition transition_type) {
642   if (render_frame_host->GetFrameName() != "paymentForm")
643     return;
644
645   web_ui()->CallJavascriptFunction(
646         kJsPortalFrameLoadCompletedCallback);
647 }
648
649 void MobileSetupUI::DidFailProvisionalLoad(
650     content::RenderFrameHost* render_frame_host,
651     const GURL& validated_url,
652     int error_code,
653     const base::string16& error_description) {
654   if (render_frame_host->GetFrameName() != "paymentForm")
655     return;
656
657   base::FundamentalValue result_value(-error_code);
658   web_ui()->CallJavascriptFunction(kJsPortalFrameLoadFailedCallback,
659                                    result_value);
660 }