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