pepper_flash_component_installer.cc revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file. 4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <string.h> 6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <vector> 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/base_paths.h" 10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/bind.h" 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/command_line.h" 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/compiler_specific.h" 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/file_util.h" 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/files/file_enumerator.h" 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/files/file_path.h" 16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/logging.h" 17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/path_service.h" 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/string_split.h" 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/string_util.h" 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/stringprintf.h" 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/values.h" 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/version.h" 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "build/build_config.h" 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/component_updater/flash_component_installer.h" 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/component_updater/ppapi_utils.h" 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/plugins/plugin_prefs.h" 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/chrome_constants.h" 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/chrome_paths.h" 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/chrome_switches.h" 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/pepper_flash.h" 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/component_updater/component_updater_service.h" 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/plugin_service.h" 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/common/content_constants.h" 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/common/pepper_plugin_info.h" 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "flapper_version.h" // In SHARED_INTERMEDIATE_DIR. NOLINT 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ppapi/c/private/ppb_pdf.h" 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ppapi/shared_impl/ppapi_permissions.h" 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using content::BrowserThread; 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using content::PluginService; 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace component_updater { 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace { 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// File name of the Pepper Flash component manifest on different platforms. 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kPepperFlashManifestName[] = "Flapper"; 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// CRX hash. The extension id is: mimojjlkmoijpicakmndhoigimigcmbb. 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const uint8 kSha2Hash[] = {0xc8, 0xce, 0x99, 0xba, 0xce, 0x89, 0xf8, 0x20, 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 0xac, 0xd3, 0x7e, 0x86, 0x8c, 0x86, 0x2c, 0x11, 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 0xb9, 0x40, 0xc5, 0x55, 0xaf, 0x08, 0x63, 0x70, 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 0x54, 0xf9, 0x56, 0xd3, 0xe7, 0x88, 0xba, 0x8c}; 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// If we don't have a Pepper Flash component, this is the version we claim. 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kNullVersion[] = "0.0.0.0"; 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif // defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) 62 63// Name of the Pepper Flash OS in the component manifest. 64const char kPepperFlashOperatingSystem[] = 65#if defined(OS_MACOSX) 66 "mac"; 67#elif defined(OS_WIN) 68 "win"; 69#else // OS_LINUX, etc. TODO(viettrungluu): Separate out Chrome OS and Android? 70 "linux"; 71#endif 72 73// Name of the Pepper Flash architecture in the component manifest. 74const char kPepperFlashArch[] = 75#if defined(ARCH_CPU_X86) 76 "ia32"; 77#elif defined(ARCH_CPU_X86_64) 78 "x64"; 79#else // TODO(viettrungluu): Support an ARM check? 80 "???"; 81#endif 82 83// The base directory on Windows looks like: 84// <profile>\AppData\Local\Google\Chrome\User Data\PepperFlash\. 85base::FilePath GetPepperFlashBaseDirectory() { 86 base::FilePath result; 87 PathService::Get(chrome::DIR_COMPONENT_UPDATED_PEPPER_FLASH_PLUGIN, &result); 88 return result; 89} 90 91#if defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) 92// Install directory for pepper flash debugger dlls will be like 93// c:\windows\system32\macromed\flash\, or basically the Macromed\Flash 94// subdirectory of the Windows system directory. 95base::FilePath GetPepperFlashDebuggerDirectory() { 96 base::FilePath result; 97 PathService::Get(chrome::DIR_PEPPER_FLASH_DEBUGGER_PLUGIN, &result); 98 return result; 99} 100 101// Pepper Flash plugins have the version encoded in the path itself 102// so we need to enumerate the directories to find the full path. 103// On success, |latest_dir| returns something like: 104// <profile>\AppData\Local\Google\Chrome\User Data\PepperFlash\10.3.44.555\. 105// |latest_version| returns the corresponding version number. |older_dirs| 106// returns directories of all older versions. 107bool GetPepperFlashDirectory(base::FilePath* latest_dir, 108 Version* latest_version, 109 std::vector<base::FilePath>* older_dirs) { 110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 111 base::FilePath base_dir = GetPepperFlashBaseDirectory(); 112 bool found = false; 113 base::FileEnumerator file_enumerator( 114 base_dir, false, base::FileEnumerator::DIRECTORIES); 115 for (base::FilePath path = file_enumerator.Next(); !path.value().empty(); 116 path = file_enumerator.Next()) { 117 Version version(path.BaseName().MaybeAsASCII()); 118 if (!version.IsValid()) 119 continue; 120 if (found) { 121 if (version.CompareTo(*latest_version) > 0) { 122 older_dirs->push_back(*latest_dir); 123 *latest_dir = path; 124 *latest_version = version; 125 } else { 126 older_dirs->push_back(path); 127 } 128 } else { 129 *latest_dir = path; 130 *latest_version = version; 131 found = true; 132 } 133 } 134 return found; 135} 136 137#if defined(OS_WIN) 138const wchar_t kPepperFlashDebuggerDLLSearchString[] = 139#if defined(ARCH_CPU_X86) 140 L"pepflashplayer32*.dll"; 141#elif defined(ARCH_CPU_X86_64) 142 L"pepflashplayer64*.dll"; 143#else 144#error Unsupported Windows CPU architecture. 145#endif // defined(ARCH_CPU_X86) 146#endif // defined(OS_WIN) 147 148bool GetPepperFlashDebuggerPath(base::FilePath* dll_path, 149 Version* dll_version) { 150 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 151 base::FilePath debugger_dir = GetPepperFlashDebuggerDirectory(); 152 // If path doesn't exist they simply don't have the flash debugger installed. 153 if (!base::PathExists(debugger_dir)) 154 return false; 155 156 bool found = false; 157#if defined(OS_WIN) 158 // Enumerate any DLLs that match the appropriate pattern for this DLL, and 159 // pick the highest version number we find. 160 base::FileEnumerator file_enumerator(debugger_dir, 161 false, 162 base::FileEnumerator::FILES, 163 kPepperFlashDebuggerDLLSearchString); 164 for (base::FilePath path = file_enumerator.Next(); !path.value().empty(); 165 path = file_enumerator.Next()) { 166 // Version number is embedded in file name like basename_x_y_z.dll. Extract. 167 std::string file_name(path.BaseName().RemoveExtension().MaybeAsASCII()); 168 // file_name should now be basename_x_y_z. Split along '_' for version. 169 std::vector<std::string> components; 170 base::SplitString(file_name, '_', &components); 171 // Should have at least one version number. 172 if (components.size() <= 1) 173 continue; 174 // Meld version components back into a string, now separated by periods, so 175 // Version can parse it. 176 std::string version_string(components[1]); 177 for (size_t i = 2; i < components.size(); ++i) { 178 version_string += "." + components[i]; 179 } 180 Version version(version_string); 181 if (!version.IsValid()) 182 continue; 183 if (found) { 184 if (version.CompareTo(*dll_version) > 0) { 185 *dll_path = path; 186 *dll_version = version; 187 } 188 } else { 189 *dll_path = path; 190 *dll_version = version; 191 found = true; 192 } 193 } 194#endif 195 return found; 196} 197#endif // defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) 198 199// Returns true if the Pepper |interface_name| is implemented by this browser. 200// It does not check if the interface is proxied. 201bool SupportsPepperInterface(const char* interface_name) { 202 if (IsSupportedPepperInterface(interface_name)) 203 return true; 204 // The PDF interface is invisible to SupportsInterface() on the browser 205 // process because it is provided using PpapiInterfaceFactoryManager. We need 206 // to check for that as well. 207 // TODO(cpu): make this more sane. 208 return (strcmp(interface_name, PPB_PDF_INTERFACE) == 0); 209} 210 211bool MakePepperFlashPluginInfo(const base::FilePath& flash_path, 212 const Version& flash_version, 213 bool out_of_process, 214 bool is_debugger, 215 content::PepperPluginInfo* plugin_info) { 216 if (!flash_version.IsValid()) 217 return false; 218 const std::vector<uint16> ver_nums = flash_version.components(); 219 if (ver_nums.size() < 3) 220 return false; 221 222 plugin_info->is_internal = false; 223 plugin_info->is_out_of_process = out_of_process; 224 plugin_info->path = flash_path; 225 plugin_info->name = content::kFlashPluginName; 226 plugin_info->permissions = kPepperFlashPermissions; 227 228 // The description is like "Shockwave Flash 10.2 r154". 229 plugin_info->description = base::StringPrintf("%s %d.%d r%d", 230 content::kFlashPluginName, 231 ver_nums[0], 232 ver_nums[1], 233 ver_nums[2]); 234 235 plugin_info->version = flash_version.GetString(); 236 237 content::WebPluginMimeType swf_mime_type(content::kFlashPluginSwfMimeType, 238 content::kFlashPluginSwfExtension, 239 content::kFlashPluginName); 240 plugin_info->mime_types.push_back(swf_mime_type); 241 content::WebPluginMimeType spl_mime_type(content::kFlashPluginSplMimeType, 242 content::kFlashPluginSplExtension, 243 content::kFlashPluginName); 244 plugin_info->mime_types.push_back(spl_mime_type); 245 return true; 246} 247 248bool IsPepperFlash(const content::WebPluginInfo& plugin) { 249 // We try to recognize Pepper Flash by the following criteria: 250 // * It is a Pepper plug-in. 251 // * It has the special Flash permissions. 252 return plugin.is_pepper_plugin() && 253 (plugin.pepper_permissions & ppapi::PERMISSION_FLASH); 254} 255 256void RegisterPepperFlashWithChrome(const base::FilePath& path, 257 const Version& version, 258 bool is_debugger) { 259 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 260 content::PepperPluginInfo plugin_info; 261 if (!MakePepperFlashPluginInfo( 262 path, version, true, is_debugger, &plugin_info)) 263 return; 264 265 // If this is the non-debugger version, we enumerate any installed versions of 266 // pepper flash to make sure we only replace the installed version with a 267 // newer version. 268 if (!is_debugger) { 269 std::vector<content::WebPluginInfo> plugins; 270 PluginService::GetInstance()->GetInternalPlugins(&plugins); 271 for (std::vector<content::WebPluginInfo>::const_iterator it = 272 plugins.begin(); 273 it != plugins.end(); 274 ++it) { 275 if (!IsPepperFlash(*it)) 276 continue; 277 278 // Do it only if the version we're trying to register is newer. 279 Version registered_version(base::UTF16ToUTF8(it->version)); 280 if (registered_version.IsValid() && 281 version.CompareTo(registered_version) <= 0) { 282 return; 283 } 284 285 // If the version is newer, remove the old one first. 286 PluginService::GetInstance()->UnregisterInternalPlugin(it->path); 287 break; 288 } 289 } 290 291 // We only ask for registration at the beginning for the non-debugger plugin, 292 // that way the debugger plugin doesn't automatically clobber the built-in or 293 // updated non-debugger version. 294 PluginService::GetInstance()->RegisterInternalPlugin( 295 plugin_info.ToWebPluginInfo(), !is_debugger); 296 PluginService::GetInstance()->RefreshPlugins(); 297} 298 299// Returns true if this browser implements one of the interfaces given in 300// |interface_string|, which is a '|'-separated string of interface names. 301bool CheckPepperFlashInterfaceString(const std::string& interface_string) { 302 std::vector<std::string> interface_names; 303 base::SplitString(interface_string, '|', &interface_names); 304 for (size_t i = 0; i < interface_names.size(); i++) { 305 if (SupportsPepperInterface(interface_names[i].c_str())) 306 return true; 307 } 308 return false; 309} 310 311// Returns true if this browser implements all the interfaces that Flash 312// specifies in its component installer manifest. 313bool CheckPepperFlashInterfaces(const base::DictionaryValue& manifest) { 314 const base::ListValue* interface_list = NULL; 315 316 // We don't *require* an interface list, apparently. 317 if (!manifest.GetList("x-ppapi-required-interfaces", &interface_list)) 318 return true; 319 320 for (size_t i = 0; i < interface_list->GetSize(); i++) { 321 std::string interface_string; 322 if (!interface_list->GetString(i, &interface_string)) 323 return false; 324 if (!CheckPepperFlashInterfaceString(interface_string)) 325 return false; 326 } 327 328 return true; 329} 330 331} // namespace 332 333class PepperFlashComponentInstaller : public ComponentInstaller { 334 public: 335 explicit PepperFlashComponentInstaller(const Version& version); 336 337 virtual ~PepperFlashComponentInstaller() {} 338 339 virtual void OnUpdateError(int error) OVERRIDE; 340 341 virtual bool Install(const base::DictionaryValue& manifest, 342 const base::FilePath& unpack_path) OVERRIDE; 343 344 virtual bool GetInstalledFile(const std::string& file, 345 base::FilePath* installed_file) OVERRIDE; 346 347 private: 348 Version current_version_; 349}; 350 351PepperFlashComponentInstaller::PepperFlashComponentInstaller( 352 const Version& version) 353 : current_version_(version) { 354 DCHECK(version.IsValid()); 355} 356 357void PepperFlashComponentInstaller::OnUpdateError(int error) { 358 NOTREACHED() << "Pepper Flash update error: " << error; 359} 360 361bool PepperFlashComponentInstaller::Install( 362 const base::DictionaryValue& manifest, 363 const base::FilePath& unpack_path) { 364 Version version; 365 if (!CheckPepperFlashManifest(manifest, &version)) 366 return false; 367 if (current_version_.CompareTo(version) > 0) 368 return false; 369 if (!base::PathExists(unpack_path.Append(chrome::kPepperFlashPluginFilename))) 370 return false; 371 // Passed the basic tests. Time to install it. 372 base::FilePath path = 373 GetPepperFlashBaseDirectory().AppendASCII(version.GetString()); 374 if (base::PathExists(path)) 375 return false; 376 if (!base::Move(unpack_path, path)) 377 return false; 378 // Installation is done. Now tell the rest of chrome. Both the path service 379 // and to the plugin service. 380 current_version_ = version; 381 PathService::Override(chrome::DIR_PEPPER_FLASH_PLUGIN, path); 382 path = path.Append(chrome::kPepperFlashPluginFilename); 383 BrowserThread::PostTask( 384 BrowserThread::UI, 385 FROM_HERE, 386 base::Bind(&RegisterPepperFlashWithChrome, path, version, false)); 387 return true; 388} 389 390bool PepperFlashComponentInstaller::GetInstalledFile( 391 const std::string& file, 392 base::FilePath* installed_file) { 393 return false; 394} 395 396bool CheckPepperFlashManifest(const base::DictionaryValue& manifest, 397 Version* version_out) { 398 std::string name; 399 manifest.GetStringASCII("name", &name); 400 // TODO(viettrungluu): Support WinFlapper for now, while we change the format 401 // of the manifest. (Should be safe to remove checks for "WinFlapper" in, say, 402 // Nov. 2011.) crbug.com/98458 403 if (name != kPepperFlashManifestName && name != "WinFlapper") 404 return false; 405 406 std::string proposed_version; 407 manifest.GetStringASCII("version", &proposed_version); 408 Version version(proposed_version.c_str()); 409 if (!version.IsValid()) 410 return false; 411 412 if (!CheckPepperFlashInterfaces(manifest)) 413 return false; 414 415 // TODO(viettrungluu): See above TODO. 416 if (name == "WinFlapper") { 417 *version_out = version; 418 return true; 419 } 420 421 std::string os; 422 manifest.GetStringASCII("x-ppapi-os", &os); 423 if (os != kPepperFlashOperatingSystem) 424 return false; 425 426 std::string arch; 427 manifest.GetStringASCII("x-ppapi-arch", &arch); 428 if (arch != kPepperFlashArch) 429 return false; 430 431 *version_out = version; 432 return true; 433} 434 435namespace { 436 437#if defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) 438void FinishPepperFlashUpdateRegistration(ComponentUpdateService* cus, 439 const Version& version) { 440 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 441 CrxComponent pepflash; 442 pepflash.name = "pepper_flash"; 443 pepflash.installer = new PepperFlashComponentInstaller(version); 444 pepflash.version = version; 445 pepflash.pk_hash.assign(kSha2Hash, &kSha2Hash[sizeof(kSha2Hash)]); 446 if (cus->RegisterComponent(pepflash) != ComponentUpdateService::kOk) { 447 NOTREACHED() << "Pepper Flash component registration failed."; 448 } 449} 450 451void StartPepperFlashUpdateRegistration(ComponentUpdateService* cus) { 452 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 453 base::FilePath path = GetPepperFlashBaseDirectory(); 454 if (!base::PathExists(path)) { 455 if (!base::CreateDirectory(path)) { 456 NOTREACHED() << "Could not create Pepper Flash directory."; 457 return; 458 } 459 } 460 461 Version version(kNullVersion); 462 std::vector<base::FilePath> older_dirs; 463 if (GetPepperFlashDirectory(&path, &version, &older_dirs)) { 464 path = path.Append(chrome::kPepperFlashPluginFilename); 465 if (base::PathExists(path)) { 466 BrowserThread::PostTask( 467 BrowserThread::UI, 468 FROM_HERE, 469 base::Bind(&RegisterPepperFlashWithChrome, path, version, false)); 470 } else { 471 version = Version(kNullVersion); 472 } 473 } 474 475 BrowserThread::PostTask( 476 BrowserThread::UI, 477 FROM_HERE, 478 base::Bind(&FinishPepperFlashUpdateRegistration, cus, version)); 479 480 // Remove older versions of Pepper Flash. 481 for (std::vector<base::FilePath>::iterator iter = older_dirs.begin(); 482 iter != older_dirs.end(); 483 ++iter) { 484 base::DeleteFile(*iter, true); 485 } 486 487 // Check for Debugging version of Flash and register if present. 488 base::FilePath debugger_path; 489 Version debugger_version(kNullVersion); 490 if (GetPepperFlashDebuggerPath(&debugger_path, &debugger_version)) { 491 BrowserThread::PostTask(BrowserThread::UI, 492 FROM_HERE, 493 base::Bind(&RegisterPepperFlashWithChrome, 494 debugger_path, 495 debugger_version, 496 true)); 497 } 498} 499#endif // defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) 500 501} // namespace 502 503void RegisterPepperFlashComponent(ComponentUpdateService* cus) { 504#if defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) 505 // Component updated flash supersedes bundled flash therefore if that one 506 // is disabled then this one should never install. 507 CommandLine* cmd_line = CommandLine::ForCurrentProcess(); 508 if (cmd_line->HasSwitch(switches::kDisableBundledPpapiFlash)) 509 return; 510 BrowserThread::PostTask(BrowserThread::FILE, 511 FROM_HERE, 512 base::Bind(&StartPepperFlashUpdateRegistration, cus)); 513#endif 514} 515 516} // namespace component_updater 517