local_discovery_ui_handler.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
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_ = 184 PrivetHTTPAsynchronousFactory::CreateInstance( 185 service_discovery_client_.get(), profile->GetRequestContext()); 186 187 SigninManagerBase* signin_manager = 188 SigninManagerFactory::GetInstance()->GetForProfile(profile); 189 if (signin_manager) 190 signin_manager->AddObserver(this); 191 } 192 193 privet_lister_->Start(); 194 privet_lister_->DiscoverNewDevices(false); 195 196#if defined(CLOUD_PRINT_CONNECTOR_UI_AVAILABLE) 197 StartCloudPrintConnector(); 198#endif 199 200#if defined(ENABLE_WIFI_BOOTSTRAPPING) 201 if (CommandLine::ForCurrentProcess()->HasSwitch( 202 switches::kEnableCloudDevices)) { 203 StartWifiBootstrapping(); 204 } 205#endif 206 207 CheckUserLoggedIn(); 208} 209 210void LocalDiscoveryUIHandler::HandleIsVisible(const base::ListValue* args) { 211 bool is_visible = false; 212 bool rv = args->GetBoolean(0, &is_visible); 213 DCHECK(rv); 214 SetIsVisible(is_visible); 215} 216 217void LocalDiscoveryUIHandler::HandleRegisterDevice( 218 const base::ListValue* args) { 219 std::string device; 220 221 bool rv = args->GetString(0, &device); 222 DCHECK(rv); 223 224 privet_resolution_ = privet_http_factory_->CreatePrivetHTTP( 225 device, 226 device_descriptions_[device].address, 227 base::Bind(&LocalDiscoveryUIHandler::StartRegisterHTTP, 228 base::Unretained(this))); 229 privet_resolution_->Start(); 230} 231 232void LocalDiscoveryUIHandler::HandleCancelRegistration( 233 const base::ListValue* args) { 234 ResetCurrentRegistration(); 235} 236 237void LocalDiscoveryUIHandler::HandleRequestDeviceList( 238 const base::ListValue* args) { 239 failed_list_count_ = 0; 240 succeded_list_count_ = 0; 241 cloud_devices_.clear(); 242 243 cloud_print_printer_list_ = CreateApiFlow( 244 scoped_ptr<GCDApiFlow::Request>(new CloudPrintPrinterList(this))); 245 if (CommandLine::ForCurrentProcess()->HasSwitch( 246 switches::kEnableCloudDevices)) { 247 cloud_device_list_ = CreateApiFlow( 248 scoped_ptr<GCDApiFlow::Request>(new CloudDeviceList(this))); 249 } 250 251 if (cloud_print_printer_list_) 252 cloud_print_printer_list_->Start(); 253 if (cloud_device_list_) 254 cloud_device_list_->Start(); 255 CheckListingDone(); 256} 257 258void LocalDiscoveryUIHandler::HandleOpenCloudPrintURL( 259 const base::ListValue* args) { 260 std::string id; 261 bool rv = args->GetString(0, &id); 262 DCHECK(rv); 263 264 Browser* browser = chrome::FindBrowserWithWebContents( 265 web_ui()->GetWebContents()); 266 DCHECK(browser); 267 268 chrome::AddSelectedTabWithURL(browser, 269 cloud_devices::GetCloudPrintManageDeviceURL(id), 270 content::PAGE_TRANSITION_FROM_API); 271} 272 273void LocalDiscoveryUIHandler::HandleShowSyncUI( 274 const base::ListValue* args) { 275 Browser* browser = chrome::FindBrowserWithWebContents( 276 web_ui()->GetWebContents()); 277 DCHECK(browser); 278 279 GURL url(signin::GetPromoURL(signin::SOURCE_DEVICES_PAGE, 280 true)); // auto close after success. 281 282 browser->OpenURL( 283 content::OpenURLParams(url, content::Referrer(), SINGLETON_TAB, 284 content::PAGE_TRANSITION_AUTO_BOOKMARK, false)); 285} 286 287void LocalDiscoveryUIHandler::StartRegisterHTTP( 288 scoped_ptr<PrivetHTTPClient> http_client) { 289 current_http_client_.swap(http_client); 290 291 std::string user = GetSyncAccount(); 292 293 if (!current_http_client_) { 294 SendRegisterError(); 295 return; 296 } 297 298 current_register_operation_ = 299 current_http_client_->CreateRegisterOperation(user, this); 300 current_register_operation_->Start(); 301} 302 303void LocalDiscoveryUIHandler::OnPrivetRegisterClaimToken( 304 PrivetRegisterOperation* operation, 305 const std::string& token, 306 const GURL& url) { 307 web_ui()->CallJavascriptFunction( 308 "local_discovery.onRegistrationConfirmedOnPrinter"); 309 if (device_descriptions_.count(current_http_client_->GetName()) == 0) { 310 SendRegisterError(); 311 return; 312 } 313 314 confirm_api_call_flow_ = CreateApiFlow( 315 scoped_ptr<GCDApiFlow::Request>(new PrivetConfirmApiCallFlow( 316 token, 317 base::Bind(&LocalDiscoveryUIHandler::OnConfirmDone, 318 base::Unretained(this))))); 319 if (!confirm_api_call_flow_) { 320 SendRegisterError(); 321 return; 322 } 323 confirm_api_call_flow_->Start(); 324} 325 326void LocalDiscoveryUIHandler::OnPrivetRegisterError( 327 PrivetRegisterOperation* operation, 328 const std::string& action, 329 PrivetRegisterOperation::FailureReason reason, 330 int printer_http_code, 331 const base::DictionaryValue* json) { 332 std::string error; 333 334 if (reason == PrivetRegisterOperation::FAILURE_JSON_ERROR && 335 json->GetString(kPrivetKeyError, &error)) { 336 if (error == kPrivetErrorTimeout) { 337 web_ui()->CallJavascriptFunction( 338 "local_discovery.onRegistrationTimeout"); 339 return; 340 } else if (error == kPrivetErrorCancel) { 341 web_ui()->CallJavascriptFunction( 342 "local_discovery.onRegistrationCanceledPrinter"); 343 return; 344 } 345 } 346 347 SendRegisterError(); 348} 349 350void LocalDiscoveryUIHandler::OnPrivetRegisterDone( 351 PrivetRegisterOperation* operation, 352 const std::string& device_id) { 353 std::string name = operation->GetHTTPClient()->GetName(); 354 355 current_register_operation_.reset(); 356 current_http_client_.reset(); 357 358 // HACK(noamsml): Generate network traffic so the Windows firewall doesn't 359 // block the printer's announcement. 360 privet_lister_->DiscoverNewDevices(false); 361 362 DeviceDescriptionMap::iterator found = device_descriptions_.find(name); 363 364 if (found == device_descriptions_.end()) { 365 // TODO(noamsml): Handle the case where a printer's record is not present at 366 // the end of registration. 367 SendRegisterError(); 368 return; 369 } 370 371 SendRegisterDone(found->first, found->second); 372} 373 374void LocalDiscoveryUIHandler::OnConfirmDone(GCDApiFlow::Status status) { 375 if (status == GCDApiFlow::SUCCESS) { 376 confirm_api_call_flow_.reset(); 377 current_register_operation_->CompleteRegistration(); 378 } else { 379 SendRegisterError(); 380 } 381} 382 383void LocalDiscoveryUIHandler::DeviceChanged( 384 bool added, 385 const std::string& name, 386 const DeviceDescription& description) { 387 device_descriptions_[name] = description; 388 389 base::DictionaryValue info; 390 391 base::StringValue service_key(kKeyPrefixMDns + name); 392 393 if (description.id.empty()) { 394 info.SetString(kDictionaryKeyServiceName, name); 395 info.SetString(kDictionaryKeyDisplayName, description.name); 396 info.SetString(kDictionaryKeyDescription, description.description); 397 info.SetString(kDictionaryKeyType, description.type); 398 info.SetBoolean(kDictionaryKeyIsWifi, false); 399 400 web_ui()->CallJavascriptFunction( 401 "local_discovery.onUnregisteredDeviceUpdate", service_key, info); 402 } else { 403 scoped_ptr<base::Value> null_value(base::Value::CreateNullValue()); 404 405 web_ui()->CallJavascriptFunction( 406 "local_discovery.onUnregisteredDeviceUpdate", service_key, *null_value); 407 } 408} 409 410void LocalDiscoveryUIHandler::DeviceRemoved(const std::string& name) { 411 device_descriptions_.erase(name); 412 scoped_ptr<base::Value> null_value(base::Value::CreateNullValue()); 413 base::StringValue name_value(kKeyPrefixMDns + name); 414 415 web_ui()->CallJavascriptFunction("local_discovery.onUnregisteredDeviceUpdate", 416 name_value, *null_value); 417} 418 419void LocalDiscoveryUIHandler::DeviceCacheFlushed() { 420 web_ui()->CallJavascriptFunction("local_discovery.onDeviceCacheFlushed"); 421 privet_lister_->DiscoverNewDevices(false); 422} 423 424void LocalDiscoveryUIHandler::OnDeviceListReady( 425 const std::vector<Device>& devices) { 426 cloud_devices_.insert(cloud_devices_.end(), devices.begin(), devices.end()); 427 ++succeded_list_count_; 428 CheckListingDone(); 429} 430 431void LocalDiscoveryUIHandler::OnDeviceListUnavailable() { 432 ++failed_list_count_; 433 CheckListingDone(); 434} 435 436void LocalDiscoveryUIHandler::GoogleSigninSucceeded( 437 const std::string& username, 438 const std::string& password) { 439 CheckUserLoggedIn(); 440} 441 442void LocalDiscoveryUIHandler::GoogleSignedOut(const std::string& username) { 443 CheckUserLoggedIn(); 444} 445 446void LocalDiscoveryUIHandler::SendRegisterError() { 447 web_ui()->CallJavascriptFunction("local_discovery.onRegistrationFailed"); 448} 449 450void LocalDiscoveryUIHandler::SendRegisterDone( 451 const std::string& service_name, const DeviceDescription& device) { 452 base::DictionaryValue printer_value; 453 454 printer_value.SetString(kDictionaryKeyID, device.id); 455 printer_value.SetString(kDictionaryKeyDisplayName, device.name); 456 printer_value.SetString(kDictionaryKeyDescription, device.description); 457 printer_value.SetString(kDictionaryKeyServiceName, service_name); 458 459 web_ui()->CallJavascriptFunction("local_discovery.onRegistrationSuccess", 460 printer_value); 461} 462 463void LocalDiscoveryUIHandler::SetIsVisible(bool visible) { 464 if (visible != is_visible_) { 465 g_num_visible += visible ? 1 : -1; 466 is_visible_ = visible; 467 } 468} 469 470std::string LocalDiscoveryUIHandler::GetSyncAccount() { 471 Profile* profile = Profile::FromWebUI(web_ui()); 472 SigninManagerBase* signin_manager = 473 SigninManagerFactory::GetForProfileIfExists(profile); 474 475 if (!signin_manager) { 476 return ""; 477 } 478 479 return signin_manager->GetAuthenticatedUsername(); 480} 481 482// TODO(noamsml): Create master object for registration flow. 483void LocalDiscoveryUIHandler::ResetCurrentRegistration() { 484 if (current_register_operation_.get()) { 485 current_register_operation_->Cancel(); 486 current_register_operation_.reset(); 487 } 488 489 confirm_api_call_flow_.reset(); 490 privet_resolution_.reset(); 491 current_http_client_.reset(); 492} 493 494void LocalDiscoveryUIHandler::CheckUserLoggedIn() { 495 base::FundamentalValue logged_in_value(!GetSyncAccount().empty()); 496 web_ui()->CallJavascriptFunction("local_discovery.setUserLoggedIn", 497 logged_in_value); 498} 499 500void LocalDiscoveryUIHandler::CheckListingDone() { 501 int started = 0; 502 if (cloud_print_printer_list_) 503 ++started; 504 if (cloud_device_list_) 505 ++started; 506 507 if (started > failed_list_count_ + succeded_list_count_) 508 return; 509 510 if (succeded_list_count_ <= 0) { 511 web_ui()->CallJavascriptFunction( 512 "local_discovery.onCloudDeviceListUnavailable"); 513 return; 514 } 515 516 base::ListValue devices_list; 517 std::set<std::string> local_ids; 518 519 for (DeviceDescriptionMap::iterator i = device_descriptions_.begin(); 520 i != device_descriptions_.end(); i++) { 521 local_ids.insert(i->second.id); 522 } 523 524 ReadDevicesList(cloud_devices_, local_ids, &devices_list); 525 526 web_ui()->CallJavascriptFunction( 527 "local_discovery.onCloudDeviceListAvailable", devices_list); 528 cloud_print_printer_list_.reset(); 529 cloud_device_list_.reset(); 530} 531 532scoped_ptr<GCDApiFlow> LocalDiscoveryUIHandler::CreateApiFlow( 533 scoped_ptr<GCDApiFlow::Request> request) { 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 make_scoped_ptr( 546 new GCDApiFlow(profile->GetRequestContext(), 547 token_service, 548 signin_manager->GetAuthenticatedAccountId(), 549 request.Pass())); 550} 551 552#if defined(CLOUD_PRINT_CONNECTOR_UI_AVAILABLE) 553void LocalDiscoveryUIHandler::StartCloudPrintConnector() { 554 Profile* profile = Profile::FromWebUI(web_ui()); 555 556 base::Closure cloud_print_callback = base::Bind( 557 &LocalDiscoveryUIHandler::OnCloudPrintPrefsChanged, 558 base::Unretained(this)); 559 560 if (cloud_print_connector_email_.GetPrefName().empty()) { 561 cloud_print_connector_email_.Init( 562 prefs::kCloudPrintEmail, profile->GetPrefs(), cloud_print_callback); 563 } 564 565 if (cloud_print_connector_enabled_.GetPrefName().empty()) { 566 cloud_print_connector_enabled_.Init( 567 prefs::kCloudPrintProxyEnabled, profile->GetPrefs(), 568 cloud_print_callback); 569 } 570 571 if (cloud_print_connector_ui_enabled_) { 572 SetupCloudPrintConnectorSection(); 573 RefreshCloudPrintStatusFromService(); 574 } else { 575 RemoveCloudPrintConnectorSection(); 576 } 577} 578 579void LocalDiscoveryUIHandler::OnCloudPrintPrefsChanged() { 580 if (cloud_print_connector_ui_enabled_) 581 SetupCloudPrintConnectorSection(); 582} 583 584void LocalDiscoveryUIHandler::ShowCloudPrintSetupDialog( 585 const base::ListValue* args) { 586 content::RecordAction( 587 base::UserMetricsAction("Options_EnableCloudPrintProxy")); 588 // Open the connector enable page in the current tab. 589 Profile* profile = Profile::FromWebUI(web_ui()); 590 content::OpenURLParams params( 591 cloud_devices::GetCloudPrintEnableURL( 592 CloudPrintProxyServiceFactory::GetForProfile(profile)->proxy_id()), 593 content::Referrer(), 594 CURRENT_TAB, 595 content::PAGE_TRANSITION_LINK, 596 false); 597 web_ui()->GetWebContents()->OpenURL(params); 598} 599 600void LocalDiscoveryUIHandler::HandleDisableCloudPrintConnector( 601 const base::ListValue* args) { 602 content::RecordAction( 603 base::UserMetricsAction("Options_DisableCloudPrintProxy")); 604 CloudPrintProxyServiceFactory::GetForProfile(Profile::FromWebUI(web_ui()))-> 605 DisableForUser(); 606} 607 608void LocalDiscoveryUIHandler::SetupCloudPrintConnectorSection() { 609 Profile* profile = Profile::FromWebUI(web_ui()); 610 611 if (!CloudPrintProxyServiceFactory::GetForProfile(profile)) { 612 cloud_print_connector_ui_enabled_ = false; 613 RemoveCloudPrintConnectorSection(); 614 return; 615 } 616 617 bool cloud_print_connector_allowed = 618 !cloud_print_connector_enabled_.IsManaged() || 619 cloud_print_connector_enabled_.GetValue(); 620 base::FundamentalValue allowed(cloud_print_connector_allowed); 621 622 std::string email; 623 if (profile->GetPrefs()->HasPrefPath(prefs::kCloudPrintEmail) && 624 cloud_print_connector_allowed) { 625 email = profile->GetPrefs()->GetString(prefs::kCloudPrintEmail); 626 } 627 base::FundamentalValue disabled(email.empty()); 628 629 base::string16 label_str; 630 if (email.empty()) { 631 label_str = l10n_util::GetStringFUTF16( 632 IDS_LOCAL_DISCOVERY_CLOUD_PRINT_CONNECTOR_DISABLED_LABEL, 633 l10n_util::GetStringUTF16(IDS_GOOGLE_CLOUD_PRINT)); 634 } else { 635 label_str = l10n_util::GetStringFUTF16( 636 IDS_OPTIONS_CLOUD_PRINT_CONNECTOR_ENABLED_LABEL, 637 l10n_util::GetStringUTF16(IDS_GOOGLE_CLOUD_PRINT), 638 base::UTF8ToUTF16(email)); 639 } 640 base::StringValue label(label_str); 641 642 web_ui()->CallJavascriptFunction( 643 "local_discovery.setupCloudPrintConnectorSection", disabled, label, 644 allowed); 645} 646 647void LocalDiscoveryUIHandler::RemoveCloudPrintConnectorSection() { 648 web_ui()->CallJavascriptFunction( 649 "local_discovery.removeCloudPrintConnectorSection"); 650} 651 652void LocalDiscoveryUIHandler::RefreshCloudPrintStatusFromService() { 653 if (cloud_print_connector_ui_enabled_) 654 CloudPrintProxyServiceFactory::GetForProfile(Profile::FromWebUI(web_ui()))-> 655 RefreshStatusFromService(); 656} 657 658#endif // cloud print connector option stuff 659 660#if defined(ENABLE_WIFI_BOOTSTRAPPING) 661 662void LocalDiscoveryUIHandler::StartWifiBootstrapping() { 663 // Since LocalDiscoveryUIHandler isn't destroyed every time the page is 664 // refreshed, reset bootstrapping_device_lister_ so it's destoryed before 665 // wifi_manager_ is. 666 bootstrapping_device_lister_.reset(); 667 668 wifi_manager_ = wifi::WifiManager::Create(); 669 bootstrapping_device_lister_.reset(new wifi::BootstrappingDeviceLister( 670 wifi_manager_.get(), 671 base::Bind(&LocalDiscoveryUIHandler::OnBootstrappingDeviceChanged, 672 base::Unretained(this)))); 673 674 wifi_manager_->Start(); 675 bootstrapping_device_lister_->Start(); 676 wifi_manager_->RequestScan(); 677} 678 679void LocalDiscoveryUIHandler::OnBootstrappingDeviceChanged( 680 bool available, 681 const wifi::BootstrappingDeviceDescription& description) { 682 base::DictionaryValue info; 683 684 base::StringValue service_key(kKeyPrefixWifi + description.device_ssid); 685 686 if (available) { 687 info.SetString(kDictionaryKeyServiceName, description.device_ssid); 688 info.SetString(kDictionaryKeyDisplayName, description.device_name); 689 info.SetString(kDictionaryKeyDescription, std::string()); 690 info.SetString(kDictionaryKeyType, description.device_kind); 691 info.SetBoolean(kDictionaryKeyIsWifi, true); 692 693 web_ui()->CallJavascriptFunction( 694 "local_discovery.onUnregisteredDeviceUpdate", service_key, info); 695 } else { 696 scoped_ptr<base::Value> null_value(base::Value::CreateNullValue()); 697 698 web_ui()->CallJavascriptFunction( 699 "local_discovery.onUnregisteredDeviceUpdate", service_key, *null_value); 700 } 701} 702 703#endif // ENABLE_WIFI_BOOTSTRAPPING 704 705} // namespace local_discovery 706