local_discovery_ui_handler.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
1// Copyright 2013 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/local_discovery/local_discovery_ui_handler.h" 6 7#include <set> 8 9#include "base/bind.h" 10#include "base/command_line.h" 11#include "base/message_loop/message_loop.h" 12#include "base/prefs/pref_service.h" 13#include "base/strings/stringprintf.h" 14#include "base/strings/utf_string_conversions.h" 15#include "base/values.h" 16#include "chrome/browser/local_discovery/privet_confirm_api_flow.h" 17#include "chrome/browser/local_discovery/privet_constants.h" 18#include "chrome/browser/local_discovery/privet_device_lister_impl.h" 19#include "chrome/browser/local_discovery/privet_http_asynchronous_factory.h" 20#include "chrome/browser/local_discovery/privet_http_impl.h" 21#include "chrome/browser/local_discovery/service_discovery_shared_client.h" 22#include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h" 23#include "chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory.h" 24#include "chrome/browser/profiles/profile.h" 25#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 26#include "chrome/browser/signin/signin_manager_factory.h" 27#include "chrome/browser/signin/signin_promo.h" 28#include "chrome/browser/ui/browser_finder.h" 29#include "chrome/browser/ui/browser_tabstrip.h" 30#include "chrome/common/chrome_switches.h" 31#include "chrome/common/pref_names.h" 32#include "components/cloud_devices/common/cloud_devices_switches.h" 33#include "components/cloud_devices/common/cloud_devices_urls.h" 34#include "components/signin/core/browser/profile_oauth2_token_service.h" 35#include "components/signin/core/browser/signin_manager_base.h" 36#include "content/public/browser/user_metrics.h" 37#include "content/public/browser/web_ui.h" 38#include "content/public/common/page_transition_types.h" 39#include "grit/generated_resources.h" 40#include "net/base/host_port_pair.h" 41#include "net/base/net_util.h" 42#include "net/base/url_util.h" 43#include "net/http/http_status_code.h" 44#include "ui/base/l10n/l10n_util.h" 45 46#if defined(ENABLE_FULL_PRINTING) && !defined(OS_CHROMEOS) 47#define CLOUD_PRINT_CONNECTOR_UI_AVAILABLE 48#endif 49 50namespace local_discovery { 51 52namespace { 53 54const char kDictionaryKeyServiceName[] = "service_name"; 55const char kDictionaryKeyDisplayName[] = "display_name"; 56const char kDictionaryKeyDescription[] = "description"; 57const char kDictionaryKeyType[] = "type"; 58const char kDictionaryKeyIsWifi[] = "is_wifi"; 59const char kDictionaryKeyID[] = "id"; 60 61const char kKeyPrefixMDns[] = "MDns:"; 62 63#if defined(ENABLE_WIFI_BOOTSTRAPPING) 64const char kKeyPrefixWifi[] = "WiFi:"; 65#endif // ENABLE_WIFI_BOOTSTRAPPING 66 67int g_num_visible = 0; 68 69scoped_ptr<base::DictionaryValue> CreateDeviceInfo( 70 const CloudDeviceListDelegate::Device& description) { 71 scoped_ptr<base::DictionaryValue> return_value(new base::DictionaryValue); 72 73 return_value->SetString(kDictionaryKeyID, description.id); 74 return_value->SetString(kDictionaryKeyDisplayName, description.display_name); 75 return_value->SetString(kDictionaryKeyDescription, description.description); 76 return_value->SetString(kDictionaryKeyType, description.type); 77 78 return return_value.Pass(); 79} 80 81void ReadDevicesList( 82 const std::vector<CloudDeviceListDelegate::Device>& devices, 83 const std::set<std::string>& local_ids, 84 base::ListValue* devices_list) { 85 for (CloudDeviceList::iterator i = devices.begin(); i != devices.end(); i++) { 86 if (local_ids.count(i->id) > 0) { 87 devices_list->Append(CreateDeviceInfo(*i).release()); 88 } 89 } 90 91 for (CloudDeviceList::iterator i = devices.begin(); i != devices.end(); i++) { 92 if (local_ids.count(i->id) == 0) { 93 devices_list->Append(CreateDeviceInfo(*i).release()); 94 } 95 } 96} 97 98} // namespace 99 100LocalDiscoveryUIHandler::LocalDiscoveryUIHandler() 101 : is_visible_(false), 102 failed_list_count_(0), 103 succeded_list_count_(0) { 104#if defined(CLOUD_PRINT_CONNECTOR_UI_AVAILABLE) 105#if !defined(GOOGLE_CHROME_BUILD) && defined(OS_WIN) 106 // On Windows, we need the PDF plugin which is only guaranteed to exist on 107 // Google Chrome builds. Use a command-line switch for Windows non-Google 108 // Chrome builds. 109 cloud_print_connector_ui_enabled_ = 110 CommandLine::ForCurrentProcess()->HasSwitch( 111 switches::kEnableCloudPrintProxy); 112#else 113 // Always enabled for Linux and Google Chrome Windows builds. 114 // Never enabled for Chrome OS, we don't even need to indicate it. 115 cloud_print_connector_ui_enabled_ = true; 116#endif 117#endif // defined(CLOUD_PRINT_CONNECTOR_UI_AVAILABLE) 118} 119 120LocalDiscoveryUIHandler::~LocalDiscoveryUIHandler() { 121 Profile* profile = Profile::FromWebUI(web_ui()); 122 SigninManagerBase* signin_manager = 123 SigninManagerFactory::GetInstance()->GetForProfile(profile); 124 if (signin_manager) 125 signin_manager->RemoveObserver(this); 126 ResetCurrentRegistration(); 127 SetIsVisible(false); 128} 129 130// static 131bool LocalDiscoveryUIHandler::GetHasVisible() { 132 return g_num_visible != 0; 133} 134 135void LocalDiscoveryUIHandler::RegisterMessages() { 136 web_ui()->RegisterMessageCallback("start", base::Bind( 137 &LocalDiscoveryUIHandler::HandleStart, 138 base::Unretained(this))); 139 web_ui()->RegisterMessageCallback("isVisible", base::Bind( 140 &LocalDiscoveryUIHandler::HandleIsVisible, 141 base::Unretained(this))); 142 web_ui()->RegisterMessageCallback("registerDevice", base::Bind( 143 &LocalDiscoveryUIHandler::HandleRegisterDevice, 144 base::Unretained(this))); 145 web_ui()->RegisterMessageCallback("cancelRegistration", base::Bind( 146 &LocalDiscoveryUIHandler::HandleCancelRegistration, 147 base::Unretained(this))); 148 web_ui()->RegisterMessageCallback( 149 "requestDeviceList", 150 base::Bind(&LocalDiscoveryUIHandler::HandleRequestDeviceList, 151 base::Unretained(this))); 152 web_ui()->RegisterMessageCallback("openCloudPrintURL", base::Bind( 153 &LocalDiscoveryUIHandler::HandleOpenCloudPrintURL, 154 base::Unretained(this))); 155 web_ui()->RegisterMessageCallback("showSyncUI", base::Bind( 156 &LocalDiscoveryUIHandler::HandleShowSyncUI, 157 base::Unretained(this))); 158 159 // Cloud print connector related messages 160#if defined(CLOUD_PRINT_CONNECTOR_UI_AVAILABLE) 161 if (cloud_print_connector_ui_enabled_) { 162 web_ui()->RegisterMessageCallback( 163 "showCloudPrintSetupDialog", 164 base::Bind(&LocalDiscoveryUIHandler::ShowCloudPrintSetupDialog, 165 base::Unretained(this))); 166 web_ui()->RegisterMessageCallback( 167 "disableCloudPrintConnector", 168 base::Bind(&LocalDiscoveryUIHandler::HandleDisableCloudPrintConnector, 169 base::Unretained(this))); 170 } 171#endif // defined(CLOUD_PRINT_CONNECTOR_UI_AVAILABLE) 172} 173 174void LocalDiscoveryUIHandler::HandleStart(const base::ListValue* args) { 175 Profile* profile = Profile::FromWebUI(web_ui()); 176 177 // If privet_lister_ is already set, it is a mock used for tests or the result 178 // of a reload. 179 if (!privet_lister_) { 180 service_discovery_client_ = ServiceDiscoverySharedClient::GetInstance(); 181 privet_lister_.reset( 182 new PrivetDeviceListerImpl(service_discovery_client_.get(), this)); 183 privet_http_factory_ = PrivetHTTPAsynchronousFactory::CreateInstance( 184 service_discovery_client_.get(), profile->GetRequestContext()); 185 186 SigninManagerBase* signin_manager = 187 SigninManagerFactory::GetInstance()->GetForProfile(profile); 188 if (signin_manager) 189 signin_manager->AddObserver(this); 190 } 191 192 privet_lister_->Start(); 193 privet_lister_->DiscoverNewDevices(false); 194 195#if defined(CLOUD_PRINT_CONNECTOR_UI_AVAILABLE) 196 StartCloudPrintConnector(); 197#endif 198 199#if defined(ENABLE_WIFI_BOOTSTRAPPING) 200 if (CommandLine::ForCurrentProcess()->HasSwitch( 201 switches::kEnableCloudDevices)) { 202 StartWifiBootstrapping(); 203 } 204#endif 205 206 CheckUserLoggedIn(); 207} 208 209void LocalDiscoveryUIHandler::HandleIsVisible(const base::ListValue* args) { 210 bool is_visible = false; 211 bool rv = args->GetBoolean(0, &is_visible); 212 DCHECK(rv); 213 SetIsVisible(is_visible); 214} 215 216void LocalDiscoveryUIHandler::HandleRegisterDevice( 217 const base::ListValue* args) { 218 std::string device; 219 220 bool rv = args->GetString(0, &device); 221 DCHECK(rv); 222 223 privet_resolution_ = privet_http_factory_->CreatePrivetHTTP( 224 device, 225 device_descriptions_[device].address, 226 base::Bind(&LocalDiscoveryUIHandler::StartRegisterHTTP, 227 base::Unretained(this))); 228 privet_resolution_->Start(); 229} 230 231void LocalDiscoveryUIHandler::HandleCancelRegistration( 232 const base::ListValue* args) { 233 ResetCurrentRegistration(); 234} 235 236void LocalDiscoveryUIHandler::HandleRequestDeviceList( 237 const base::ListValue* args) { 238 failed_list_count_ = 0; 239 succeded_list_count_ = 0; 240 cloud_devices_.clear(); 241 242 cloud_print_printer_list_ = CreateApiFlow(); 243 if (CommandLine::ForCurrentProcess()->HasSwitch( 244 switches::kEnableCloudDevices)) { 245 cloud_device_list_ = CreateApiFlow(); 246 } 247 248 if (cloud_print_printer_list_) { 249 cloud_print_printer_list_->Start( 250 make_scoped_ptr<GCDApiFlow::Request>(new CloudPrintPrinterList(this))); 251 } 252 if (cloud_device_list_) { 253 cloud_device_list_->Start( 254 make_scoped_ptr<GCDApiFlow::Request>(new CloudDeviceList(this))); 255 } 256 CheckListingDone(); 257} 258 259void LocalDiscoveryUIHandler::HandleOpenCloudPrintURL( 260 const base::ListValue* args) { 261 std::string id; 262 bool rv = args->GetString(0, &id); 263 DCHECK(rv); 264 265 Browser* browser = chrome::FindBrowserWithWebContents( 266 web_ui()->GetWebContents()); 267 DCHECK(browser); 268 269 chrome::AddSelectedTabWithURL(browser, 270 cloud_devices::GetCloudPrintManageDeviceURL(id), 271 content::PAGE_TRANSITION_FROM_API); 272} 273 274void LocalDiscoveryUIHandler::HandleShowSyncUI( 275 const base::ListValue* args) { 276 Browser* browser = chrome::FindBrowserWithWebContents( 277 web_ui()->GetWebContents()); 278 DCHECK(browser); 279 280 GURL url(signin::GetPromoURL(signin::SOURCE_DEVICES_PAGE, 281 true)); // auto close after success. 282 283 browser->OpenURL( 284 content::OpenURLParams(url, content::Referrer(), SINGLETON_TAB, 285 content::PAGE_TRANSITION_AUTO_BOOKMARK, false)); 286} 287 288void LocalDiscoveryUIHandler::StartRegisterHTTP( 289 scoped_ptr<PrivetHTTPClient> http_client) { 290 current_http_client_ = PrivetV1HTTPClient::CreateDefault(http_client.Pass()); 291 292 std::string user = GetSyncAccount(); 293 294 if (!current_http_client_) { 295 SendRegisterError(); 296 return; 297 } 298 299 current_register_operation_ = 300 current_http_client_->CreateRegisterOperation(user, this); 301 current_register_operation_->Start(); 302} 303 304void LocalDiscoveryUIHandler::OnPrivetRegisterClaimToken( 305 PrivetRegisterOperation* operation, 306 const std::string& token, 307 const GURL& url) { 308 web_ui()->CallJavascriptFunction( 309 "local_discovery.onRegistrationConfirmedOnPrinter"); 310 if (device_descriptions_.count(current_http_client_->GetName()) == 0) { 311 SendRegisterError(); 312 return; 313 } 314 315 confirm_api_call_flow_ = CreateApiFlow(); 316 if (!confirm_api_call_flow_) { 317 SendRegisterError(); 318 return; 319 } 320 confirm_api_call_flow_->Start( 321 make_scoped_ptr<GCDApiFlow::Request>(new PrivetConfirmApiCallFlow( 322 token, 323 base::Bind(&LocalDiscoveryUIHandler::OnConfirmDone, 324 base::Unretained(this))))); 325} 326 327void LocalDiscoveryUIHandler::OnPrivetRegisterError( 328 PrivetRegisterOperation* operation, 329 const std::string& action, 330 PrivetRegisterOperation::FailureReason reason, 331 int printer_http_code, 332 const base::DictionaryValue* json) { 333 std::string error; 334 335 if (reason == PrivetRegisterOperation::FAILURE_JSON_ERROR && 336 json->GetString(kPrivetKeyError, &error)) { 337 if (error == kPrivetErrorTimeout) { 338 web_ui()->CallJavascriptFunction( 339 "local_discovery.onRegistrationTimeout"); 340 return; 341 } else if (error == kPrivetErrorCancel) { 342 web_ui()->CallJavascriptFunction( 343 "local_discovery.onRegistrationCanceledPrinter"); 344 return; 345 } 346 } 347 348 SendRegisterError(); 349} 350 351void LocalDiscoveryUIHandler::OnPrivetRegisterDone( 352 PrivetRegisterOperation* operation, 353 const std::string& device_id) { 354 std::string name = operation->GetHTTPClient()->GetName(); 355 356 current_register_operation_.reset(); 357 current_http_client_.reset(); 358 359 // HACK(noamsml): Generate network traffic so the Windows firewall doesn't 360 // block the printer's announcement. 361 privet_lister_->DiscoverNewDevices(false); 362 363 DeviceDescriptionMap::iterator found = device_descriptions_.find(name); 364 365 if (found == device_descriptions_.end()) { 366 // TODO(noamsml): Handle the case where a printer's record is not present at 367 // the end of registration. 368 SendRegisterError(); 369 return; 370 } 371 372 SendRegisterDone(found->first, found->second); 373} 374 375void LocalDiscoveryUIHandler::OnConfirmDone(GCDApiFlow::Status status) { 376 if (status == GCDApiFlow::SUCCESS) { 377 confirm_api_call_flow_.reset(); 378 current_register_operation_->CompleteRegistration(); 379 } else { 380 SendRegisterError(); 381 } 382} 383 384void LocalDiscoveryUIHandler::DeviceChanged( 385 bool added, 386 const std::string& name, 387 const DeviceDescription& description) { 388 device_descriptions_[name] = description; 389 390 base::DictionaryValue info; 391 392 base::StringValue service_key(kKeyPrefixMDns + name); 393 394 if (description.id.empty()) { 395 info.SetString(kDictionaryKeyServiceName, name); 396 info.SetString(kDictionaryKeyDisplayName, description.name); 397 info.SetString(kDictionaryKeyDescription, description.description); 398 info.SetString(kDictionaryKeyType, description.type); 399 info.SetBoolean(kDictionaryKeyIsWifi, false); 400 401 web_ui()->CallJavascriptFunction( 402 "local_discovery.onUnregisteredDeviceUpdate", service_key, info); 403 } else { 404 scoped_ptr<base::Value> null_value(base::Value::CreateNullValue()); 405 406 web_ui()->CallJavascriptFunction( 407 "local_discovery.onUnregisteredDeviceUpdate", service_key, *null_value); 408 } 409} 410 411void LocalDiscoveryUIHandler::DeviceRemoved(const std::string& name) { 412 device_descriptions_.erase(name); 413 scoped_ptr<base::Value> null_value(base::Value::CreateNullValue()); 414 base::StringValue name_value(kKeyPrefixMDns + name); 415 416 web_ui()->CallJavascriptFunction("local_discovery.onUnregisteredDeviceUpdate", 417 name_value, *null_value); 418} 419 420void LocalDiscoveryUIHandler::DeviceCacheFlushed() { 421 web_ui()->CallJavascriptFunction("local_discovery.onDeviceCacheFlushed"); 422 privet_lister_->DiscoverNewDevices(false); 423} 424 425void LocalDiscoveryUIHandler::OnDeviceListReady( 426 const std::vector<Device>& devices) { 427 cloud_devices_.insert(cloud_devices_.end(), devices.begin(), devices.end()); 428 ++succeded_list_count_; 429 CheckListingDone(); 430} 431 432void LocalDiscoveryUIHandler::OnDeviceListUnavailable() { 433 ++failed_list_count_; 434 CheckListingDone(); 435} 436 437void LocalDiscoveryUIHandler::GoogleSigninSucceeded( 438 const std::string& username, 439 const std::string& password) { 440 CheckUserLoggedIn(); 441} 442 443void LocalDiscoveryUIHandler::GoogleSignedOut(const std::string& username) { 444 CheckUserLoggedIn(); 445} 446 447void LocalDiscoveryUIHandler::SendRegisterError() { 448 web_ui()->CallJavascriptFunction("local_discovery.onRegistrationFailed"); 449} 450 451void LocalDiscoveryUIHandler::SendRegisterDone( 452 const std::string& service_name, const DeviceDescription& device) { 453 base::DictionaryValue printer_value; 454 455 printer_value.SetString(kDictionaryKeyID, device.id); 456 printer_value.SetString(kDictionaryKeyDisplayName, device.name); 457 printer_value.SetString(kDictionaryKeyDescription, device.description); 458 printer_value.SetString(kDictionaryKeyServiceName, service_name); 459 460 web_ui()->CallJavascriptFunction("local_discovery.onRegistrationSuccess", 461 printer_value); 462} 463 464void LocalDiscoveryUIHandler::SetIsVisible(bool visible) { 465 if (visible != is_visible_) { 466 g_num_visible += visible ? 1 : -1; 467 is_visible_ = visible; 468 } 469} 470 471std::string LocalDiscoveryUIHandler::GetSyncAccount() { 472 Profile* profile = Profile::FromWebUI(web_ui()); 473 SigninManagerBase* signin_manager = 474 SigninManagerFactory::GetForProfileIfExists(profile); 475 476 if (!signin_manager) { 477 return ""; 478 } 479 480 return signin_manager->GetAuthenticatedUsername(); 481} 482 483// TODO(noamsml): Create master object for registration flow. 484void LocalDiscoveryUIHandler::ResetCurrentRegistration() { 485 if (current_register_operation_) { 486 current_register_operation_->Cancel(); 487 current_register_operation_.reset(); 488 } 489 490 confirm_api_call_flow_.reset(); 491 privet_resolution_.reset(); 492 current_http_client_.reset(); 493} 494 495void LocalDiscoveryUIHandler::CheckUserLoggedIn() { 496 base::FundamentalValue logged_in_value(!GetSyncAccount().empty()); 497 web_ui()->CallJavascriptFunction("local_discovery.setUserLoggedIn", 498 logged_in_value); 499} 500 501void LocalDiscoveryUIHandler::CheckListingDone() { 502 int started = 0; 503 if (cloud_print_printer_list_) 504 ++started; 505 if (cloud_device_list_) 506 ++started; 507 508 if (started > failed_list_count_ + succeded_list_count_) 509 return; 510 511 if (succeded_list_count_ <= 0) { 512 web_ui()->CallJavascriptFunction( 513 "local_discovery.onCloudDeviceListUnavailable"); 514 return; 515 } 516 517 base::ListValue devices_list; 518 std::set<std::string> local_ids; 519 520 for (DeviceDescriptionMap::iterator i = device_descriptions_.begin(); 521 i != device_descriptions_.end(); i++) { 522 local_ids.insert(i->second.id); 523 } 524 525 ReadDevicesList(cloud_devices_, local_ids, &devices_list); 526 527 web_ui()->CallJavascriptFunction( 528 "local_discovery.onCloudDeviceListAvailable", devices_list); 529 cloud_print_printer_list_.reset(); 530 cloud_device_list_.reset(); 531} 532 533scoped_ptr<GCDApiFlow> LocalDiscoveryUIHandler::CreateApiFlow() { 534 Profile* profile = Profile::FromWebUI(web_ui()); 535 if (!profile) 536 return scoped_ptr<GCDApiFlow>(); 537 ProfileOAuth2TokenService* token_service = 538 ProfileOAuth2TokenServiceFactory::GetForProfile(profile); 539 if (!token_service) 540 return scoped_ptr<GCDApiFlow>(); 541 SigninManagerBase* signin_manager = 542 SigninManagerFactory::GetInstance()->GetForProfile(profile); 543 if (!signin_manager) 544 return scoped_ptr<GCDApiFlow>(); 545 return GCDApiFlow::Create(profile->GetRequestContext(), 546 token_service, 547 signin_manager->GetAuthenticatedAccountId()); 548} 549 550#if defined(CLOUD_PRINT_CONNECTOR_UI_AVAILABLE) 551void LocalDiscoveryUIHandler::StartCloudPrintConnector() { 552 Profile* profile = Profile::FromWebUI(web_ui()); 553 554 base::Closure cloud_print_callback = base::Bind( 555 &LocalDiscoveryUIHandler::OnCloudPrintPrefsChanged, 556 base::Unretained(this)); 557 558 if (cloud_print_connector_email_.GetPrefName().empty()) { 559 cloud_print_connector_email_.Init( 560 prefs::kCloudPrintEmail, profile->GetPrefs(), cloud_print_callback); 561 } 562 563 if (cloud_print_connector_enabled_.GetPrefName().empty()) { 564 cloud_print_connector_enabled_.Init( 565 prefs::kCloudPrintProxyEnabled, profile->GetPrefs(), 566 cloud_print_callback); 567 } 568 569 if (cloud_print_connector_ui_enabled_) { 570 SetupCloudPrintConnectorSection(); 571 RefreshCloudPrintStatusFromService(); 572 } else { 573 RemoveCloudPrintConnectorSection(); 574 } 575} 576 577void LocalDiscoveryUIHandler::OnCloudPrintPrefsChanged() { 578 if (cloud_print_connector_ui_enabled_) 579 SetupCloudPrintConnectorSection(); 580} 581 582void LocalDiscoveryUIHandler::ShowCloudPrintSetupDialog( 583 const base::ListValue* args) { 584 content::RecordAction( 585 base::UserMetricsAction("Options_EnableCloudPrintProxy")); 586 // Open the connector enable page in the current tab. 587 Profile* profile = Profile::FromWebUI(web_ui()); 588 content::OpenURLParams params( 589 cloud_devices::GetCloudPrintEnableURL( 590 CloudPrintProxyServiceFactory::GetForProfile(profile)->proxy_id()), 591 content::Referrer(), 592 CURRENT_TAB, 593 content::PAGE_TRANSITION_LINK, 594 false); 595 web_ui()->GetWebContents()->OpenURL(params); 596} 597 598void LocalDiscoveryUIHandler::HandleDisableCloudPrintConnector( 599 const base::ListValue* args) { 600 content::RecordAction( 601 base::UserMetricsAction("Options_DisableCloudPrintProxy")); 602 CloudPrintProxyServiceFactory::GetForProfile(Profile::FromWebUI(web_ui()))-> 603 DisableForUser(); 604} 605 606void LocalDiscoveryUIHandler::SetupCloudPrintConnectorSection() { 607 Profile* profile = Profile::FromWebUI(web_ui()); 608 609 if (!CloudPrintProxyServiceFactory::GetForProfile(profile)) { 610 cloud_print_connector_ui_enabled_ = false; 611 RemoveCloudPrintConnectorSection(); 612 return; 613 } 614 615 bool cloud_print_connector_allowed = 616 !cloud_print_connector_enabled_.IsManaged() || 617 cloud_print_connector_enabled_.GetValue(); 618 base::FundamentalValue allowed(cloud_print_connector_allowed); 619 620 std::string email; 621 if (profile->GetPrefs()->HasPrefPath(prefs::kCloudPrintEmail) && 622 cloud_print_connector_allowed) { 623 email = profile->GetPrefs()->GetString(prefs::kCloudPrintEmail); 624 } 625 base::FundamentalValue disabled(email.empty()); 626 627 base::string16 label_str; 628 if (email.empty()) { 629 label_str = l10n_util::GetStringFUTF16( 630 IDS_LOCAL_DISCOVERY_CLOUD_PRINT_CONNECTOR_DISABLED_LABEL, 631 l10n_util::GetStringUTF16(IDS_GOOGLE_CLOUD_PRINT)); 632 } else { 633 label_str = l10n_util::GetStringFUTF16( 634 IDS_OPTIONS_CLOUD_PRINT_CONNECTOR_ENABLED_LABEL, 635 l10n_util::GetStringUTF16(IDS_GOOGLE_CLOUD_PRINT), 636 base::UTF8ToUTF16(email)); 637 } 638 base::StringValue label(label_str); 639 640 web_ui()->CallJavascriptFunction( 641 "local_discovery.setupCloudPrintConnectorSection", disabled, label, 642 allowed); 643} 644 645void LocalDiscoveryUIHandler::RemoveCloudPrintConnectorSection() { 646 web_ui()->CallJavascriptFunction( 647 "local_discovery.removeCloudPrintConnectorSection"); 648} 649 650void LocalDiscoveryUIHandler::RefreshCloudPrintStatusFromService() { 651 if (cloud_print_connector_ui_enabled_) 652 CloudPrintProxyServiceFactory::GetForProfile(Profile::FromWebUI(web_ui()))-> 653 RefreshStatusFromService(); 654} 655 656#endif // cloud print connector option stuff 657 658#if defined(ENABLE_WIFI_BOOTSTRAPPING) 659 660void LocalDiscoveryUIHandler::StartWifiBootstrapping() { 661 // Since LocalDiscoveryUIHandler isn't destroyed every time the page is 662 // refreshed, reset bootstrapping_device_lister_ so it's destoryed before 663 // wifi_manager_ is. 664 bootstrapping_device_lister_.reset(); 665 666 wifi_manager_ = wifi::WifiManager::Create(); 667 bootstrapping_device_lister_.reset(new wifi::BootstrappingDeviceLister( 668 wifi_manager_.get(), 669 base::Bind(&LocalDiscoveryUIHandler::OnBootstrappingDeviceChanged, 670 base::Unretained(this)))); 671 672 wifi_manager_->Start(); 673 bootstrapping_device_lister_->Start(); 674 wifi_manager_->RequestScan(); 675} 676 677void LocalDiscoveryUIHandler::OnBootstrappingDeviceChanged( 678 bool available, 679 const wifi::BootstrappingDeviceDescription& description) { 680 base::DictionaryValue info; 681 682 base::StringValue service_key(kKeyPrefixWifi + description.device_ssid); 683 684 if (available) { 685 info.SetString(kDictionaryKeyServiceName, description.device_ssid); 686 info.SetString(kDictionaryKeyDisplayName, description.device_name); 687 info.SetString(kDictionaryKeyDescription, std::string()); 688 info.SetString(kDictionaryKeyType, description.device_kind); 689 info.SetBoolean(kDictionaryKeyIsWifi, true); 690 691 web_ui()->CallJavascriptFunction( 692 "local_discovery.onUnregisteredDeviceUpdate", service_key, info); 693 } else { 694 scoped_ptr<base::Value> null_value(base::Value::CreateNullValue()); 695 696 web_ui()->CallJavascriptFunction( 697 "local_discovery.onUnregisteredDeviceUpdate", service_key, *null_value); 698 } 699} 700 701#endif // ENABLE_WIFI_BOOTSTRAPPING 702 703} // namespace local_discovery 704