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/url_data_source.h" 37 #include "content/public/browser/web_contents.h" 38 #include "content/public/browser/web_ui.h" 39 #include "content/public/browser/web_ui_message_handler.h" 40 #include "grit/browser_resources.h" 41 #include "grit/chromium_strings.h" 42 #include "grit/generated_resources.h" 43 #include "grit/locale_settings.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 DictionaryValue& properties, DictionaryValue* value) { 89 std::string name; 90 properties.GetStringWithoutPathExpansion(shill::kNameProperty, &name); 91 bool activate_over_non_cellular_networks = false; 92 properties.GetBooleanWithoutPathExpansion( 93 shill::kActivateOverNonCellularNetworkProperty, 94 &activate_over_non_cellular_networks); 95 const DictionaryValue* payment_dict; 96 std::string payment_url, post_method, post_data; 97 if (properties.GetDictionaryWithoutPathExpansion( 98 shill::kPaymentPortalProperty, &payment_dict)) { 99 payment_dict->GetStringWithoutPathExpansion( 100 shill::kPaymentPortalURL, &payment_url); 101 payment_dict->GetStringWithoutPathExpansion( 102 shill::kPaymentPortalMethod, &post_method); 103 payment_dict->GetStringWithoutPathExpansion( 104 shill::kPaymentPortalPostData, &post_data); 105 } 106 107 value->SetBoolean("activate_over_non_cellular_network", 108 activate_over_non_cellular_networks); 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 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_view_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 ListValue* args); 227 void HandleStartActivation(const ListValue* args); 228 void HandlePaymentPortalLoad(const ListValue* args); 229 void HandleGetDeviceInfo(const 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_view_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 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 DictionaryValue strings; 314 315 strings.SetString("connecting_header", 316 l10n_util::GetStringFUTF16(IDS_MOBILE_CONNECTING_HEADER, 317 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 // The webui differs based on whether the network is activated or not. If the 342 // network is activated, the webui goes straight to portal. Otherwise the 343 // webui is used for activation flow. 344 std::string full_html; 345 if (activation_state == shill::kActivationStateActivated) { 346 static const base::StringPiece html_for_activated( 347 ResourceBundle::GetSharedInstance().GetRawDataResource( 348 IDR_MOBILE_SETUP_PORTAL_PAGE_HTML)); 349 full_html = webui::GetI18nTemplateHtml(html_for_activated, &strings); 350 } else { 351 static const base::StringPiece html_for_non_activated( 352 ResourceBundle::GetSharedInstance().GetRawDataResource( 353 IDR_MOBILE_SETUP_PAGE_HTML)); 354 full_html = webui::GetI18nTemplateHtml(html_for_non_activated, &strings); 355 } 356 357 callback.Run(base::RefCountedString::TakeString(&full_html)); 358 } 359 360 void MobileSetupUIHTMLSource::GetPropertiesFailure( 361 const content::URLDataSource::GotDataCallback& callback, 362 const std::string& service_path, 363 const std::string& error_name, 364 scoped_ptr<base::DictionaryValue> error_data) { 365 DataRequestFailed(service_path, callback); 366 } 367 368 //////////////////////////////////////////////////////////////////////////////// 369 // 370 // MobileSetupHandler 371 // 372 //////////////////////////////////////////////////////////////////////////////// 373 MobileSetupHandler::MobileSetupHandler() 374 : type_(TYPE_UNDETERMINED), 375 lte_portal_reachable_(true), 376 weak_ptr_factory_(this) { 377 } 378 379 MobileSetupHandler::~MobileSetupHandler() { 380 if (type_ == TYPE_ACTIVATION) { 381 MobileActivator::GetInstance()->RemoveObserver(this); 382 MobileActivator::GetInstance()->TerminateActivation(); 383 } else if (type_ == TYPE_PORTAL_LTE) { 384 NetworkHandler::Get()->network_state_handler()->RemoveObserver(this, 385 FROM_HERE); 386 } 387 } 388 389 void MobileSetupHandler::OnActivationStateChanged( 390 const NetworkState* network, 391 MobileActivator::PlanActivationState state, 392 const std::string& error_description) { 393 DCHECK_EQ(TYPE_ACTIVATION, type_); 394 if (!web_ui()) 395 return; 396 397 if (!network) { 398 DictionaryValue device_dict; 399 SetActivationStateAndError(state, error_description, &device_dict); 400 web_ui()->CallJavascriptFunction(kJsDeviceStatusChangedCallback, 401 device_dict); 402 return; 403 } 404 405 NetworkHandler::Get()->network_configuration_handler()->GetProperties( 406 network->path(), 407 base::Bind(&MobileSetupHandler::GetPropertiesAndCallStatusChanged, 408 weak_ptr_factory_.GetWeakPtr(), 409 state, 410 error_description), 411 base::Bind(&MobileSetupHandler::GetPropertiesFailure, 412 weak_ptr_factory_.GetWeakPtr(), 413 network->path(), 414 kJsDeviceStatusChangedCallback)); 415 } 416 417 void MobileSetupHandler::GetPropertiesAndCallStatusChanged( 418 MobileActivator::PlanActivationState state, 419 const std::string& error_description, 420 const std::string& service_path, 421 const base::DictionaryValue& properties) { 422 DictionaryValue device_dict; 423 GetDeviceInfo(properties, &device_dict); 424 SetActivationStateAndError(state, error_description, &device_dict); 425 web_ui()->CallJavascriptFunction(kJsDeviceStatusChangedCallback, device_dict); 426 } 427 428 void MobileSetupHandler::RegisterMessages() { 429 web_ui()->RegisterMessageCallback(kJsApiStartActivation, 430 base::Bind(&MobileSetupHandler::HandleStartActivation, 431 base::Unretained(this))); 432 web_ui()->RegisterMessageCallback(kJsApiSetTransactionStatus, 433 base::Bind(&MobileSetupHandler::HandleSetTransactionStatus, 434 base::Unretained(this))); 435 web_ui()->RegisterMessageCallback(kJsApiPaymentPortalLoad, 436 base::Bind(&MobileSetupHandler::HandlePaymentPortalLoad, 437 base::Unretained(this))); 438 web_ui()->RegisterMessageCallback(kJsGetDeviceInfo, 439 base::Bind(&MobileSetupHandler::HandleGetDeviceInfo, 440 base::Unretained(this))); 441 } 442 443 void MobileSetupHandler::HandleStartActivation(const ListValue* args) { 444 DCHECK_EQ(TYPE_UNDETERMINED, type_); 445 446 if (!web_ui()) 447 return; 448 449 std::string path = web_ui()->GetWebContents()->GetURL().path(); 450 if (!path.size()) 451 return; 452 453 LOG(WARNING) << "Starting activation for service " << path; 454 455 type_ = TYPE_ACTIVATION; 456 MobileActivator::GetInstance()->AddObserver(this); 457 MobileActivator::GetInstance()->InitiateActivation(path.substr(1)); 458 } 459 460 void MobileSetupHandler::HandleSetTransactionStatus(const ListValue* args) { 461 DCHECK_EQ(TYPE_ACTIVATION, type_); 462 if (!web_ui()) 463 return; 464 465 const size_t kSetTransactionStatusParamCount = 1; 466 if (args->GetSize() != kSetTransactionStatusParamCount) 467 return; 468 // Get change callback function name. 469 std::string status; 470 if (!args->GetString(0, &status)) 471 return; 472 473 MobileActivator::GetInstance()->OnSetTransactionStatus( 474 LowerCaseEqualsASCII(status, kJsApiResultOK)); 475 } 476 477 void MobileSetupHandler::HandlePaymentPortalLoad(const ListValue* args) { 478 // Only activation flow webui is interested in these events. 479 if (type_ != TYPE_ACTIVATION || !web_ui()) 480 return; 481 482 const size_t kPaymentPortalLoadParamCount = 1; 483 if (args->GetSize() != kPaymentPortalLoadParamCount) 484 return; 485 // Get change callback function name. 486 std::string result; 487 if (!args->GetString(0, &result)) 488 return; 489 490 MobileActivator::GetInstance()->OnPortalLoaded( 491 LowerCaseEqualsASCII(result, kJsApiResultOK)); 492 } 493 494 void MobileSetupHandler::HandleGetDeviceInfo(const ListValue* args) { 495 DCHECK_NE(TYPE_ACTIVATION, type_); 496 if (!web_ui()) 497 return; 498 499 std::string path = web_ui()->GetWebContents()->GetURL().path(); 500 if (path.empty()) 501 return; 502 503 chromeos::NetworkStateHandler* nsh = 504 NetworkHandler::Get()->network_state_handler(); 505 // TODO: Figure out why the path has an extra '/' in the front. (e.g. It is 506 // '//service/5' instead of '/service/5'. 507 const NetworkState* network = nsh->GetNetworkState(path.substr(1)); 508 if (!network) { 509 web_ui()->GetWebContents()->Close(); 510 return; 511 } 512 513 // If this is the initial call, update the network status and start observing 514 // network changes, but only for LTE networks. The other networks should 515 // ignore network status. 516 if (type_ == TYPE_UNDETERMINED) { 517 if (network->network_technology() == shill::kNetworkTechnologyLte || 518 network->network_technology() == shill::kNetworkTechnologyLteAdvanced) { 519 type_ = TYPE_PORTAL_LTE; 520 nsh->AddObserver(this, FROM_HERE); 521 // Update the network status and notify the webui. This is the initial 522 // network state so the webui should be notified no matter what. 523 UpdatePortalReachability(network, 524 true /* force notification */); 525 } else { 526 type_ = TYPE_PORTAL; 527 // For non-LTE networks network state is ignored, so report the portal is 528 // reachable, so it gets shown. 529 web_ui()->CallJavascriptFunction(kJsConnectivityChangedCallback, 530 base::FundamentalValue(true)); 531 } 532 } 533 534 NetworkHandler::Get()->network_configuration_handler()->GetProperties( 535 network->path(), 536 base::Bind(&MobileSetupHandler::GetPropertiesAndCallGetDeviceInfo, 537 weak_ptr_factory_.GetWeakPtr()), 538 base::Bind(&MobileSetupHandler::GetPropertiesFailure, 539 weak_ptr_factory_.GetWeakPtr(), 540 network->path(), 541 kJsGetDeviceInfoCallback)); 542 } 543 544 void MobileSetupHandler::GetPropertiesAndCallGetDeviceInfo( 545 const std::string& service_path, 546 const base::DictionaryValue& properties) { 547 DictionaryValue device_info; 548 GetDeviceInfo(properties, &device_info); 549 web_ui()->CallJavascriptFunction(kJsGetDeviceInfoCallback, device_info); 550 } 551 552 void MobileSetupHandler::GetPropertiesFailure( 553 const std::string& service_path, 554 const std::string& callback_name, 555 const std::string& error_name, 556 scoped_ptr<base::DictionaryValue> error_data) { 557 NET_LOG_ERROR("MobileActivator GetProperties Failed: " + error_name, 558 service_path); 559 // Invoke |callback_name| with an empty dictionary. 560 DictionaryValue device_dict; 561 web_ui()->CallJavascriptFunction(callback_name, device_dict); 562 } 563 564 void MobileSetupHandler::DefaultNetworkChanged( 565 const NetworkState* default_network) { 566 if (!web_ui()) 567 return; 568 569 std::string path = web_ui()->GetWebContents()->GetURL().path().substr(1); 570 if (path.empty()) 571 return; 572 573 const NetworkState* network = 574 NetworkHandler::Get()->network_state_handler()->GetNetworkState(path); 575 if (!network) { 576 LOG(ERROR) << "Service path lost"; 577 web_ui()->GetWebContents()->Close(); 578 return; 579 } 580 581 UpdatePortalReachability(network, false /* do not force notification */); 582 } 583 584 void MobileSetupHandler::NetworkConnectionStateChanged( 585 const NetworkState* network) { 586 if (!web_ui()) 587 return; 588 589 std::string path = web_ui()->GetWebContents()->GetURL().path().substr(1); 590 if (path.empty() || path != network->path()) 591 return; 592 593 UpdatePortalReachability(network, false /* do not force notification */); 594 } 595 596 void MobileSetupHandler::UpdatePortalReachability( 597 const NetworkState* network, 598 bool force_notification) { 599 DCHECK(web_ui()); 600 601 DCHECK_EQ(type_, TYPE_PORTAL_LTE); 602 603 chromeos::NetworkStateHandler* nsh = 604 NetworkHandler::Get()->network_state_handler(); 605 bool portal_reachable = 606 (network->IsConnectedState() || 607 (nsh->DefaultNetwork() && 608 nsh->DefaultNetwork()->connection_state() == shill::kStateOnline)); 609 610 if (force_notification || portal_reachable != lte_portal_reachable_) { 611 web_ui()->CallJavascriptFunction(kJsConnectivityChangedCallback, 612 base::FundamentalValue(portal_reachable)); 613 } 614 615 lte_portal_reachable_ = portal_reachable; 616 } 617 618 //////////////////////////////////////////////////////////////////////////////// 619 // 620 // MobileSetupUI 621 // 622 //////////////////////////////////////////////////////////////////////////////// 623 624 MobileSetupUI::MobileSetupUI(content::WebUI* web_ui) 625 : WebUIController(web_ui) { 626 web_ui->AddMessageHandler(new MobileSetupHandler()); 627 MobileSetupUIHTMLSource* html_source = new MobileSetupUIHTMLSource(); 628 629 // Set up the chrome://mobilesetup/ source. 630 Profile* profile = Profile::FromWebUI(web_ui); 631 content::URLDataSource::Add(profile, html_source); 632 633 content::WebContentsObserver::Observe(web_ui->GetWebContents()); 634 } 635 636 void MobileSetupUI::DidCommitProvisionalLoadForFrame( 637 int64 frame_id, 638 const base::string16& frame_unique_name, 639 bool is_main_frame, 640 const GURL& url, 641 content::PageTransition transition_type, 642 content::RenderViewHost* render_view_host) { 643 if (frame_unique_name != UTF8ToUTF16("paymentForm")) 644 return; 645 646 web_ui()->CallJavascriptFunction( 647 kJsPortalFrameLoadCompletedCallback); 648 } 649 650 void MobileSetupUI::DidFailProvisionalLoad( 651 int64 frame_id, 652 const base::string16& frame_unique_name, 653 bool is_main_frame, 654 const GURL& validated_url, 655 int error_code, 656 const base::string16& error_description, 657 content::RenderViewHost* render_view_host) { 658 if (frame_unique_name != UTF8ToUTF16("paymentForm")) 659 return; 660 661 base::FundamentalValue result_value(-error_code); 662 web_ui()->CallJavascriptFunction(kJsPortalFrameLoadFailedCallback, 663 result_value); 664 } 665