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