1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/ui/webui/help/help_handler.h"
6
7#include <string>
8
9#include "base/basictypes.h"
10#include "base/bind.h"
11#include "base/bind_helpers.h"
12#include "base/command_line.h"
13#include "base/strings/string16.h"
14#include "base/strings/string_number_conversions.h"
15#include "base/strings/utf_string_conversions.h"
16#include "base/values.h"
17#include "chrome/browser/browser_process.h"
18#include "chrome/browser/chrome_notification_types.h"
19#include "chrome/browser/ui/browser.h"
20#include "chrome/browser/ui/browser_commands.h"
21#include "chrome/browser/ui/browser_finder.h"
22#include "chrome/browser/ui/chrome_pages.h"
23#include "chrome/common/chrome_content_client.h"
24#include "chrome/common/chrome_version_info.h"
25#include "chrome/common/pref_names.h"
26#include "chrome/common/url_constants.h"
27#include "chrome/grit/chromium_strings.h"
28#include "chrome/grit/generated_resources.h"
29#include "chrome/grit/google_chrome_strings.h"
30#include "components/google/core/browser/google_util.h"
31#include "content/public/browser/browser_thread.h"
32#include "content/public/browser/notification_service.h"
33#include "content/public/browser/web_ui.h"
34#include "content/public/common/user_agent.h"
35#include "grit/components_strings.h"
36#include "ui/base/l10n/l10n_util.h"
37#include "v8/include/v8.h"
38
39#if defined(OS_MACOSX)
40#include "chrome/browser/mac/obsolete_system.h"
41#endif
42
43#if defined(OS_CHROMEOS)
44#include "base/files/file_util_proxy.h"
45#include "base/i18n/time_formatting.h"
46#include "base/prefs/pref_service.h"
47#include "base/sys_info.h"
48#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
49#include "chrome/browser/chromeos/settings/cros_settings.h"
50#include "chrome/browser/profiles/profile.h"
51#include "chrome/browser/ui/webui/help/help_utils_chromeos.h"
52#include "chrome/browser/ui/webui/help/version_updater_chromeos.h"
53#include "chromeos/chromeos_switches.h"
54#include "chromeos/dbus/dbus_thread_manager.h"
55#include "chromeos/dbus/power_manager_client.h"
56#include "components/user_manager/user_manager.h"
57#endif
58
59using base::ListValue;
60using content::BrowserThread;
61
62namespace {
63
64#if defined(OS_CHROMEOS)
65
66// Returns message that informs user that for update it's better to
67// connect to a network of one of the allowed types.
68base::string16 GetAllowedConnectionTypesMessage() {
69  if (help_utils_chromeos::IsUpdateOverCellularAllowed()) {
70    return l10n_util::GetStringUTF16(IDS_UPGRADE_NETWORK_LIST_CELLULAR_ALLOWED);
71  } else {
72    return l10n_util::GetStringUTF16(
73        IDS_UPGRADE_NETWORK_LIST_CELLULAR_DISALLOWED);
74  }
75}
76
77// Returns true if the device is enterprise managed, false otherwise.
78bool IsEnterpriseManaged() {
79  policy::BrowserPolicyConnectorChromeOS* connector =
80      g_browser_process->platform_part()->browser_policy_connector_chromeos();
81  return connector->IsEnterpriseManaged();
82}
83
84// Returns true if current user can change channel, false otherwise.
85bool CanChangeChannel() {
86  bool value = false;
87  chromeos::CrosSettings::Get()->GetBoolean(chromeos::kReleaseChannelDelegated,
88                                            &value);
89
90  // On a managed machine we delegate this setting to the users of the same
91  // domain only if the policy value is "domain".
92  if (IsEnterpriseManaged()) {
93    if (!value)
94      return false;
95    // Get the currently logged in user and strip the domain part only.
96    std::string domain = "";
97    std::string user =
98        user_manager::UserManager::Get()->GetLoggedInUser()->email();
99    size_t at_pos = user.find('@');
100    if (at_pos != std::string::npos && at_pos + 1 < user.length())
101      domain = user.substr(user.find('@') + 1);
102    policy::BrowserPolicyConnectorChromeOS* connector =
103        g_browser_process->platform_part()->browser_policy_connector_chromeos();
104    return domain == connector->GetEnterpriseDomain();
105  } else if (user_manager::UserManager::Get()->IsCurrentUserOwner()) {
106    // On non managed machines we have local owner who is the only one to change
107    // anything. Ensure that ReleaseChannelDelegated is false.
108    return !value;
109  }
110  return false;
111}
112
113#endif  // defined(OS_CHROMEOS)
114
115}  // namespace
116
117HelpHandler::HelpHandler()
118    : version_updater_(VersionUpdater::Create()),
119      weak_factory_(this) {
120}
121
122HelpHandler::~HelpHandler() {
123}
124
125void HelpHandler::GetLocalizedValues(base::DictionaryValue* localized_strings) {
126  struct L10nResources {
127    const char* name;
128    int ids;
129  };
130
131  static L10nResources resources[] = {
132    { "aboutTitle", IDS_ABOUT_TITLE },
133#if defined(OS_CHROMEOS)
134    { "aboutProductTitle", IDS_PRODUCT_OS_NAME },
135#else
136    { "aboutProductTitle", IDS_PRODUCT_NAME },
137#endif
138    { "aboutProductDescription", IDS_ABOUT_PRODUCT_DESCRIPTION },
139    { "relaunch", IDS_RELAUNCH_BUTTON },
140#if defined(OS_CHROMEOS)
141    { "relaunchAndPowerwash", IDS_RELAUNCH_AND_POWERWASH_BUTTON },
142#endif
143    { "productName", IDS_PRODUCT_NAME },
144    { "updateCheckStarted", IDS_UPGRADE_CHECK_STARTED },
145    { "upToDate", IDS_UPGRADE_UP_TO_DATE },
146    { "updating", IDS_UPGRADE_UPDATING },
147#if defined(OS_CHROMEOS)
148    { "updateButton", IDS_UPGRADE_BUTTON },
149    { "updatingChannelSwitch", IDS_UPGRADE_UPDATING_CHANNEL_SWITCH },
150#endif
151    { "updateAlmostDone", IDS_UPGRADE_SUCCESSFUL_RELAUNCH },
152#if defined(OS_CHROMEOS)
153    { "successfulChannelSwitch", IDS_UPGRADE_SUCCESSFUL_CHANNEL_SWITCH },
154#endif
155    { "getHelpWithChrome", IDS_GET_HELP_USING_CHROME },
156    { "reportAnIssue", IDS_REPORT_AN_ISSUE },
157#if defined(OS_CHROMEOS)
158    { "platform", IDS_PLATFORM_LABEL },
159    { "firmware", IDS_ABOUT_PAGE_FIRMWARE },
160    { "showMoreInfo", IDS_SHOW_MORE_INFO },
161    { "hideMoreInfo", IDS_HIDE_MORE_INFO },
162    { "channel", IDS_ABOUT_PAGE_CHANNEL },
163    { "stable", IDS_ABOUT_PAGE_CHANNEL_STABLE },
164    { "beta", IDS_ABOUT_PAGE_CHANNEL_BETA },
165    { "dev", IDS_ABOUT_PAGE_CHANNEL_DEVELOPMENT },
166    { "channel-changed", IDS_ABOUT_PAGE_CHANNEL_CHANGED },
167    { "currentChannelStable", IDS_ABOUT_PAGE_CURRENT_CHANNEL_STABLE },
168    { "currentChannelBeta", IDS_ABOUT_PAGE_CURRENT_CHANNEL_BETA },
169    { "currentChannelDev", IDS_ABOUT_PAGE_CURRENT_CHANNEL_DEV },
170    { "currentChannel", IDS_ABOUT_PAGE_CURRENT_CHANNEL },
171    { "channelChangeButton", IDS_ABOUT_PAGE_CHANNEL_CHANGE_BUTTON },
172    { "channelChangeDisallowedMessage",
173      IDS_ABOUT_PAGE_CHANNEL_CHANGE_DISALLOWED_MESSAGE },
174    { "channelChangePageTitle", IDS_ABOUT_PAGE_CHANNEL_CHANGE_PAGE_TITLE },
175    { "channelChangePagePowerwashTitle",
176      IDS_ABOUT_PAGE_CHANNEL_CHANGE_PAGE_POWERWASH_TITLE },
177    { "channelChangePagePowerwashMessage",
178      IDS_ABOUT_PAGE_CHANNEL_CHANGE_PAGE_POWERWASH_MESSAGE },
179    { "channelChangePageDelayedChangeTitle",
180      IDS_ABOUT_PAGE_CHANNEL_CHANGE_PAGE_DELAYED_CHANGE_TITLE },
181    { "channelChangePageUnstableTitle",
182      IDS_ABOUT_PAGE_CHANNEL_CHANGE_PAGE_UNSTABLE_TITLE },
183    { "channelChangePagePowerwashButton",
184      IDS_ABOUT_PAGE_CHANNEL_CHANGE_PAGE_POWERWASH_BUTTON },
185    { "channelChangePageChangeButton",
186      IDS_ABOUT_PAGE_CHANNEL_CHANGE_PAGE_CHANGE_BUTTON },
187    { "channelChangePageCancelButton",
188      IDS_ABOUT_PAGE_CHANNEL_CHANGE_PAGE_CANCEL_BUTTON },
189    { "webkit", IDS_WEBKIT },
190    { "userAgent", IDS_ABOUT_VERSION_USER_AGENT },
191    { "commandLine", IDS_ABOUT_VERSION_COMMAND_LINE },
192    { "buildDate", IDS_ABOUT_VERSION_BUILD_DATE },
193#endif
194#if defined(OS_MACOSX)
195    { "promote", IDS_ABOUT_CHROME_PROMOTE_UPDATER },
196    { "learnMore", IDS_LEARN_MORE },
197#endif
198  };
199
200  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(resources); ++i) {
201    localized_strings->SetString(resources[i].name,
202                                 l10n_util::GetStringUTF16(resources[i].ids));
203  }
204
205#if defined(OS_MACOSX)
206  localized_strings->SetString(
207      "updateObsoleteSystem",
208      ObsoleteSystemMac::LocalizedObsoleteSystemString());
209  localized_strings->SetString(
210      "updateObsoleteSystemURL",
211      chrome::kMac32BitDeprecationURL);
212#endif
213
214  localized_strings->SetString(
215      "browserVersion",
216      l10n_util::GetStringFUTF16(IDS_ABOUT_PRODUCT_VERSION,
217                                 BuildBrowserVersionString()));
218
219  base::Time::Exploded exploded_time;
220  base::Time::Now().LocalExplode(&exploded_time);
221  localized_strings->SetString(
222      "productCopyright",
223       l10n_util::GetStringFUTF16(IDS_ABOUT_VERSION_COPYRIGHT,
224                                  base::IntToString16(exploded_time.year)));
225
226  base::string16 license = l10n_util::GetStringFUTF16(
227      IDS_ABOUT_VERSION_LICENSE,
228      base::ASCIIToUTF16(chrome::kChromiumProjectURL),
229      base::ASCIIToUTF16(chrome::kChromeUICreditsURL));
230  localized_strings->SetString("productLicense", license);
231
232#if defined(OS_CHROMEOS)
233  base::string16 os_license = l10n_util::GetStringFUTF16(
234      IDS_ABOUT_CROS_VERSION_LICENSE,
235      base::ASCIIToUTF16(chrome::kChromeUIOSCreditsURL));
236  localized_strings->SetString("productOsLicense", os_license);
237
238  base::string16 product_name = l10n_util::GetStringUTF16(IDS_PRODUCT_OS_NAME);
239  localized_strings->SetString(
240      "channelChangePageDelayedChangeMessage",
241      l10n_util::GetStringFUTF16(
242          IDS_ABOUT_PAGE_CHANNEL_CHANGE_PAGE_DELAYED_CHANGE_MESSAGE,
243          product_name));
244  localized_strings->SetString(
245      "channelChangePageUnstableMessage",
246      l10n_util::GetStringFUTF16(
247          IDS_ABOUT_PAGE_CHANNEL_CHANGE_PAGE_UNSTABLE_MESSAGE,
248          product_name));
249
250  if (CommandLine::ForCurrentProcess()->
251      HasSwitch(chromeos::switches::kDisableNewChannelSwitcherUI)) {
252    localized_strings->SetBoolean("disableNewChannelSwitcherUI", true);
253  }
254#endif
255
256  base::string16 tos = l10n_util::GetStringFUTF16(
257      IDS_ABOUT_TERMS_OF_SERVICE, base::UTF8ToUTF16(chrome::kChromeUITermsURL));
258  localized_strings->SetString("productTOS", tos);
259
260  localized_strings->SetString("webkitVersion", content::GetWebKitVersion());
261
262  localized_strings->SetString("jsEngine", "V8");
263  localized_strings->SetString("jsEngineVersion", v8::V8::GetVersion());
264
265  localized_strings->SetString("userAgentInfo", GetUserAgent());
266
267  CommandLine::StringType command_line =
268      CommandLine::ForCurrentProcess()->GetCommandLineString();
269  localized_strings->SetString("commandLineInfo", command_line);
270}
271
272void HelpHandler::RegisterMessages() {
273  registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED,
274                 content::NotificationService::AllSources());
275
276  web_ui()->RegisterMessageCallback("onPageLoaded",
277      base::Bind(&HelpHandler::OnPageLoaded, base::Unretained(this)));
278  web_ui()->RegisterMessageCallback("relaunchNow",
279      base::Bind(&HelpHandler::RelaunchNow, base::Unretained(this)));
280  web_ui()->RegisterMessageCallback("openFeedbackDialog",
281      base::Bind(&HelpHandler::OpenFeedbackDialog, base::Unretained(this)));
282  web_ui()->RegisterMessageCallback("openHelpPage",
283      base::Bind(&HelpHandler::OpenHelpPage, base::Unretained(this)));
284#if defined(OS_CHROMEOS)
285  web_ui()->RegisterMessageCallback("setChannel",
286      base::Bind(&HelpHandler::SetChannel, base::Unretained(this)));
287  web_ui()->RegisterMessageCallback("relaunchAndPowerwash",
288      base::Bind(&HelpHandler::RelaunchAndPowerwash, base::Unretained(this)));
289  web_ui()->RegisterMessageCallback("requestUpdate",
290      base::Bind(&HelpHandler::RequestUpdate, base::Unretained(this)));
291#endif
292#if defined(OS_MACOSX)
293  web_ui()->RegisterMessageCallback("promoteUpdater",
294      base::Bind(&HelpHandler::PromoteUpdater, base::Unretained(this)));
295#endif
296}
297
298void HelpHandler::Observe(int type, const content::NotificationSource& source,
299                          const content::NotificationDetails& details) {
300  switch (type) {
301    case chrome::NOTIFICATION_UPGRADE_RECOMMENDED: {
302      // A version update is installed and ready to go. Refresh the UI so the
303      // correct state will be shown.
304      RequestUpdate(NULL);
305      break;
306    }
307    default:
308      NOTREACHED();
309  }
310}
311
312// static
313base::string16 HelpHandler::BuildBrowserVersionString() {
314  chrome::VersionInfo version_info;
315  DCHECK(version_info.is_valid());
316
317  std::string version = version_info.Version();
318
319  std::string modifier = chrome::VersionInfo::GetVersionStringModifier();
320  if (!modifier.empty())
321    version += " " + modifier;
322
323#if defined(ARCH_CPU_64_BITS)
324  version += " (64-bit)";
325#endif
326
327  return base::UTF8ToUTF16(version);
328}
329
330void HelpHandler::OnPageLoaded(const base::ListValue* args) {
331#if defined(OS_CHROMEOS)
332  // Version information is loaded from a callback
333  loader_.GetVersion(
334      chromeos::VersionLoader::VERSION_FULL,
335      base::Bind(&HelpHandler::OnOSVersion, base::Unretained(this)),
336      &tracker_);
337  loader_.GetFirmware(
338      base::Bind(&HelpHandler::OnOSFirmware, base::Unretained(this)),
339      &tracker_);
340
341  web_ui()->CallJavascriptFunction(
342      "help.HelpPage.updateEnableReleaseChannel",
343      base::FundamentalValue(CanChangeChannel()));
344
345  base::Time build_time = base::SysInfo::GetLsbReleaseTime();
346  base::string16 build_date = base::TimeFormatFriendlyDate(build_time);
347  web_ui()->CallJavascriptFunction("help.HelpPage.setBuildDate",
348                                   base::StringValue(build_date));
349#endif  // defined(OS_CHROMEOS)
350
351  // On Chrome OS, do not check for an update automatically.
352#if defined(OS_CHROMEOS)
353  static_cast<VersionUpdaterCros*>(version_updater_.get())->GetUpdateStatus(
354      base::Bind(&HelpHandler::SetUpdateStatus, base::Unretained(this)));
355#else
356  RequestUpdate(NULL);
357#endif
358
359#if defined(OS_MACOSX)
360  web_ui()->CallJavascriptFunction(
361      "help.HelpPage.setObsoleteSystem",
362      base::FundamentalValue(ObsoleteSystemMac::Is32BitObsoleteNowOrSoon() &&
363                             ObsoleteSystemMac::Has32BitOnlyCPU()));
364  web_ui()->CallJavascriptFunction(
365      "help.HelpPage.setObsoleteSystemEndOfTheLine",
366      base::FundamentalValue(ObsoleteSystemMac::Is32BitObsoleteNowOrSoon() &&
367                             ObsoleteSystemMac::Is32BitEndOfTheLine()));
368#endif
369
370#if defined(OS_CHROMEOS)
371  web_ui()->CallJavascriptFunction(
372      "help.HelpPage.updateIsEnterpriseManaged",
373      base::FundamentalValue(IsEnterpriseManaged()));
374  // First argument to GetChannel() is a flag that indicates whether
375  // current channel should be returned (if true) or target channel
376  // (otherwise).
377  version_updater_->GetChannel(true,
378      base::Bind(&HelpHandler::OnCurrentChannel, weak_factory_.GetWeakPtr()));
379  version_updater_->GetChannel(false,
380      base::Bind(&HelpHandler::OnTargetChannel, weak_factory_.GetWeakPtr()));
381#endif
382}
383
384#if defined(OS_MACOSX)
385void HelpHandler::PromoteUpdater(const base::ListValue* args) {
386  version_updater_->PromoteUpdater();
387}
388#endif
389
390void HelpHandler::RelaunchNow(const base::ListValue* args) {
391  DCHECK(args->empty());
392  version_updater_->RelaunchBrowser();
393}
394
395void HelpHandler::OpenFeedbackDialog(const base::ListValue* args) {
396  DCHECK(args->empty());
397  Browser* browser = chrome::FindBrowserWithWebContents(
398      web_ui()->GetWebContents());
399  chrome::OpenFeedbackDialog(browser);
400}
401
402void HelpHandler::OpenHelpPage(const base::ListValue* args) {
403  DCHECK(args->empty());
404  Browser* browser = chrome::FindBrowserWithWebContents(
405      web_ui()->GetWebContents());
406  chrome::ShowHelp(browser, chrome::HELP_SOURCE_WEBUI);
407}
408
409#if defined(OS_CHROMEOS)
410
411void HelpHandler::SetChannel(const base::ListValue* args) {
412  DCHECK(args->GetSize() == 2);
413
414  if (!CanChangeChannel()) {
415    LOG(WARNING) << "Non-owner tried to change release track.";
416    return;
417  }
418
419  base::string16 channel;
420  bool is_powerwash_allowed;
421  if (!args->GetString(0, &channel) ||
422      !args->GetBoolean(1, &is_powerwash_allowed)) {
423    LOG(ERROR) << "Can't parse SetChannel() args";
424    return;
425  }
426
427  version_updater_->SetChannel(base::UTF16ToUTF8(channel),
428                               is_powerwash_allowed);
429  if (user_manager::UserManager::Get()->IsCurrentUserOwner()) {
430    // Check for update after switching release channel.
431    version_updater_->CheckForUpdate(base::Bind(&HelpHandler::SetUpdateStatus,
432                                                base::Unretained(this)));
433  }
434}
435
436void HelpHandler::RelaunchAndPowerwash(const base::ListValue* args) {
437  DCHECK(args->empty());
438
439  if (IsEnterpriseManaged())
440    return;
441
442  PrefService* prefs = g_browser_process->local_state();
443  prefs->SetBoolean(prefs::kFactoryResetRequested, true);
444  prefs->CommitPendingWrite();
445
446  // Perform sign out. Current chrome process will then terminate, new one will
447  // be launched (as if it was a restart).
448  chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
449}
450
451#endif  // defined(OS_CHROMEOS)
452
453void HelpHandler::RequestUpdate(const base::ListValue* args) {
454  version_updater_->CheckForUpdate(
455      base::Bind(&HelpHandler::SetUpdateStatus, base::Unretained(this))
456#if defined(OS_MACOSX)
457      , base::Bind(&HelpHandler::SetPromotionState, base::Unretained(this))
458#endif
459      );
460}
461
462void HelpHandler::SetUpdateStatus(VersionUpdater::Status status,
463                                  int progress, const base::string16& message) {
464  // Only UPDATING state should have progress set.
465  DCHECK(status == VersionUpdater::UPDATING || progress == 0);
466
467  std::string status_str;
468  switch (status) {
469  case VersionUpdater::CHECKING:
470    status_str = "checking";
471    break;
472  case VersionUpdater::UPDATING:
473    status_str = "updating";
474    break;
475  case VersionUpdater::NEARLY_UPDATED:
476    status_str = "nearly_updated";
477    break;
478  case VersionUpdater::UPDATED:
479    status_str = "updated";
480    break;
481  case VersionUpdater::FAILED:
482  case VersionUpdater::FAILED_OFFLINE:
483  case VersionUpdater::FAILED_CONNECTION_TYPE_DISALLOWED:
484    status_str = "failed";
485    break;
486  case VersionUpdater::DISABLED:
487    status_str = "disabled";
488    break;
489  }
490
491  web_ui()->CallJavascriptFunction("help.HelpPage.setUpdateStatus",
492                                   base::StringValue(status_str),
493                                   base::StringValue(message));
494
495  if (status == VersionUpdater::UPDATING) {
496    web_ui()->CallJavascriptFunction("help.HelpPage.setProgress",
497                                     base::FundamentalValue(progress));
498  }
499
500#if defined(OS_CHROMEOS)
501  if (status == VersionUpdater::FAILED_OFFLINE ||
502      status == VersionUpdater::FAILED_CONNECTION_TYPE_DISALLOWED) {
503    base::string16 types_msg = GetAllowedConnectionTypesMessage();
504    if (!types_msg.empty()) {
505      web_ui()->CallJavascriptFunction(
506          "help.HelpPage.setAndShowAllowedConnectionTypesMsg",
507          base::StringValue(types_msg));
508    } else {
509      web_ui()->CallJavascriptFunction(
510          "help.HelpPage.showAllowedConnectionTypesMsg",
511          base::FundamentalValue(false));
512    }
513  } else {
514    web_ui()->CallJavascriptFunction(
515        "help.HelpPage.showAllowedConnectionTypesMsg",
516        base::FundamentalValue(false));
517  }
518#endif  // defined(OS_CHROMEOS)
519}
520
521#if defined(OS_MACOSX)
522void HelpHandler::SetPromotionState(VersionUpdater::PromotionState state) {
523  std::string state_str;
524  switch (state) {
525  case VersionUpdater::PROMOTE_HIDDEN:
526    state_str = "hidden";
527    break;
528  case VersionUpdater::PROMOTE_ENABLED:
529    state_str = "enabled";
530    break;
531  case VersionUpdater::PROMOTE_DISABLED:
532    state_str = "disabled";
533    break;
534  }
535
536  web_ui()->CallJavascriptFunction("help.HelpPage.setPromotionState",
537                                   base::StringValue(state_str));
538}
539#endif  // defined(OS_MACOSX)
540
541#if defined(OS_CHROMEOS)
542void HelpHandler::OnOSVersion(const std::string& version) {
543  web_ui()->CallJavascriptFunction("help.HelpPage.setOSVersion",
544                                   base::StringValue(version));
545}
546
547void HelpHandler::OnOSFirmware(const std::string& firmware) {
548  web_ui()->CallJavascriptFunction("help.HelpPage.setOSFirmware",
549                                   base::StringValue(firmware));
550}
551
552void HelpHandler::OnCurrentChannel(const std::string& channel) {
553  web_ui()->CallJavascriptFunction(
554      "help.HelpPage.updateCurrentChannel", base::StringValue(channel));
555}
556
557void HelpHandler::OnTargetChannel(const std::string& channel) {
558  web_ui()->CallJavascriptFunction(
559      "help.HelpPage.updateTargetChannel", base::StringValue(channel));
560}
561
562#endif // defined(OS_CHROMEOS)
563