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