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