Commit ce3ea567 authored by wfh's avatar wfh Committed by Commit bot

Register system Pepper Flash plugin if no packaged Pepper plugin is found.

With the NPAPI deprecation, Adobe have now made a supported, automatically updating version of Pepper Flash available on Windows and OS X.

This CL moves the code previously added in https://codereview.chromium.org/203993004 into chrome/common so the system plugin is added on all Chromium builds.

To manually override bundled PepperFlash on Chrome (e.g. to load a Debug version), use --disable-bundled-ppapi-flash

BUG=345886,454131
TEST=Install PPAPI Flash from Adobe site (link in bug)
TEST=For Chromium builds: Check Chromium now automatically uses system version of Flash in chrome://plugins.
TEST=For Chrome builds: Check Chrome still uses bundled Flash by default.  Check if --disable-bundled-ppapi-flash it uses system flash.
TEST=Check an old version of System flash will pop out of date plugin warning.

Review URL: https://codereview.chromium.org/893823002

Cr-Commit-Position: refs/heads/master@{#317656}
parent e6f7a58b
...@@ -19,11 +19,6 @@ class ComponentUpdateService; ...@@ -19,11 +19,6 @@ class ComponentUpdateService;
// The first part is IO intensive so we do it asynchronously in the file thread. // The first part is IO intensive so we do it asynchronously in the file thread.
void RegisterPepperFlashComponent(ComponentUpdateService* cus); void RegisterPepperFlashComponent(ComponentUpdateService* cus);
// Returns true if this browser is compatible with the given Pepper Flash
// manifest, with the version specified in the manifest in |version_out|.
bool CheckPepperFlashManifest(const base::DictionaryValue& manifest,
base::Version* version_out);
} // namespace component_updater } // namespace component_updater
#endif // CHROME_BROWSER_COMPONENT_UPDATER_FLASH_COMPONENT_INSTALLER_H_ #endif // CHROME_BROWSER_COMPONENT_UPDATER_FLASH_COMPONENT_INSTALLER_H_
...@@ -15,20 +15,18 @@ ...@@ -15,20 +15,18 @@
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "base/version.h" #include "base/version.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/browser/component_updater/flash_component_installer.h" #include "chrome/browser/component_updater/flash_component_installer.h"
#include "chrome/browser/component_updater/ppapi_utils.h"
#include "chrome/browser/plugins/plugin_prefs.h" #include "chrome/browser/plugins/plugin_prefs.h"
#include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "chrome/common/pepper_flash.h" #include "chrome/common/pepper_flash.h"
#include "chrome/common/ppapi_utils.h"
#include "components/component_updater/component_updater_service.h" #include "components/component_updater/component_updater_service.h"
#include "components/update_client/update_client.h" #include "components/update_client/update_client.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
...@@ -36,7 +34,6 @@ ...@@ -36,7 +34,6 @@
#include "content/public/common/content_constants.h" #include "content/public/common/content_constants.h"
#include "content/public/common/pepper_plugin_info.h" #include "content/public/common/pepper_plugin_info.h"
#include "flapper_version.h" // In SHARED_INTERMEDIATE_DIR. NOLINT #include "flapper_version.h" // In SHARED_INTERMEDIATE_DIR. NOLINT
#include "ppapi/c/private/ppb_pdf.h"
#include "ppapi/shared_impl/ppapi_permissions.h" #include "ppapi/shared_impl/ppapi_permissions.h"
using content::BrowserThread; using content::BrowserThread;
...@@ -46,9 +43,6 @@ namespace component_updater { ...@@ -46,9 +43,6 @@ namespace component_updater {
namespace { namespace {
// File name of the Pepper Flash component manifest on different platforms.
const char kPepperFlashManifestName[] = "Flapper";
#if defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) #if defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX)
// CRX hash. The extension id is: mimojjlkmoijpicakmndhoigimigcmbb. // CRX hash. The extension id is: mimojjlkmoijpicakmndhoigimigcmbb.
const uint8_t kSha2Hash[] = {0xc8, 0xce, 0x99, 0xba, 0xce, 0x89, 0xf8, 0x20, const uint8_t kSha2Hash[] = {0xc8, 0xce, 0x99, 0xba, 0xce, 0x89, 0xf8, 0x20,
...@@ -61,26 +55,6 @@ const char kNullVersion[] = "0.0.0.0"; ...@@ -61,26 +55,6 @@ const char kNullVersion[] = "0.0.0.0";
#endif // defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) #endif // defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX)
// Name of the Pepper Flash OS in the component manifest.
const char kPepperFlashOperatingSystem[] =
#if defined(OS_MACOSX)
"mac";
#elif defined(OS_WIN)
"win";
#else // OS_LINUX, etc. TODO(viettrungluu): Separate out Chrome OS and Android?
"linux";
#endif
// Name of the Pepper Flash architecture in the component manifest.
const char kPepperFlashArch[] =
#if defined(ARCH_CPU_X86)
"ia32";
#elif defined(ARCH_CPU_X86_64)
"x64";
#else // TODO(viettrungluu): Support an ARM check?
"???";
#endif
// The base directory on Windows looks like: // The base directory on Windows looks like:
// <profile>\AppData\Local\Google\Chrome\User Data\PepperFlash\. // <profile>\AppData\Local\Google\Chrome\User Data\PepperFlash\.
base::FilePath GetPepperFlashBaseDirectory() { base::FilePath GetPepperFlashBaseDirectory() {
...@@ -90,15 +64,6 @@ base::FilePath GetPepperFlashBaseDirectory() { ...@@ -90,15 +64,6 @@ base::FilePath GetPepperFlashBaseDirectory() {
} }
#if defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) #if defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX)
// Install directory for pepper flash debugger dlls will be like
// c:\windows\system32\macromed\flash\, or basically the Macromed\Flash
// subdirectory of the Windows system directory.
base::FilePath GetPepperFlashDebuggerDirectory() {
base::FilePath result;
PathService::Get(chrome::DIR_PEPPER_FLASH_DEBUGGER_PLUGIN, &result);
return result;
}
// Pepper Flash plugins have the version encoded in the path itself // Pepper Flash plugins have the version encoded in the path itself
// so we need to enumerate the directories to find the full path. // so we need to enumerate the directories to find the full path.
// On success, |latest_dir| returns something like: // On success, |latest_dir| returns something like:
...@@ -134,85 +99,11 @@ bool GetPepperFlashDirectory(base::FilePath* latest_dir, ...@@ -134,85 +99,11 @@ bool GetPepperFlashDirectory(base::FilePath* latest_dir,
} }
return found; return found;
} }
#if defined(OS_WIN)
const wchar_t kPepperFlashDebuggerDLLSearchString[] =
#if defined(ARCH_CPU_X86)
L"pepflashplayer32*.dll";
#elif defined(ARCH_CPU_X86_64)
L"pepflashplayer64*.dll";
#else
#error Unsupported Windows CPU architecture.
#endif // defined(ARCH_CPU_X86)
#endif // defined(OS_WIN)
bool GetPepperFlashDebuggerPath(base::FilePath* dll_path,
Version* dll_version) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
base::FilePath debugger_dir = GetPepperFlashDebuggerDirectory();
// If path doesn't exist they simply don't have the flash debugger installed.
if (!base::PathExists(debugger_dir))
return false;
bool found = false;
#if defined(OS_WIN)
// Enumerate any DLLs that match the appropriate pattern for this DLL, and
// pick the highest version number we find.
base::FileEnumerator file_enumerator(debugger_dir,
false,
base::FileEnumerator::FILES,
kPepperFlashDebuggerDLLSearchString);
for (base::FilePath path = file_enumerator.Next(); !path.value().empty();
path = file_enumerator.Next()) {
// Version number is embedded in file name like basename_x_y_z.dll. Extract.
std::string file_name(path.BaseName().RemoveExtension().MaybeAsASCII());
// file_name should now be basename_x_y_z. Split along '_' for version.
std::vector<std::string> components;
base::SplitString(file_name, '_', &components);
// Should have at least one version number.
if (components.size() <= 1)
continue;
// Meld version components back into a string, now separated by periods, so
// Version can parse it.
std::string version_string(components[1]);
for (size_t i = 2; i < components.size(); ++i) {
version_string += "." + components[i];
}
Version version(version_string);
if (!version.IsValid())
continue;
if (found) {
if (version.CompareTo(*dll_version) > 0) {
*dll_path = path;
*dll_version = version;
}
} else {
*dll_path = path;
*dll_version = version;
found = true;
}
}
#endif
return found;
}
#endif // defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) #endif // defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX)
// Returns true if the Pepper |interface_name| is implemented by this browser.
// It does not check if the interface is proxied.
bool SupportsPepperInterface(const char* interface_name) {
if (IsSupportedPepperInterface(interface_name))
return true;
// The PDF interface is invisible to SupportsInterface() on the browser
// process because it is provided using PpapiInterfaceFactoryManager. We need
// to check for that as well.
// TODO(cpu): make this more sane.
return (strcmp(interface_name, PPB_PDF_INTERFACE) == 0);
}
bool MakePepperFlashPluginInfo(const base::FilePath& flash_path, bool MakePepperFlashPluginInfo(const base::FilePath& flash_path,
const Version& flash_version, const Version& flash_version,
bool out_of_process, bool out_of_process,
bool is_debugger,
content::PepperPluginInfo* plugin_info) { content::PepperPluginInfo* plugin_info) {
if (!flash_version.IsValid()) if (!flash_version.IsValid())
return false; return false;
...@@ -224,7 +115,7 @@ bool MakePepperFlashPluginInfo(const base::FilePath& flash_path, ...@@ -224,7 +115,7 @@ bool MakePepperFlashPluginInfo(const base::FilePath& flash_path,
plugin_info->is_out_of_process = out_of_process; plugin_info->is_out_of_process = out_of_process;
plugin_info->path = flash_path; plugin_info->path = flash_path;
plugin_info->name = content::kFlashPluginName; plugin_info->name = content::kFlashPluginName;
plugin_info->permissions = kPepperFlashPermissions; plugin_info->permissions = chrome::kPepperFlashPermissions;
// The description is like "Shockwave Flash 10.2 r154". // The description is like "Shockwave Flash 10.2 r154".
plugin_info->description = base::StringPrintf("%s %d.%d r%d", plugin_info->description = base::StringPrintf("%s %d.%d r%d",
...@@ -255,80 +146,38 @@ bool IsPepperFlash(const content::WebPluginInfo& plugin) { ...@@ -255,80 +146,38 @@ bool IsPepperFlash(const content::WebPluginInfo& plugin) {
} }
void RegisterPepperFlashWithChrome(const base::FilePath& path, void RegisterPepperFlashWithChrome(const base::FilePath& path,
const Version& version, const Version& version) {
bool is_debugger) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
content::PepperPluginInfo plugin_info; content::PepperPluginInfo plugin_info;
if (!MakePepperFlashPluginInfo( if (!MakePepperFlashPluginInfo(path, version, true, &plugin_info))
path, version, true, is_debugger, &plugin_info))
return; return;
// If this is the non-debugger version, we enumerate any installed versions of std::vector<content::WebPluginInfo> plugins;
// pepper flash to make sure we only replace the installed version with a PluginService::GetInstance()->GetInternalPlugins(&plugins);
// newer version. for (std::vector<content::WebPluginInfo>::const_iterator it =
if (!is_debugger) { plugins.begin();
std::vector<content::WebPluginInfo> plugins; it != plugins.end();
PluginService::GetInstance()->GetInternalPlugins(&plugins); ++it) {
for (std::vector<content::WebPluginInfo>::const_iterator it = if (!IsPepperFlash(*it))
plugins.begin(); continue;
it != plugins.end();
++it) {
if (!IsPepperFlash(*it))
continue;
// Do it only if the version we're trying to register is newer.
Version registered_version(base::UTF16ToUTF8(it->version));
if (registered_version.IsValid() &&
version.CompareTo(registered_version) <= 0) {
return;
}
// If the version is newer, remove the old one first. // Do it only if the version we're trying to register is newer.
PluginService::GetInstance()->UnregisterInternalPlugin(it->path); Version registered_version(base::UTF16ToUTF8(it->version));
break; if (registered_version.IsValid() &&
version.CompareTo(registered_version) <= 0) {
return;
} }
// If the version is newer, remove the old one first.
PluginService::GetInstance()->UnregisterInternalPlugin(it->path);
break;
} }
// We only ask for registration at the beginning for the non-debugger plugin,
// that way the debugger plugin doesn't automatically clobber the built-in or
// updated non-debugger version.
PluginService::GetInstance()->RegisterInternalPlugin( PluginService::GetInstance()->RegisterInternalPlugin(
plugin_info.ToWebPluginInfo(), !is_debugger); plugin_info.ToWebPluginInfo(), true);
PluginService::GetInstance()->RefreshPlugins(); PluginService::GetInstance()->RefreshPlugins();
} }
// Returns true if this browser implements one of the interfaces given in
// |interface_string|, which is a '|'-separated string of interface names.
bool CheckPepperFlashInterfaceString(const std::string& interface_string) {
std::vector<std::string> interface_names;
base::SplitString(interface_string, '|', &interface_names);
for (size_t i = 0; i < interface_names.size(); i++) {
if (SupportsPepperInterface(interface_names[i].c_str()))
return true;
}
return false;
}
// Returns true if this browser implements all the interfaces that Flash
// specifies in its component installer manifest.
bool CheckPepperFlashInterfaces(const base::DictionaryValue& manifest) {
const base::ListValue* interface_list = NULL;
// We don't *require* an interface list, apparently.
if (!manifest.GetList("x-ppapi-required-interfaces", &interface_list))
return true;
for (size_t i = 0; i < interface_list->GetSize(); i++) {
std::string interface_string;
if (!interface_list->GetString(i, &interface_string))
return false;
if (!CheckPepperFlashInterfaceString(interface_string))
return false;
}
return true;
}
} // namespace } // namespace
class PepperFlashComponentInstaller : public update_client::ComponentInstaller { class PepperFlashComponentInstaller : public update_client::ComponentInstaller {
...@@ -366,7 +215,7 @@ bool PepperFlashComponentInstaller::Install( ...@@ -366,7 +215,7 @@ bool PepperFlashComponentInstaller::Install(
const base::DictionaryValue& manifest, const base::DictionaryValue& manifest,
const base::FilePath& unpack_path) { const base::FilePath& unpack_path) {
Version version; Version version;
if (!CheckPepperFlashManifest(manifest, &version)) if (!chrome::CheckPepperFlashManifest(manifest, &version))
return false; return false;
if (current_version_.CompareTo(version) > 0) if (current_version_.CompareTo(version) > 0)
return false; return false;
...@@ -387,7 +236,7 @@ bool PepperFlashComponentInstaller::Install( ...@@ -387,7 +236,7 @@ bool PepperFlashComponentInstaller::Install(
BrowserThread::PostTask( BrowserThread::PostTask(
BrowserThread::UI, BrowserThread::UI,
FROM_HERE, FROM_HERE,
base::Bind(&RegisterPepperFlashWithChrome, path, version, false)); base::Bind(&RegisterPepperFlashWithChrome, path, version));
return true; return true;
} }
...@@ -401,44 +250,7 @@ bool PepperFlashComponentInstaller::Uninstall() { ...@@ -401,44 +250,7 @@ bool PepperFlashComponentInstaller::Uninstall() {
return false; return false;
} }
bool CheckPepperFlashManifest(const base::DictionaryValue& manifest,
Version* version_out) {
std::string name;
manifest.GetStringASCII("name", &name);
// TODO(viettrungluu): Support WinFlapper for now, while we change the format
// of the manifest. (Should be safe to remove checks for "WinFlapper" in, say,
// Nov. 2011.) crbug.com/98458
if (name != kPepperFlashManifestName && name != "WinFlapper")
return false;
std::string proposed_version;
manifest.GetStringASCII("version", &proposed_version);
Version version(proposed_version.c_str());
if (!version.IsValid())
return false;
if (!CheckPepperFlashInterfaces(manifest))
return false;
// TODO(viettrungluu): See above TODO.
if (name == "WinFlapper") {
*version_out = version;
return true;
}
std::string os;
manifest.GetStringASCII("x-ppapi-os", &os);
if (os != kPepperFlashOperatingSystem)
return false;
std::string arch;
manifest.GetStringASCII("x-ppapi-arch", &arch);
if (arch != kPepperFlashArch)
return false;
*version_out = version;
return true;
}
namespace { namespace {
...@@ -474,7 +286,7 @@ void StartPepperFlashUpdateRegistration(ComponentUpdateService* cus) { ...@@ -474,7 +286,7 @@ void StartPepperFlashUpdateRegistration(ComponentUpdateService* cus) {
BrowserThread::PostTask( BrowserThread::PostTask(
BrowserThread::UI, BrowserThread::UI,
FROM_HERE, FROM_HERE,
base::Bind(&RegisterPepperFlashWithChrome, path, version, false)); base::Bind(&RegisterPepperFlashWithChrome, path, version));
} else { } else {
version = Version(kNullVersion); version = Version(kNullVersion);
} }
...@@ -491,18 +303,6 @@ void StartPepperFlashUpdateRegistration(ComponentUpdateService* cus) { ...@@ -491,18 +303,6 @@ void StartPepperFlashUpdateRegistration(ComponentUpdateService* cus) {
++iter) { ++iter) {
base::DeleteFile(*iter, true); base::DeleteFile(*iter, true);
} }
// Check for Debugging version of Flash and register if present.
base::FilePath debugger_path;
Version debugger_version(kNullVersion);
if (GetPepperFlashDebuggerPath(&debugger_path, &debugger_version)) {
BrowserThread::PostTask(BrowserThread::UI,
FROM_HERE,
base::Bind(&RegisterPepperFlashWithChrome,
debugger_path,
debugger_version,
true));
}
} }
#endif // defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) #endif // defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX)
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/version.h" #include "base/version.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_paths.h"
#include "chrome/common/pepper_flash.h"
#include "content/public/test/test_browser_thread.h" #include "content/public/test/test_browser_thread.h"
#include "ppapi/shared_impl/test_globals.h" #include "ppapi/shared_impl/test_globals.h"
...@@ -81,7 +82,7 @@ TEST(ComponentInstallerTest, PepperFlashCheck) { ...@@ -81,7 +82,7 @@ TEST(ComponentInstallerTest, PepperFlashCheck) {
// This checks that the whole manifest is compatible. // This checks that the whole manifest is compatible.
Version version; Version version;
EXPECT_TRUE(CheckPepperFlashManifest(*root, &version)); EXPECT_TRUE(chrome::CheckPepperFlashManifest(*root, &version));
EXPECT_TRUE(version.IsValid()); EXPECT_TRUE(version.IsValid());
} }
......
...@@ -372,16 +372,24 @@ void PluginsDOMHandler::PluginsLoaded( ...@@ -372,16 +372,24 @@ void PluginsDOMHandler::PluginsLoaded(
plugin_file->SetString("name", group_plugin.name); plugin_file->SetString("name", group_plugin.name);
// If this plugin is Pepper Flash, and the plugin path is the same as the // If this plugin is Pepper Flash, and the plugin path is the same as the
// path for the Pepper Flash Debugger plugin, then mark this plugin // path for the Pepper Flash System plugin, then mark this plugin
// description as the debugger plugin to help the user disambiguate the // description as the system plugin to help the user disambiguate the
// two plugins. // two plugins.
base::string16 desc = group_plugin.desc; base::string16 desc = group_plugin.desc;
if (group_plugin.is_pepper_plugin() && if (group_plugin.is_pepper_plugin() &&
group_plugin.name == base::ASCIIToUTF16(content::kFlashPluginName)) { group_plugin.name == base::ASCIIToUTF16(content::kFlashPluginName)) {
base::FilePath debug_path; base::FilePath system_path;
PathService::Get(chrome::DIR_PEPPER_FLASH_DEBUGGER_PLUGIN, &debug_path); PathService::Get(chrome::DIR_PEPPER_FLASH_SYSTEM_PLUGIN, &system_path);
if (group_plugin.path.DirName() == debug_path) if (group_plugin.path.DirName() == system_path) {
#if defined(GOOGLE_CHROME_BUILD)
// Existing documentation for debugging Flash describe this plugin as
// "Debug" so preserve this nomenclature here.
desc += base::ASCIIToUTF16(" Debug"); desc += base::ASCIIToUTF16(" Debug");
#else
// On Chromium, we can name it what it really is; the system plugin.
desc += base::ASCIIToUTF16(" System");
#endif
}
} }
plugin_file->SetString("description", desc); plugin_file->SetString("description", desc);
......
...@@ -1897,8 +1897,6 @@ ...@@ -1897,8 +1897,6 @@
'browser/browsing_data/browsing_data_flash_lso_helper.h', 'browser/browsing_data/browsing_data_flash_lso_helper.h',
'browser/component_updater/flash_component_installer.h', 'browser/component_updater/flash_component_installer.h',
'browser/component_updater/pepper_flash_component_installer.cc', 'browser/component_updater/pepper_flash_component_installer.cc',
'browser/component_updater/ppapi_utils.cc',
'browser/component_updater/ppapi_utils.h',
'browser/metrics/plugin_metrics_provider.cc', 'browser/metrics/plugin_metrics_provider.cc',
'browser/metrics/plugin_metrics_provider.h', 'browser/metrics/plugin_metrics_provider.h',
'browser/pepper_broker_infobar_delegate.cc', 'browser/pepper_broker_infobar_delegate.cc',
......
...@@ -416,6 +416,8 @@ ...@@ -416,6 +416,8 @@
'sources': [ 'sources': [
'common/pepper_flash.cc', 'common/pepper_flash.cc',
'common/pepper_flash.h', 'common/pepper_flash.h',
'common/ppapi_utils.cc',
'common/ppapi_utils.h',
], ],
}], }],
['enable_plugins==1 and enable_extensions==1', { ['enable_plugins==1 and enable_extensions==1', {
......
...@@ -208,6 +208,8 @@ static_library("common") { ...@@ -208,6 +208,8 @@ static_library("common") {
sources += [ sources += [
"pepper_flash.cc", "pepper_flash.cc",
"pepper_flash.h", "pepper_flash.h",
"ppapi_utils.cc",
"ppapi_utils.h",
] ]
deps += [ "//third_party/adobe/flash:flapper_version_h" ] deps += [ "//third_party/adobe/flash:flapper_version_h" ]
} }
......
...@@ -23,7 +23,9 @@ include_rules = [ ...@@ -23,7 +23,9 @@ include_rules = [
"+google_apis/gaia", # For gaia_switches.h "+google_apis/gaia", # For gaia_switches.h
"+grit", # For generated headers. TODO(thestig): Remove. "+grit", # For generated headers. TODO(thestig): Remove.
"+media", "+media",
"+ppapi/c",
"+ppapi/shared_impl", "+ppapi/shared_impl",
"+ppapi/thunk",
# FIXME - refactor code and remove these dependencies # FIXME - refactor code and remove these dependencies
"+chrome/installer", "+chrome/installer",
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/debug/crash_logging.h" #include "base/debug/crash_logging.h"
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/json/json_reader.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
...@@ -16,10 +17,12 @@ ...@@ -16,10 +17,12 @@
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/common/child_process_logging.h" #include "chrome/common/child_process_logging.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version_info.h" #include "chrome/common/chrome_version_info.h"
#include "chrome/common/crash_keys.h" #include "chrome/common/crash_keys.h"
#include "chrome/common/pepper_flash.h"
#include "chrome/common/render_messages.h" #include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h" #include "chrome/common/url_constants.h"
#include "chrome/grit/common_resources.h" #include "chrome/grit/common_resources.h"
...@@ -314,7 +317,7 @@ content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path, ...@@ -314,7 +317,7 @@ content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
plugin.is_out_of_process = true; plugin.is_out_of_process = true;
plugin.name = content::kFlashPluginName; plugin.name = content::kFlashPluginName;
plugin.path = path; plugin.path = path;
plugin.permissions = kPepperFlashPermissions; plugin.permissions = chrome::kPepperFlashPermissions;
std::vector<std::string> flash_version_numbers; std::vector<std::string> flash_version_numbers;
base::SplitString(version, '.', &flash_version_numbers); base::SplitString(version, '.', &flash_version_numbers);
...@@ -387,7 +390,76 @@ bool GetBundledPepperFlash(content::PepperPluginInfo* plugin) { ...@@ -387,7 +390,76 @@ bool GetBundledPepperFlash(content::PepperPluginInfo* plugin) {
return false; return false;
#endif // FLAPPER_AVAILABLE #endif // FLAPPER_AVAILABLE
} }
#endif // defined(ENABLE_PLUGINS)
#if defined(OS_WIN)
const char kPepperFlashDLLBaseName[] =
#if defined(ARCH_CPU_X86)
"pepflashplayer32_";
#elif defined(ARCH_CPU_X86_64)
"pepflashplayer64_";
#else
#error Unsupported Windows CPU architecture.
#endif // defined(ARCH_CPU_X86)
#endif // defined(OS_WIN)
bool GetSystemPepperFlash(content::PepperPluginInfo* plugin) {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
#if defined(FLAPPER_AVAILABLE)
// If flapper is available, only try system plugin if
// --disable-bundled-ppapi-flash is specified.
if (!command_line->HasSwitch(switches::kDisableBundledPpapiFlash))
return false;
#endif // defined(FLAPPER_AVAILABLE)
// Do not try and find System Pepper Flash if there is a specific path on
// the commmand-line.
if (command_line->HasSwitch(switches::kPpapiFlashPath))
return false;
base::FilePath flash_path;
if (!PathService::Get(chrome::DIR_PEPPER_FLASH_SYSTEM_PLUGIN, &flash_path))
return false;
if (!base::PathExists(flash_path))
return false;
base::FilePath manifest_path(flash_path.AppendASCII("manifest.json"));
std::string manifest_data;
if (!base::ReadFileToString(manifest_path, &manifest_data))
return false;
scoped_ptr<base::Value> manifest_value(
base::JSONReader::Read(manifest_data, base::JSON_ALLOW_TRAILING_COMMAS));
if (!manifest_value.get())
return false;
base::DictionaryValue* manifest = NULL;
if (!manifest_value->GetAsDictionary(&manifest))
return false;
Version version;
if (!chrome::CheckPepperFlashManifest(*manifest, &version))
return false;
#if defined(OS_WIN)
// PepperFlash DLLs on Windows look like basename_v_x_y_z.dll.
std::string filename(kPepperFlashDLLBaseName);
filename.append(version.GetString());
base::ReplaceChars(filename, ".", "_", &filename);
filename.append(".dll");
base::FilePath path(flash_path.Append(base::ASCIIToUTF16(filename)));
#else
// PepperFlash on OS X is called PepperFlashPlayer.plugin
base::FilePath path(flash_path.Append(chrome::kPepperFlashPluginFilename));
#endif
if (!base::PathExists(path))
return false;
*plugin = CreatePepperFlashInfo(path, version.GetString());
return true;
}
#endif // defined(ENABLE_PLUGINS)
std::string GetProduct() { std::string GetProduct() {
chrome::VersionInfo version_info; chrome::VersionInfo version_info;
...@@ -483,6 +555,8 @@ void ChromeContentClient::AddPepperPlugins( ...@@ -483,6 +555,8 @@ void ChromeContentClient::AddPepperPlugins(
content::PepperPluginInfo plugin; content::PepperPluginInfo plugin;
if (GetBundledPepperFlash(&plugin)) if (GetBundledPepperFlash(&plugin))
plugins->push_back(plugin); plugins->push_back(plugin);
if (GetSystemPepperFlash(&plugin))
plugins->push_back(plugin);
#endif #endif
} }
......
...@@ -27,10 +27,20 @@ ...@@ -27,10 +27,20 @@
#include "base/mac/foundation_util.h" #include "base/mac/foundation_util.h"
#endif #endif
#if defined(OS_WIN)
#include "base/win/registry.h"
#endif
#include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
namespace { namespace {
#if defined(OS_WIN)
const wchar_t kFlashRegistryRoot[] = L"SOFTWARE\\Macromedia\\FlashPlayerPepper";
const wchar_t kFlashPlayerPathValueName[] = L"PlayerPath";
#endif
// File name of the internal Flash plugin on different platforms. // File name of the internal Flash plugin on different platforms.
const base::FilePath::CharType kInternalFlashPluginFileName[] = const base::FilePath::CharType kInternalFlashPluginFileName[] =
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
...@@ -46,8 +56,11 @@ const base::FilePath::CharType kPepperFlashBaseDirectory[] = ...@@ -46,8 +56,11 @@ const base::FilePath::CharType kPepperFlashBaseDirectory[] =
FILE_PATH_LITERAL("PepperFlash"); FILE_PATH_LITERAL("PepperFlash");
#if defined(OS_WIN) #if defined(OS_WIN)
const base::FilePath::CharType kPepperFlashDebuggerBaseDirectory[] = const base::FilePath::CharType kPepperFlashSystemBaseDirectory[] =
FILE_PATH_LITERAL("Macromed\\Flash"); FILE_PATH_LITERAL("Macromed\\Flash");
#elif defined(OS_MACOSX)
const base::FilePath::CharType kPepperFlashSystemBaseDirectory[] =
FILE_PATH_LITERAL("Internet Plug-Ins/PepperFlashPlayer");
#endif #endif
const base::FilePath::CharType kInternalNaClPluginFileName[] = const base::FilePath::CharType kInternalNaClPluginFileName[] =
...@@ -104,6 +117,23 @@ bool GetInternalPluginsDirectory(base::FilePath* result) { ...@@ -104,6 +117,23 @@ bool GetInternalPluginsDirectory(base::FilePath* result) {
return PathService::Get(base::DIR_MODULE, result); return PathService::Get(base::DIR_MODULE, result);
} }
#if defined(OS_WIN)
// Gets the Flash path if installed on the system.
bool GetSystemFlashDirectory(base::FilePath* out_path) {
base::win::RegKey path_key(HKEY_LOCAL_MACHINE, kFlashRegistryRoot, KEY_READ);
base::string16 path_str;
if (FAILED(path_key.ReadValue(kFlashPlayerPathValueName, &path_str)))
return false;
base::FilePath plugin_path = base::FilePath(path_str).DirName();
if (!base::PathExists(plugin_path))
return false;
*out_path = plugin_path;
return true;
}
#endif
} // namespace } // namespace
namespace chrome { namespace chrome {
...@@ -261,16 +291,16 @@ bool PathProvider(int key, base::FilePath* result) { ...@@ -261,16 +291,16 @@ bool PathProvider(int key, base::FilePath* result) {
return false; return false;
cur = cur.Append(kPepperFlashBaseDirectory); cur = cur.Append(kPepperFlashBaseDirectory);
break; break;
case chrome::DIR_PEPPER_FLASH_DEBUGGER_PLUGIN: case chrome::DIR_PEPPER_FLASH_SYSTEM_PLUGIN:
#if defined(OS_WIN) #if defined(OS_WIN)
if (!PathService::Get(base::DIR_SYSTEM, &cur)) if (!GetSystemFlashDirectory(&cur))
return false; return false;
cur = cur.Append(kPepperFlashDebuggerBaseDirectory);
#elif defined(OS_MACOSX) #elif defined(OS_MACOSX)
// TODO(luken): finalize Mac OS directory paths, current consensus is if (!GetLocalLibraryDirectory(&cur))
// around /Library/Internet Plug-Ins/PepperFlashPlayer/ return false;
return false; cur = cur.Append(kPepperFlashSystemBaseDirectory);
#else #else
// TODO(wfh): If Adobe release PPAPI binaries for Linux, add support here.
return false; return false;
#endif #endif
break; break;
......
...@@ -72,8 +72,9 @@ enum { ...@@ -72,8 +72,9 @@ enum {
DIR_COMPONENT_UPDATED_PEPPER_FLASH_PLUGIN, // Base directory of the Pepper DIR_COMPONENT_UPDATED_PEPPER_FLASH_PLUGIN, // Base directory of the Pepper
// Flash plugins downloaded by the // Flash plugins downloaded by the
// component updater. // component updater.
DIR_PEPPER_FLASH_DEBUGGER_PLUGIN, // Base directory of the debugging version DIR_PEPPER_FLASH_SYSTEM_PLUGIN, // Base directory of the system version of
// of the Pepper Flash plugin. // the Pepper Flash plugin, downloadable
// from Adobe website.
FILE_RESOURCE_MODULE, // Full path and filename of the module that FILE_RESOURCE_MODULE, // Full path and filename of the module that
// contains embedded resources (version, // contains embedded resources (version,
// strings, images, etc.). // strings, images, etc.).
......
...@@ -2,12 +2,128 @@ ...@@ -2,12 +2,128 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "base/strings/string_split.h"
#include "base/values.h"
#include "base/version.h"
#include "chrome/common/pepper_flash.h" #include "chrome/common/pepper_flash.h"
#include "chrome/common/ppapi_utils.h"
#include "ppapi/c/private/ppb_pdf.h"
#include "ppapi/shared_impl/ppapi_permissions.h" #include "ppapi/shared_impl/ppapi_permissions.h"
namespace chrome {
const int32 kPepperFlashPermissions = ppapi::PERMISSION_DEV | const int32 kPepperFlashPermissions = ppapi::PERMISSION_DEV |
ppapi::PERMISSION_PRIVATE | ppapi::PERMISSION_PRIVATE |
ppapi::PERMISSION_BYPASS_USER_GESTURE | ppapi::PERMISSION_BYPASS_USER_GESTURE |
ppapi::PERMISSION_FLASH; ppapi::PERMISSION_FLASH;
namespace {
// File name of the Pepper Flash component manifest on different platforms.
const char kPepperFlashManifestName[] = "Flapper";
// Name of the Pepper Flash OS in the component manifest.
const char kPepperFlashOperatingSystem[] =
#if defined(OS_MACOSX)
"mac";
#elif defined(OS_WIN)
"win";
#else // OS_LINUX, etc. TODO(viettrungluu): Separate out Chrome OS and Android?
"linux";
#endif
// Name of the Pepper Flash architecture in the component manifest.
const char kPepperFlashArch[] =
#if defined(ARCH_CPU_X86)
"ia32";
#elif defined(ARCH_CPU_X86_64)
"x64";
#else // TODO(viettrungluu): Support an ARM check?
"???";
#endif
// Returns true if the Pepper |interface_name| is implemented by this browser.
// It does not check if the interface is proxied.
bool SupportsPepperInterface(const char* interface_name) {
if (IsSupportedPepperInterface(interface_name))
return true;
// The PDF interface is invisible to SupportsInterface() on the browser
// process because it is provided using PpapiInterfaceFactoryManager. We need
// to check for that as well.
// TODO(cpu): make this more sane.
return (strcmp(interface_name, PPB_PDF_INTERFACE) == 0);
}
// Returns true if this browser implements one of the interfaces given in
// |interface_string|, which is a '|'-separated string of interface names.
bool CheckPepperFlashInterfaceString(const std::string& interface_string) {
std::vector<std::string> interface_names;
base::SplitString(interface_string, '|', &interface_names);
for (size_t i = 0; i < interface_names.size(); i++) {
if (SupportsPepperInterface(interface_names[i].c_str()))
return true;
}
return false;
}
// Returns true if this browser implements all the interfaces that Flash
// specifies in its component installer manifest.
bool CheckPepperFlashInterfaces(const base::DictionaryValue& manifest) {
const base::ListValue* interface_list = NULL;
// We don't *require* an interface list, apparently.
if (!manifest.GetList("x-ppapi-required-interfaces", &interface_list))
return true;
for (size_t i = 0; i < interface_list->GetSize(); i++) {
std::string interface_string;
if (!interface_list->GetString(i, &interface_string))
return false;
if (!CheckPepperFlashInterfaceString(interface_string))
return false;
}
return true;
}
} // namespace
bool CheckPepperFlashManifest(const base::DictionaryValue& manifest,
Version* version_out) {
std::string name;
manifest.GetStringASCII("name", &name);
// TODO(viettrungluu): Support WinFlapper for now, while we change the format
// of the manifest. (Should be safe to remove checks for "WinFlapper" in, say,
// Nov. 2011.) crbug.com/98458
if (name != kPepperFlashManifestName && name != "WinFlapper")
return false;
std::string proposed_version;
manifest.GetStringASCII("version", &proposed_version);
Version version(proposed_version.c_str());
if (!version.IsValid())
return false;
if (!CheckPepperFlashInterfaces(manifest))
return false;
// TODO(viettrungluu): See above TODO.
if (name == "WinFlapper") {
*version_out = version;
return true;
}
std::string os;
manifest.GetStringASCII("x-ppapi-os", &os);
if (os != kPepperFlashOperatingSystem)
return false;
std::string arch;
manifest.GetStringASCII("x-ppapi-arch", &arch);
if (arch != kPepperFlashArch)
return false;
*version_out = version;
return true;
}
} // namespace chrome
...@@ -6,8 +6,17 @@ ...@@ -6,8 +6,17 @@
#define CHROME_COMMON_PEPPER_FLASH_H_ #define CHROME_COMMON_PEPPER_FLASH_H_
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/values.h"
#include "base/version.h"
namespace chrome {
// Permission bits for Pepper Flash. // Permission bits for Pepper Flash.
extern const int32 kPepperFlashPermissions; extern const int32 kPepperFlashPermissions;
// Returns true if this browser is compatible with the given Pepper Flash
// manifest, with the version specified in the manifest in |version_out|.
bool CheckPepperFlashManifest(const base::DictionaryValue& manifest,
base::Version* version_out);
} // namespace chrome
#endif // CHROME_COMMON_PEPPER_FLASH_H_ #endif // CHROME_COMMON_PEPPER_FLASH_H_
// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/component_updater/ppapi_utils.h" #include "chrome/common/ppapi_utils.h"
#include <cstring> #include <cstring>
......
// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef CHROME_BROWSER_COMPONENT_UPDATER_PPAPI_UTILS_H_ #ifndef CHROME_COMMON_PPAPI_UTILS_H_
#define CHROME_BROWSER_COMPONENT_UPDATER_PPAPI_UTILS_H_ #define CHROME_COMMON_PPAPI_UTILS_H_
// Returns true if the interface name passed in is supported by the // Returns true if the interface name passed in is supported by the
// browser. // browser.
bool IsSupportedPepperInterface(const char* name); bool IsSupportedPepperInterface(const char* name);
#endif // CHROME_BROWSER_COMPONENT_UPDATER_PPAPI_UTILS_H_ #endif // CHROME_COMMON_PPAPI_UTILS_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment