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