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