diff --git a/cef.gyp b/cef.gyp index b9c2335cb..d6b860f4b 100644 --- a/cef.gyp +++ b/cef.gyp @@ -864,6 +864,7 @@ '<(DEPTH)/components/components.gyp:keyed_service_content', '<(DEPTH)/components/components.gyp:keyed_service_core', '<(DEPTH)/components/components.gyp:navigation_interception', + '<(DEPTH)/components/components.gyp:pdf_renderer', '<(DEPTH)/components/components.gyp:pref_registry', '<(DEPTH)/components/components.gyp:printing_common', '<(DEPTH)/components/components.gyp:printing_renderer', @@ -878,6 +879,7 @@ '<(DEPTH)/content/content.gyp:content_renderer', '<(DEPTH)/content/content.gyp:content_resources', '<(DEPTH)/content/content.gyp:content_utility', + '<(DEPTH)/crypto/crypto.gyp:crypto', '<(DEPTH)/gpu/gpu.gyp:gpu', '<(DEPTH)/ipc/ipc.gyp:ipc', '<(DEPTH)/media/blink/media_blink.gyp:media_blink', @@ -969,6 +971,11 @@ 'libcef/browser/origin_whitelist_impl.cc', 'libcef/browser/origin_whitelist_impl.h', 'libcef/browser/path_util_impl.cc', + 'libcef/browser/pepper/browser_pepper_host_factory.cc', + 'libcef/browser/pepper/browser_pepper_host_factory.h', + 'libcef/browser/pepper/pepper_flash_browser_host.cc', + 'libcef/browser/pepper/pepper_flash_browser_host.h', + 'libcef/browser/pepper/device_id_fetcher.cc', 'libcef/browser/print_settings_impl.cc', 'libcef/browser/print_settings_impl.h', 'libcef/browser/printing/printing_message_filter.cc', @@ -1096,6 +1103,10 @@ 'libcef/renderer/dom_node_impl.h', 'libcef/renderer/frame_impl.cc', 'libcef/renderer/frame_impl.h', + 'libcef/renderer/pepper/pepper_helper.cc', + 'libcef/renderer/pepper/pepper_helper.h', + 'libcef/renderer/pepper/renderer_pepper_host_factory.cc', + 'libcef/renderer/pepper/renderer_pepper_host_factory.h', 'libcef/renderer/render_frame_observer.cc', 'libcef/renderer/render_frame_observer.h', 'libcef/renderer/render_message_filter.cc', @@ -1176,6 +1187,7 @@ '<(DEPTH)/chrome/browser/spellchecker/spelling_service_client.cc', '<(DEPTH)/chrome/browser/spellchecker/spelling_service_client.h', '<(DEPTH)/chrome/common/chrome_constants.cc', + '<(DEPTH)/chrome/common/chrome_constants.h', '<(DEPTH)/chrome/common/spellcheck_common.cc', '<(DEPTH)/chrome/common/spellcheck_common.h', '<(DEPTH)/chrome/common/spellcheck_marker.h', @@ -1194,6 +1206,25 @@ '<(DEPTH)/chrome/renderer/spellchecker/spellcheck_worditerator.cc', '<(DEPTH)/chrome/renderer/spellchecker/spellcheck_worditerator.h', '<(DEPTH)/chrome/renderer/spellchecker/spelling_engine.h', + # Include sources for pepper flash support. + '<(DEPTH)/chrome/common/pepper_flash.cc', + '<(DEPTH)/chrome/common/pepper_flash.h', + '<(DEPTH)/chrome/common/ppapi_utils.cc', + '<(DEPTH)/chrome/common/ppapi_utils.h', + '<(DEPTH)/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc', + '<(DEPTH)/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h', + '<(DEPTH)/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.cc', + '<(DEPTH)/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.h', + '<(DEPTH)/chrome/renderer/pepper/pepper_flash_drm_renderer_host.cc', + '<(DEPTH)/chrome/renderer/pepper/pepper_flash_drm_renderer_host.h', + '<(DEPTH)/chrome/renderer/pepper/pepper_flash_font_file_host.cc', + '<(DEPTH)/chrome/renderer/pepper/pepper_flash_font_file_host.h', + '<(DEPTH)/chrome/renderer/pepper/pepper_flash_fullscreen_host.cc', + '<(DEPTH)/chrome/renderer/pepper/pepper_flash_fullscreen_host.h', + '<(DEPTH)/chrome/renderer/pepper/pepper_flash_menu_host.cc', + '<(DEPTH)/chrome/renderer/pepper/pepper_flash_menu_host.h', + '<(DEPTH)/chrome/renderer/pepper/pepper_flash_renderer_host.cc', + '<(DEPTH)/chrome/renderer/pepper/pepper_flash_renderer_host.h', ], 'conditions': [ ['OS=="win"', { @@ -1228,6 +1259,8 @@ 'libcef/browser/render_widget_host_view_osr_mac.mm', 'libcef/browser/text_input_client_osr_mac.mm', 'libcef/browser/text_input_client_osr_mac.h', + 'libcef/common/util_mac.h', + 'libcef/common/util_mac.mm', # Include sources for spell checking support. '<(DEPTH)/chrome/browser/spellchecker/spellcheck_message_filter_mac.cc', '<(DEPTH)/chrome/browser/spellchecker/spellcheck_message_filter_mac.h', @@ -1235,6 +1268,9 @@ '<(DEPTH)/chrome/browser/spellchecker/spellcheck_platform_mac.mm', '<(DEPTH)/chrome/renderer/spellchecker/cocoa_spelling_engine_mac.cc', '<(DEPTH)/chrome/renderer/spellchecker/cocoa_spelling_engine_mac.h', + # Include sources for pepper flash support. + '<(DEPTH)/chrome/browser/renderer_host/pepper/monitor_finder_mac.h', + '<(DEPTH)/chrome/browser/renderer_host/pepper/monitor_finder_mac.mm', ], }], [ 'OS=="linux" or OS=="freebsd" or OS=="openbsd"', { @@ -1757,4 +1793,4 @@ ], }], # OS=="win" ], -} \ No newline at end of file +} diff --git a/libcef/browser/browser_host_impl.cc b/libcef/browser/browser_host_impl.cc index 18326c4dd..e72eab769 100644 --- a/libcef/browser/browser_host_impl.cc +++ b/libcef/browser/browser_host_impl.cc @@ -2394,6 +2394,17 @@ void CefBrowserHostImpl::RequestMediaAccessPermission( scoped_ptr()); } +bool CefBrowserHostImpl::CheckMediaAccessPermission( + content::WebContents* web_contents, + const GURL& security_origin, + content::MediaStreamType type) { + // Check media access permission without prompting the user. This is called + // when loading the Pepper Flash plugin. + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); + return command_line->HasSwitch(switches::kEnableMediaStream); +} + // content::WebContentsObserver methods. // ----------------------------------------------------------------------------- diff --git a/libcef/browser/browser_host_impl.h b/libcef/browser/browser_host_impl.h index d6e9b256a..374cff8bd 100644 --- a/libcef/browser/browser_host_impl.h +++ b/libcef/browser/browser_host_impl.h @@ -415,6 +415,9 @@ class CefBrowserHostImpl : public CefBrowserHost, content::WebContents* web_contents, const content::MediaStreamRequest& request, const content::MediaResponseCallback& callback) override; + bool CheckMediaAccessPermission(content::WebContents* web_contents, + const GURL& security_origin, + content::MediaStreamType type) override; // content::WebContentsObserver methods. using content::WebContentsObserver::BeforeUnloadFired; diff --git a/libcef/browser/browser_pref_store.cc b/libcef/browser/browser_pref_store.cc index 3a5834fe7..f2c10a442 100644 --- a/libcef/browser/browser_pref_store.cc +++ b/libcef/browser/browser_pref_store.cc @@ -92,6 +92,7 @@ scoped_ptr CefBrowserPrefStore::CreateService() { registry->RegisterBooleanPref(prefs::kPrintingEnabled, true); // Spell checking settings. + // Based on SpellcheckServiceFactory::RegisterProfilePrefs. std::string spellcheck_lang = command_line->GetSwitchValueASCII(switches::kOverrideSpellCheckLang); if (!spellcheck_lang.empty()) { @@ -110,6 +111,11 @@ scoped_ptr CefBrowserPrefStore::CreateService() { registry->RegisterBooleanPref(prefs::kEnableAutoSpellCorrect, command_line->HasSwitch(switches::kEnableSpellingAutoCorrect)); + // Pepper flash settings. + // Based on DeviceIDFetcher::RegisterProfilePrefs. + registry->RegisterBooleanPref(prefs::kEnableDRM, false); + registry->RegisterStringPref(prefs::kDRMSalt, ""); + return factory.Create(registry.get()); } diff --git a/libcef/browser/content_browser_client.cc b/libcef/browser/content_browser_client.cc index 6221f69b6..2f7f6002c 100644 --- a/libcef/browser/content_browser_client.cc +++ b/libcef/browser/content_browser_client.cc @@ -15,6 +15,7 @@ #include "libcef/browser/context.h" #include "libcef/browser/devtools_delegate.h" #include "libcef/browser/media_capture_devices_dispatcher.h" +#include "libcef/browser/pepper/browser_pepper_host_factory.h" #include "libcef/browser/printing/printing_message_filter.h" #include "libcef/browser/resource_dispatcher_host_delegate.h" #include "libcef/browser/speech_recognition_manager_delegate.h" @@ -658,6 +659,10 @@ void CefContentBrowserClient::AppendExtraCommandLineSwitches( switches::kDisableSpellChecking, switches::kEnableSpeechInput, switches::kEnableSpellingAutoCorrect, + switches::kEnableSystemFlash, + switches::kPpapiFlashArgs, + switches::kPpapiFlashPath, + switches::kPpapiFlashVersion, switches::kUncaughtExceptionStackSize, }; command_line->CopySwitchesFrom(*browser_cmd, kSwitchNames, @@ -665,13 +670,23 @@ void CefContentBrowserClient::AppendExtraCommandLineSwitches( } #if defined(OS_LINUX) - if (process_type == switches::kZygoteProcess && - browser_cmd->HasSwitch(switches::kBrowserSubprocessPath)) { - // Force use of the sub-process executable path for the zygote process. - const base::FilePath& subprocess_path = - browser_cmd->GetSwitchValuePath(switches::kBrowserSubprocessPath); - if (!subprocess_path.empty()) - command_line->SetProgram(subprocess_path); + if (process_type == switches::kZygoteProcess) { + // Propagate the following switches to the zygone command line (along with + // any associated values) if present in the browser command line. + static const char* const kSwitchNames[] = { + switches::kPpapiFlashPath, + switches::kPpapiFlashVersion, + }; + command_line->CopySwitchesFrom(*browser_cmd, kSwitchNames, + arraysize(kSwitchNames)); + + if (browser_cmd->HasSwitch(switches::kBrowserSubprocessPath)) { + // Force use of the sub-process executable path for the zygote process. + const base::FilePath& subprocess_path = + browser_cmd->GetSwitchValuePath(switches::kBrowserSubprocessPath); + if (!subprocess_path.empty()) + command_line->SetProgram(subprocess_path); + } } #endif // defined(OS_LINUX) @@ -965,6 +980,13 @@ std::string CefContentBrowserClient::GetDefaultDownloadName() { return "download"; } +void CefContentBrowserClient::DidCreatePpapiPlugin( + content::BrowserPpapiHost* browser_host) { + browser_host->GetPpapiHost()->AddHostFactoryFilter( + scoped_ptr( + new CefBrowserPepperHostFactory(browser_host))); +} + content::DevToolsManagerDelegate* CefContentBrowserClient::GetDevToolsManagerDelegate() { return new CefDevToolsManagerDelegate(); diff --git a/libcef/browser/content_browser_client.h b/libcef/browser/content_browser_client.h index 822d415d4..a6323f0cd 100644 --- a/libcef/browser/content_browser_client.h +++ b/libcef/browser/content_browser_client.h @@ -138,6 +138,7 @@ class CefContentBrowserClient : public content::ContentBrowserClient { void BrowserURLHandlerCreated( content::BrowserURLHandler* handler) override; std::string GetDefaultDownloadName() override; + void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) override; content::DevToolsManagerDelegate* GetDevToolsManagerDelegate() override; diff --git a/libcef/browser/pepper/browser_pepper_host_factory.cc b/libcef/browser/pepper/browser_pepper_host_factory.cc new file mode 100644 index 000000000..30d10f22b --- /dev/null +++ b/libcef/browser/pepper/browser_pepper_host_factory.cc @@ -0,0 +1,60 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "libcef/browser/pepper/browser_pepper_host_factory.h" + +#include "libcef/browser/pepper/pepper_flash_browser_host.h" + +#include "build/build_config.h" +#include "chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h" +#include "chrome/browser/renderer_host/pepper/pepper_flash_drm_host.h" +#include "content/public/browser/browser_ppapi_host.h" +#include "ppapi/host/message_filter_host.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/host/resource_host.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/ppapi_permissions.h" + +using ppapi::host::MessageFilterHost; +using ppapi::host::ResourceHost; +using ppapi::host::ResourceMessageFilter; + +CefBrowserPepperHostFactory::CefBrowserPepperHostFactory( + content::BrowserPpapiHost* host) + : host_(host) {} + +CefBrowserPepperHostFactory::~CefBrowserPepperHostFactory() {} + +scoped_ptr CefBrowserPepperHostFactory::CreateResourceHost( + ppapi::host::PpapiHost* host, + PP_Resource resource, + PP_Instance instance, + const IPC::Message& message) { + DCHECK(host == host_->GetPpapiHost()); + + // Make sure the plugin is giving us a valid instance for this resource. + if (!host_->IsValidInstance(instance)) + return scoped_ptr(); + + // Flash interfaces. + if (host_->GetPpapiHost()->permissions().HasPermission( + ppapi::PERMISSION_FLASH)) { + switch (message.type()) { + case PpapiHostMsg_Flash_Create::ID: + return scoped_ptr( + new PepperFlashBrowserHost(host_, instance, resource)); + case PpapiHostMsg_FlashClipboard_Create::ID: { + scoped_refptr clipboard_filter( + new chrome::PepperFlashClipboardMessageFilter); + return scoped_ptr(new MessageFilterHost( + host_->GetPpapiHost(), instance, resource, clipboard_filter)); + } + case PpapiHostMsg_FlashDRM_Create::ID: + return scoped_ptr( + new chrome::PepperFlashDRMHost(host_, instance, resource)); + } + } + + return scoped_ptr(); +} diff --git a/libcef/browser/pepper/browser_pepper_host_factory.h b/libcef/browser/pepper/browser_pepper_host_factory.h new file mode 100644 index 000000000..783338881 --- /dev/null +++ b/libcef/browser/pepper/browser_pepper_host_factory.h @@ -0,0 +1,34 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CEF_LIBCEF_BROWSER_PEPPER_BROWSER_PEPPER_HOST_FACTORY_H_ +#define CEF_LIBCEF_BROWSER_PEPPER_BROWSER_PEPPER_HOST_FACTORY_H_ + +#include "base/compiler_specific.h" +#include "ppapi/host/host_factory.h" + +namespace content { +class BrowserPpapiHost; +} // namespace content + +class CefBrowserPepperHostFactory : public ppapi::host::HostFactory { + public: + // Non-owning pointer to the filter must outlive this class. + explicit CefBrowserPepperHostFactory(content::BrowserPpapiHost* host); + ~CefBrowserPepperHostFactory() override; + + scoped_ptr CreateResourceHost( + ppapi::host::PpapiHost* host, + PP_Resource resource, + PP_Instance instance, + const IPC::Message& message) override; + + private: + // Non-owning pointer. + content::BrowserPpapiHost* host_; + + DISALLOW_COPY_AND_ASSIGN(CefBrowserPepperHostFactory); +}; + +#endif // CEF_LIBCEF_BROWSER_PEPPER_BROWSER_PEPPER_HOST_FACTORY_H_ diff --git a/libcef/browser/pepper/device_id_fetcher.cc b/libcef/browser/pepper/device_id_fetcher.cc new file mode 100644 index 000000000..18ab52c58 --- /dev/null +++ b/libcef/browser/pepper/device_id_fetcher.cc @@ -0,0 +1,219 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/renderer_host/pepper/device_id_fetcher.h" + +#include "base/files/file_util.h" +#include "base/prefs/pref_service.h" +#include "base/strings/string_number_conversions.h" +#include "chrome/common/pref_names.h" +#if defined(OS_CHROMEOS) +#include "chromeos/cryptohome/system_salt_getter.h" +#endif +#include "components/pref_registry/pref_registry_syncable.h" +#include "components/user_prefs/user_prefs.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_ppapi_host.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_process_host.h" +#include "crypto/encryptor.h" +#include "crypto/random.h" +#include "crypto/sha2.h" +#include "ppapi/c/pp_errors.h" +#if defined(ENABLE_RLZ) +#include "rlz/lib/machine_id.h" +#endif + +using content::BrowserPpapiHost; +using content::BrowserThread; +using content::RenderProcessHost; + +namespace chrome { + +namespace { + +const char kDRMIdentifierFile[] = "Pepper DRM ID.0"; + +const uint32_t kSaltLength = 32; + +void GetMachineIDAsync( + const base::Callback& callback) { +#if defined(OS_WIN) && defined(ENABLE_RLZ) + std::string result; + rlz_lib::GetMachineId(&result); + callback.Run(result); +#elif defined(OS_CHROMEOS) + chromeos::SystemSaltGetter::Get()->GetSystemSalt(callback); +#else + // Not implemented for other platforms. + NOTREACHED(); + callback.Run(std::string()); +#endif +} + +} // namespace + +DeviceIDFetcher::DeviceIDFetcher(int render_process_id) + : in_progress_(false), render_process_id_(render_process_id) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); +} + +DeviceIDFetcher::~DeviceIDFetcher() {} + +bool DeviceIDFetcher::Start(const IDCallback& callback) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + if (in_progress_) + return false; + + in_progress_ = true; + callback_ = callback; + + BrowserThread::PostTask( + BrowserThread::UI, + FROM_HERE, + base::Bind(&DeviceIDFetcher::CheckPrefsOnUIThread, this)); + return true; +} + +// static +void DeviceIDFetcher::RegisterProfilePrefs( + user_prefs::PrefRegistrySyncable* prefs) { + prefs->RegisterBooleanPref(prefs::kEnableDRM, + true, + user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); + prefs->RegisterStringPref( + prefs::kDRMSalt, "", user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); +} + +// static +base::FilePath DeviceIDFetcher::GetLegacyDeviceIDPath( + const base::FilePath& profile_path) { + return profile_path.AppendASCII(kDRMIdentifierFile); +} + +void DeviceIDFetcher::CheckPrefsOnUIThread() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + RenderProcessHost* render_process_host = + RenderProcessHost::FromID(render_process_id_); + content::BrowserContext* browser_context = NULL; + if (render_process_host) + browser_context = render_process_host->GetBrowserContext(); + + PrefService* prefs = NULL; + if (browser_context) { + prefs = user_prefs::UserPrefs::Get(browser_context); + DCHECK(prefs); + } + + if (!browser_context || browser_context->IsOffTheRecord() || + !prefs->GetBoolean(prefs::kEnableDRM)) { + RunCallbackOnIOThread(std::string(), PP_ERROR_NOACCESS); + return; + } + + // Check if the salt pref is set. If it isn't, set it. + std::string salt = prefs->GetString(prefs::kDRMSalt); + if (salt.empty()) { + uint8_t salt_bytes[kSaltLength]; + crypto::RandBytes(salt_bytes, arraysize(salt_bytes)); + // Since it will be stored in a string pref, convert it to hex. + salt = base::HexEncode(salt_bytes, arraysize(salt_bytes)); + prefs->SetString(prefs::kDRMSalt, salt); + } + +#if defined(OS_CHROMEOS) + // Try the legacy path first for ChromeOS. We pass the new salt in as well + // in case the legacy id doesn't exist. + BrowserThread::PostBlockingPoolTask( + FROM_HERE, + base::Bind(&DeviceIDFetcher::LegacyComputeOnBlockingPool, + this, + profile->GetPath(), + salt)); +#else + // Get the machine ID and call ComputeOnUIThread with salt + machine_id. + GetMachineIDAsync( + base::Bind(&DeviceIDFetcher::ComputeOnUIThread, this, salt)); +#endif +} + +void DeviceIDFetcher::ComputeOnUIThread(const std::string& salt, + const std::string& machine_id) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + if (machine_id.empty()) { + LOG(ERROR) << "Empty machine id"; + RunCallbackOnIOThread(std::string(), PP_ERROR_FAILED); + return; + } + + // Build the identifier as follows: + // SHA256(machine-id||service||SHA256(machine-id||service||salt)) + std::vector salt_bytes; + if (!base::HexStringToBytes(salt, &salt_bytes)) + salt_bytes.clear(); + if (salt_bytes.size() != kSaltLength) { + LOG(ERROR) << "Unexpected salt bytes length: " << salt_bytes.size(); + RunCallbackOnIOThread(std::string(), PP_ERROR_FAILED); + return; + } + + char id_buf[256 / 8]; // 256-bits for SHA256 + std::string input = machine_id; + input.append(kDRMIdentifierFile); + input.append(salt_bytes.begin(), salt_bytes.end()); + crypto::SHA256HashString(input, &id_buf, sizeof(id_buf)); + std::string id = base::StringToLowerASCII( + base::HexEncode(reinterpret_cast(id_buf), sizeof(id_buf))); + input = machine_id; + input.append(kDRMIdentifierFile); + input.append(id); + crypto::SHA256HashString(input, &id_buf, sizeof(id_buf)); + id = base::StringToLowerASCII( + base::HexEncode(reinterpret_cast(id_buf), sizeof(id_buf))); + + RunCallbackOnIOThread(id, PP_OK); +} + +// TODO(raymes): This is temporary code to migrate ChromeOS devices to the new +// scheme for generating device IDs. Delete this once we are sure most ChromeOS +// devices have been migrated. +void DeviceIDFetcher::LegacyComputeOnBlockingPool( + const base::FilePath& profile_path, + const std::string& salt) { + std::string id; + // First check if the legacy device ID file exists on ChromeOS. If it does, we + // should just return that. + base::FilePath id_path = GetLegacyDeviceIDPath(profile_path); + if (base::PathExists(id_path)) { + if (base::ReadFileToString(id_path, &id) && !id.empty()) { + RunCallbackOnIOThread(id, PP_OK); + return; + } + } + // If we didn't find an ID, get the machine ID and call the new code path to + // generate an ID. + BrowserThread::PostTask( + BrowserThread::UI, + FROM_HERE, + base::Bind(&GetMachineIDAsync, + base::Bind(&DeviceIDFetcher::ComputeOnUIThread, this, salt))); +} + +void DeviceIDFetcher::RunCallbackOnIOThread(const std::string& id, + int32_t result) { + if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { + BrowserThread::PostTask( + BrowserThread::IO, + FROM_HERE, + base::Bind(&DeviceIDFetcher::RunCallbackOnIOThread, this, id, result)); + return; + } + in_progress_ = false; + callback_.Run(id, result); +} + +} // namespace chrome diff --git a/libcef/browser/pepper/pepper_flash_browser_host.cc b/libcef/browser/pepper/pepper_flash_browser_host.cc new file mode 100644 index 000000000..2ef7fce11 --- /dev/null +++ b/libcef/browser/pepper/pepper_flash_browser_host.cc @@ -0,0 +1,134 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "libcef/browser/pepper/pepper_flash_browser_host.h" + +#include "base/time/time.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_ppapi_host.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_process_host.h" +#include "ipc/ipc_message_macros.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/private/ppb_flash.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/resource_message_params.h" +#include "ppapi/shared_impl/time_conversion.h" +#include "url/gurl.h" + +#if defined(OS_WIN) +#include +#elif defined(OS_MACOSX) +#include +#endif + +using content::BrowserPpapiHost; +using content::BrowserThread; +using content::RenderProcessHost; + +namespace { + +// Returns true if the page identified by (|url|, |first_party_url|) is allowed +// to read cookies. +bool IsReadingCookieAllowed(const GURL& url, + const GURL& first_party_url) { + return true; +} + +// Returns true if the cookie set by a page identified by |url| should be +// session only. +bool IsCookieSessionOnly(const GURL& url) { + return false; +} + +} // namespace + +PepperFlashBrowserHost::PepperFlashBrowserHost(BrowserPpapiHost* host, + PP_Instance instance, + PP_Resource resource) + : ResourceHost(host->GetPpapiHost(), instance, resource), + host_(host) { + int unused; + host->GetRenderFrameIDsForInstance(instance, &render_process_id_, &unused); +} + +PepperFlashBrowserHost::~PepperFlashBrowserHost() {} + +int32_t PepperFlashBrowserHost::OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) { + PPAPI_BEGIN_MESSAGE_MAP(PepperFlashBrowserHost, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Flash_UpdateActivity, + OnUpdateActivity) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_GetLocalTimeZoneOffset, + OnGetLocalTimeZoneOffset) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( + PpapiHostMsg_Flash_GetLocalDataRestrictions, OnGetLocalDataRestrictions) + PPAPI_END_MESSAGE_MAP() + return PP_ERROR_FAILED; +} + +int32_t PepperFlashBrowserHost::OnUpdateActivity( + ppapi::host::HostMessageContext* host_context) { +#if defined(OS_WIN) + // Reading then writing back the same value to the screensaver timeout system + // setting resets the countdown which prevents the screensaver from turning + // on "for a while". As long as the plugin pings us with this message faster + // than the screensaver timeout, it won't go on. + int value = 0; + if (SystemParametersInfo(SPI_GETSCREENSAVETIMEOUT, 0, &value, 0)) + SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT, value, NULL, 0); +#elif defined(OS_MACOSX) + UpdateSystemActivity(OverallAct); +#else +// TODO(brettw) implement this for other platforms. +#endif + return PP_OK; +} + +int32_t PepperFlashBrowserHost::OnGetLocalTimeZoneOffset( + ppapi::host::HostMessageContext* host_context, + const base::Time& t) { + // The reason for this processing being in the browser process is that on + // Linux, the localtime calls require filesystem access prohibited by the + // sandbox. + host_context->reply_msg = PpapiPluginMsg_Flash_GetLocalTimeZoneOffsetReply( + ppapi::PPGetLocalTimeZoneOffset(t)); + return PP_OK; +} + +int32_t PepperFlashBrowserHost::OnGetLocalDataRestrictions( + ppapi::host::HostMessageContext* context) { + // Getting the Flash LSO settings requires using the CookieSettings which + // belong to the profile which lives on the UI thread. We lazily initialize + // |cookie_settings_| by grabbing the reference from the UI thread and then + // call |GetLocalDataRestrictions| with it. + GURL document_url = host_->GetDocumentURLForInstance(pp_instance()); + GURL plugin_url = host_->GetPluginURLForInstance(pp_instance()); + GetLocalDataRestrictions(context->MakeReplyMessageContext(), + document_url, + plugin_url); + return PP_OK_COMPLETIONPENDING; +} + +void PepperFlashBrowserHost::GetLocalDataRestrictions( + ppapi::host::ReplyMessageContext reply_context, + const GURL& document_url, + const GURL& plugin_url) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + PP_FlashLSORestrictions restrictions = PP_FLASHLSORESTRICTIONS_NONE; + if (document_url.is_valid() && plugin_url.is_valid()) { + // TODO(cef): Determine how to properly handle these permissions. In Chrome + // they're handled via CookieSettings associated with a Profile. + if (!IsReadingCookieAllowed(document_url, plugin_url)) + restrictions = PP_FLASHLSORESTRICTIONS_BLOCK; + else if (IsCookieSessionOnly(plugin_url)) + restrictions = PP_FLASHLSORESTRICTIONS_IN_MEMORY; + } + SendReply(reply_context, + PpapiPluginMsg_Flash_GetLocalDataRestrictionsReply( + static_cast(restrictions))); +} diff --git a/libcef/browser/pepper/pepper_flash_browser_host.h b/libcef/browser/pepper/pepper_flash_browser_host.h new file mode 100644 index 000000000..11897a408 --- /dev/null +++ b/libcef/browser/pepper/pepper_flash_browser_host.h @@ -0,0 +1,54 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CEF_LIBCEF_BROWSER_PEPPER_PEPPER_FLASH_BROWSER_HOST_H_ +#define CEF_LIBCEF_BROWSER_PEPPER_PEPPER_FLASH_BROWSER_HOST_H_ + +#include "base/basictypes.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/host/resource_host.h" + +namespace base { +class Time; +} + +namespace content { +class BrowserPpapiHost; +class ResourceContext; +} + +class GURL; + +class PepperFlashBrowserHost : public ppapi::host::ResourceHost { + public: + PepperFlashBrowserHost(content::BrowserPpapiHost* host, + PP_Instance instance, + PP_Resource resource); + ~PepperFlashBrowserHost() override; + + // ppapi::host::ResourceHost override. + int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) override; + + private: + int32_t OnUpdateActivity(ppapi::host::HostMessageContext* host_context); + int32_t OnGetLocalTimeZoneOffset( + ppapi::host::HostMessageContext* host_context, + const base::Time& t); + int32_t OnGetLocalDataRestrictions(ppapi::host::HostMessageContext* context); + + void GetLocalDataRestrictions(ppapi::host::ReplyMessageContext reply_context, + const GURL& document_url, + const GURL& plugin_url); + + content::BrowserPpapiHost* host_; + int render_process_id_; + + DISALLOW_COPY_AND_ASSIGN(PepperFlashBrowserHost); +}; + +#endif // CEF_LIBCEF_BROWSER_PEPPER_PEPPER_FLASH_BROWSER_HOST_H_ diff --git a/libcef/common/cef_switches.cc b/libcef/common/cef_switches.cc index 898696537..fa189d68d 100644 --- a/libcef/common/cef_switches.cc +++ b/libcef/common/cef_switches.cc @@ -94,4 +94,7 @@ const char kEnableSpellingService[] = "enable-spelling-service"; // Override the default spellchecking language which comes from locales.pak. const char kOverrideSpellCheckLang[] = "override-spell-check-lang"; +// Enable detection and use of a system-wide Pepper Flash install. +const char kEnableSystemFlash[] = "enable-system-flash"; + } // namespace switches diff --git a/libcef/common/cef_switches.h b/libcef/common/cef_switches.h index ddd96bde3..c5f15b00a 100644 --- a/libcef/common/cef_switches.h +++ b/libcef/common/cef_switches.h @@ -41,6 +41,7 @@ extern const char kCrashDumpsDir[]; extern const char kDisableSpellChecking[]; extern const char kEnableSpellingService[]; extern const char kOverrideSpellCheckLang[]; +extern const char kEnableSystemFlash[]; } // namespace switches diff --git a/libcef/common/content_client.cc b/libcef/common/content_client.cc index 5e49eafc3..413ccea14 100644 --- a/libcef/common/content_client.cc +++ b/libcef/common/content_client.cc @@ -6,22 +6,160 @@ #include "include/cef_stream.h" #include "include/cef_version.h" #include "libcef/browser/content_browser_client.h" +#include "libcef/common/cef_switches.h" #include "libcef/common/scheme_registrar_impl.h" #include "libcef/common/scheme_registration.h" #include "base/command_line.h" #include "base/logging.h" +#include "base/path_service.h" +#include "base/files/file_util.h" +#include "base/json/json_reader.h" #include "base/strings/string_piece.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" #include "base/strings/stringprintf.h" +#include "base/strings/utf_string_conversions.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/pepper_flash.h" +#include "content/public/common/content_constants.h" #include "content/public/common/content_switches.h" +#include "content/public/common/pepper_plugin_info.h" #include "content/public/common/user_agent.h" #include "ui/base/resource/resource_bundle.h" + namespace { CefContentClient* g_content_client = NULL; +// The following Flash-related methods are from +// chrome/common/chrome_content_client.cc + +content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path, + const std::string& version) { + content::PepperPluginInfo plugin; + + plugin.is_out_of_process = true; + plugin.name = content::kFlashPluginName; + plugin.path = path; + plugin.permissions = chrome::kPepperFlashPermissions; + + std::vector flash_version_numbers; + base::SplitString(version, '.', &flash_version_numbers); + if (flash_version_numbers.size() < 1) + flash_version_numbers.push_back("11"); + // |SplitString()| puts in an empty string given an empty string. :( + else if (flash_version_numbers[0].empty()) + flash_version_numbers[0] = "11"; + if (flash_version_numbers.size() < 2) + flash_version_numbers.push_back("2"); + if (flash_version_numbers.size() < 3) + flash_version_numbers.push_back("999"); + if (flash_version_numbers.size() < 4) + flash_version_numbers.push_back("999"); + // E.g., "Shockwave Flash 10.2 r154": + plugin.description = plugin.name + " " + flash_version_numbers[0] + "." + + flash_version_numbers[1] + " r" + flash_version_numbers[2]; + plugin.version = JoinString(flash_version_numbers, '.'); + content::WebPluginMimeType swf_mime_type(content::kFlashPluginSwfMimeType, + content::kFlashPluginSwfExtension, + content::kFlashPluginSwfDescription); + plugin.mime_types.push_back(swf_mime_type); + content::WebPluginMimeType spl_mime_type(content::kFlashPluginSplMimeType, + content::kFlashPluginSplExtension, + content::kFlashPluginSplDescription); + plugin.mime_types.push_back(spl_mime_type); + + return plugin; +} + +void AddPepperFlashFromCommandLine( + std::vector* plugins) { + const base::CommandLine::StringType flash_path = + base::CommandLine::ForCurrentProcess()->GetSwitchValueNative( + switches::kPpapiFlashPath); + if (flash_path.empty()) + return; + + // Also get the version from the command-line. Should be something like 11.2 + // or 11.2.123.45. + std::string flash_version = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kPpapiFlashVersion); + + plugins->push_back( + CreatePepperFlashInfo(base::FilePath(flash_path), flash_version)); +} + +#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 (!command_line->HasSwitch(switches::kEnableSystemFlash)) + return false; + + // 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 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; +} + } // namespace CefContentClient::CefContentClient(CefRefPtr application) @@ -42,6 +180,15 @@ CefContentClient* CefContentClient::Get() { return g_content_client; } +void CefContentClient::AddPepperPlugins( + std::vector* plugins) { + AddPepperFlashFromCommandLine(plugins); + + content::PepperPluginInfo plugin; + if (GetSystemPepperFlash(&plugin)) + plugins->push_back(plugin); +} + void CefContentClient::AddAdditionalSchemes( std::vector* standard_schemes, std::vector* savable_schemes) { diff --git a/libcef/common/content_client.h b/libcef/common/content_client.h index ea8656045..3ff4cc22d 100644 --- a/libcef/common/content_client.h +++ b/libcef/common/content_client.h @@ -26,6 +26,8 @@ class CefContentClient : public content::ContentClient, static CefContentClient* Get(); // content::ContentClient methods. + void AddPepperPlugins( + std::vector* plugins) override; void AddAdditionalSchemes( std::vector* standard_schemes, std::vector* savable_schemes) override; diff --git a/libcef/common/main_delegate.cc b/libcef/common/main_delegate.cc index 877d88306..025eb71f3 100644 --- a/libcef/common/main_delegate.cc +++ b/libcef/common/main_delegate.cc @@ -34,10 +34,12 @@ #if defined(OS_WIN) #include // NOLINT(build/include_order) +#include "base/win/registry.h" #include "components/crash/app/breakpad_win.h" #endif #if defined(OS_MACOSX) +#include "libcef/common/util_mac.h" #include "base/mac/os_crash_dumps.h" #include "base/mac/bundle_locations.h" #include "base/mac/foundation_util.h" @@ -114,6 +116,47 @@ base::FilePath GetResourcesFilePath() { #endif // !defined(OS_MACOSX) +#if defined(OS_WIN) + +const wchar_t kFlashRegistryRoot[] = L"SOFTWARE\\Macromedia\\FlashPlayerPepper"; +const wchar_t kFlashPlayerPathValueName[] = L"PlayerPath"; + +// 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(); + + *out_path = plugin_path; + return true; +} + +#elif defined(OS_MACOSX) + +const base::FilePath::CharType kPepperFlashSystemBaseDirectory[] = + FILE_PATH_LITERAL("Internet Plug-Ins/PepperFlashPlayer"); + +#endif + +void OverridePepperFlashSystemPluginPath() { + base::FilePath plugin_path; +#if defined(OS_WIN) + if (!GetSystemFlashDirectory(&plugin_path)) + return; +#elif defined(OS_MACOSX) + if (!util_mac::GetLocalLibraryDirectory(&plugin_path)) + return; + plugin_path = plugin_path.Append(kPepperFlashSystemBaseDirectory); +#else + // A system plugin is not available on other platforms. + return; +#endif + + PathService::Override(chrome::DIR_PEPPER_FLASH_SYSTEM_PLUGIN, plugin_path); +} + #if defined(OS_LINUX) // Based on chrome/common/chrome_paths_linux.cc. @@ -450,11 +493,13 @@ void CefMainDelegate::PreSandboxStartup() { } if (!command_line->HasSwitch(switches::kProcessType)) { - // Only these paths when executing the main process. + // Only override these paths when executing the main process. #if defined(OS_MACOSX) OverrideChildProcessPath(); #endif + OverridePepperFlashSystemPluginPath(); + // Paths used to locate spell checking dictionary files. const base::FilePath& user_data_path = GetUserDataPath(); PathService::Override(chrome::DIR_USER_DATA, user_data_path); diff --git a/libcef/common/util_mac.h b/libcef/common/util_mac.h new file mode 100644 index 000000000..fcdd54ef4 --- /dev/null +++ b/libcef/common/util_mac.h @@ -0,0 +1,19 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CEF_LIBCEF_COMMON_UTIL_MAC_H_ +#define CEF_LIBCEF_COMMON_UTIL_MAC_H_ +#pragma once + +namespace base { +class FilePath; +} + +namespace util_mac { + +bool GetLocalLibraryDirectory(base::FilePath* result); + +} // namespace util_mac + +#endif // CEF_LIBCEF_COMMON_UTIL_MAC_H_ diff --git a/libcef/common/util_mac.mm b/libcef/common/util_mac.mm new file mode 100644 index 000000000..54d3f8aa1 --- /dev/null +++ b/libcef/common/util_mac.mm @@ -0,0 +1,15 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "libcef/common/util_mac.h" + +#include "base/mac/foundation_util.h" + +namespace util_mac { + +bool GetLocalLibraryDirectory(base::FilePath* result) { + return base::mac::GetLocalDirectory(NSLibraryDirectory, result); +} + +} // namespace util_mac diff --git a/libcef/renderer/content_renderer_client.cc b/libcef/renderer/content_renderer_client.cc index 1bb056798..92d0d7bb2 100644 --- a/libcef/renderer/content_renderer_client.cc +++ b/libcef/renderer/content_renderer_client.cc @@ -23,6 +23,7 @@ MSVC_POP_WARNING(); #include "libcef/common/request_impl.h" #include "libcef/common/values_impl.h" #include "libcef/renderer/browser_impl.h" +#include "libcef/renderer/pepper/pepper_helper.h" #include "libcef/renderer/render_frame_observer.h" #include "libcef/renderer/render_message_filter.h" #include "libcef/renderer/render_process_observer.h" @@ -471,6 +472,7 @@ void CefContentRendererClient::RenderThreadStarted() { void CefContentRendererClient::RenderFrameCreated( content::RenderFrame* render_frame) { new CefRenderFrameObserver(render_frame); + new CefPepperHelper(render_frame); BrowserCreated(render_frame->GetRenderView(), render_frame); } @@ -511,46 +513,24 @@ bool CefContentRendererClient::OverrideCreatePlugin( if (!found) return false; - bool flash = LowerCaseEqualsASCII(mime_type, - "application/x-shockwave-flash"); bool silverlight = StartsWithASCII(mime_type, "application/x-silverlight", false); - - if (flash) { - // "wmode" values of "opaque" or "transparent" are allowed. - size_t size = params.attributeNames.size(); - for (size_t i = 0; i < size; ++i) { - std::string name = params.attributeNames[i].utf8(); - if (name == "wmode") { - std::string value = params.attributeValues[i].utf8(); - if (value == "opaque" || value == "transparent") - flash = false; - break; - } - } - } - - if (flash || silverlight) { + if (silverlight) { // Force Flash and Silverlight plugins to use windowless mode. blink::WebPluginParams params_to_use = params; params_to_use.mimeType = blink::WebString::fromUTF8(mime_type); size_t size = params.attributeNames.size(); blink::WebVector new_names(size+1), - new_values(size+1); + new_values(size+1); for (size_t i = 0; i < size; ++i) { new_names[i] = params.attributeNames[i]; new_values[i] = params.attributeValues[i]; } - if (flash) { - new_names[size] = "wmode"; - new_values[size] = "opaque"; - } else if (silverlight) { - new_names[size] = "windowless"; - new_values[size] = "true"; - } + new_names[size] = "windowless"; + new_values[size] = "true"; params_to_use.attributeNames.swap(new_names); params_to_use.attributeValues.swap(new_values); diff --git a/libcef/renderer/pepper/pepper_helper.cc b/libcef/renderer/pepper/pepper_helper.cc new file mode 100644 index 000000000..400773433 --- /dev/null +++ b/libcef/renderer/pepper/pepper_helper.cc @@ -0,0 +1,23 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "libcef/renderer/pepper/pepper_helper.h" + +#include "libcef/renderer/pepper/renderer_pepper_host_factory.h" + +#include "content/public/renderer/renderer_ppapi_host.h" +#include "ppapi/host/ppapi_host.h" + +CefPepperHelper::CefPepperHelper(content::RenderFrame* render_frame) + : RenderFrameObserver(render_frame) {} + +CefPepperHelper::~CefPepperHelper() {} + +void CefPepperHelper::DidCreatePepperPlugin(content::RendererPpapiHost* host) { + // TODO(brettw) figure out how to hook up the host factory. It needs some + // kind of filter-like system to allow dynamic additions. + host->GetPpapiHost()->AddHostFactoryFilter( + scoped_ptr( + new CefRendererPepperHostFactory(host))); +} diff --git a/libcef/renderer/pepper/pepper_helper.h b/libcef/renderer/pepper/pepper_helper.h new file mode 100644 index 000000000..62f5a0451 --- /dev/null +++ b/libcef/renderer/pepper/pepper_helper.h @@ -0,0 +1,25 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CEF_LIBCEF_RENDERER_PEPPER_PEPPER_HELPER_H_ +#define CEF_LIBCEF_RENDERER_PEPPER_PEPPER_HELPER_H_ + +#include "base/compiler_specific.h" +#include "content/public/renderer/render_frame_observer.h" + +// This class listens for Pepper creation events from the RenderFrame and +// attaches the parts required for Chrome-specific plugin support. +class CefPepperHelper : public content::RenderFrameObserver { + public: + explicit CefPepperHelper(content::RenderFrame* render_frame); + ~CefPepperHelper() override; + + // RenderFrameObserver. + void DidCreatePepperPlugin(content::RendererPpapiHost* host) override; + + private: + DISALLOW_COPY_AND_ASSIGN(CefPepperHelper); +}; + +#endif // CEF_LIBCEF_RENDERER_PEPPER_PEPPER_HELPER_H_ diff --git a/libcef/renderer/pepper/renderer_pepper_host_factory.cc b/libcef/renderer/pepper/renderer_pepper_host_factory.cc new file mode 100644 index 000000000..90d57a725 --- /dev/null +++ b/libcef/renderer/pepper/renderer_pepper_host_factory.cc @@ -0,0 +1,87 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "libcef/renderer/pepper/renderer_pepper_host_factory.h" + +#include "base/logging.h" +#include "chrome/renderer/pepper/pepper_flash_drm_renderer_host.h" +#include "chrome/renderer/pepper/pepper_flash_font_file_host.h" +#include "chrome/renderer/pepper/pepper_flash_fullscreen_host.h" +#include "chrome/renderer/pepper/pepper_flash_menu_host.h" +#include "chrome/renderer/pepper/pepper_flash_renderer_host.h" +#include "content/public/renderer/renderer_ppapi_host.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/host/resource_host.h" +#include "ppapi/proxy/ppapi_message_utils.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/ppapi_permissions.h" + +using ppapi::host::ResourceHost; + +CefRendererPepperHostFactory::CefRendererPepperHostFactory( + content::RendererPpapiHost* host) + : host_(host) {} + +CefRendererPepperHostFactory::~CefRendererPepperHostFactory() {} + +scoped_ptr CefRendererPepperHostFactory::CreateResourceHost( + ppapi::host::PpapiHost* host, + PP_Resource resource, + PP_Instance instance, + const IPC::Message& message) { + DCHECK_EQ(host_->GetPpapiHost(), host); + + // Make sure the plugin is giving us a valid instance for this resource. + if (!host_->IsValidInstance(instance)) + return scoped_ptr(); + + if (host_->GetPpapiHost()->permissions().HasPermission( + ppapi::PERMISSION_FLASH)) { + switch (message.type()) { + case PpapiHostMsg_Flash_Create::ID: { + return scoped_ptr( + new PepperFlashRendererHost(host_, instance, resource)); + } + case PpapiHostMsg_FlashFullscreen_Create::ID: { + return scoped_ptr( + new PepperFlashFullscreenHost(host_, instance, resource)); + } + case PpapiHostMsg_FlashMenu_Create::ID: { + ppapi::proxy::SerializedFlashMenu serialized_menu; + if (ppapi::UnpackMessage( + message, &serialized_menu)) { + return scoped_ptr(new PepperFlashMenuHost( + host_, instance, resource, serialized_menu)); + } + break; + } + } + } + + // TODO(raymes): PDF also needs access to the FlashFontFileHost currently. + // We should either rename PPB_FlashFont_File to PPB_FontFile_Private or get + // rid of its use in PDF if possible. + if (host_->GetPpapiHost()->permissions().HasPermission( + ppapi::PERMISSION_FLASH) || + host_->GetPpapiHost()->permissions().HasPermission( + ppapi::PERMISSION_PRIVATE)) { + switch (message.type()) { + case PpapiHostMsg_FlashFontFile_Create::ID: { + ppapi::proxy::SerializedFontDescription description; + PP_PrivateFontCharset charset; + if (ppapi::UnpackMessage( + message, &description, &charset)) { + return scoped_ptr(new PepperFlashFontFileHost( + host_, instance, resource, description, charset)); + } + break; + } + case PpapiHostMsg_FlashDRM_Create::ID: + return scoped_ptr( + new PepperFlashDRMRendererHost(host_, instance, resource)); + } + } + + return scoped_ptr(); +} diff --git a/libcef/renderer/pepper/renderer_pepper_host_factory.h b/libcef/renderer/pepper/renderer_pepper_host_factory.h new file mode 100644 index 000000000..1d2f83155 --- /dev/null +++ b/libcef/renderer/pepper/renderer_pepper_host_factory.h @@ -0,0 +1,35 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef LIBCEF_RENDERER_PEPPER_RENDERER_PEPPER_HOST_FACTORY_H_ +#define LIBCEF_RENDERER_PEPPER_RENDERER_PEPPER_HOST_FACTORY_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "ppapi/host/host_factory.h" + +namespace content { +class RendererPpapiHost; +} + +class CefRendererPepperHostFactory : public ppapi::host::HostFactory { + public: + explicit CefRendererPepperHostFactory(content::RendererPpapiHost* host); + ~CefRendererPepperHostFactory() override; + + // HostFactory. + scoped_ptr CreateResourceHost( + ppapi::host::PpapiHost* host, + PP_Resource resource, + PP_Instance instance, + const IPC::Message& message) override; + + private: + // Not owned by this object. + content::RendererPpapiHost* host_; + + DISALLOW_COPY_AND_ASSIGN(CefRendererPepperHostFactory); +}; + +#endif // LIBCEF_RENDERER_PEPPER_RENDERER_PEPPER_HOST_FACTORY_H_ diff --git a/patch/patch.cfg b/patch/patch.cfg index 7195e8f63..9088f42f5 100644 --- a/patch/patch.cfg +++ b/patch/patch.cfg @@ -136,6 +136,19 @@ patches = [ 'name': 'net_urlrequest_1327', 'path': '../net/url_request/', }, + { + # Remove NOTREACHED() that is hit when loading Flash in incognito mode. + # https://bitbucket.org/chromiumembedded/cef/issue/1586 + 'name': 'content_pepper_flash_1586', + 'path': '../content/browser/renderer_host/pepper/', + }, + { + # Support loading of newer system Flash installations on OS X. + # https://bitbucket.org/chromiumembedded/cef/issue/1586 + # https://code.google.com/p/chromium/issues/detail?id=470737 + 'name': 'chrome_pepper_flash_1586', + 'path': '../chrome/common/', + }, { # Disable scollbar bounce and overlay on OS X. # http://code.google.com/p/chromiumembedded/issues/detail?id=364 diff --git a/patch/patches/chrome_pepper_flash_1586.patch b/patch/patches/chrome_pepper_flash_1586.patch new file mode 100644 index 000000000..2c1b9203e --- /dev/null +++ b/patch/patches/chrome_pepper_flash_1586.patch @@ -0,0 +1,27 @@ +diff --git pepper_flash.cc pepper_flash.cc +index b21d4d1..11fac76 100644 +--- pepper_flash.cc ++++ pepper_flash.cc +@@ -117,6 +117,14 @@ bool CheckPepperFlashManifest(const base::DictionaryValue& manifest, + if (os != kPepperFlashOperatingSystem) + return false; + ++#if defined(OS_MACOSX) ++ // On Mac newer versions of the plugin are a universal binary and use "mac" ++ // as the value. ++ std::string arch; ++ manifest.GetStringASCII("x-ppapi-arch", &arch); ++ if (arch != kPepperFlashArch && arch != kPepperFlashOperatingSystem) ++ return false; ++#else + // On Win64, PepperFlash manifests have "ia32" instead of "x64" so skip the + // architecture check. TODO(wfh): remove this when crbug.com/458894 is fixed. + #if !defined(OS_WIN) || !defined(ARCH_CPU_X86_64) +@@ -125,6 +133,7 @@ bool CheckPepperFlashManifest(const base::DictionaryValue& manifest, + if (arch != kPepperFlashArch) + return false; + #endif ++#endif + + *version_out = version; + return true; diff --git a/patch/patches/content_pepper_flash_1586.patch b/patch/patches/content_pepper_flash_1586.patch new file mode 100644 index 000000000..6fe2bee28 --- /dev/null +++ b/patch/patches/content_pepper_flash_1586.patch @@ -0,0 +1,13 @@ +diff --git pepper_flash_file_message_filter.cc pepper_flash_file_message_filter.cc +index 48da55d..2bbb939 100644 +--- pepper_flash_file_message_filter.cc ++++ pepper_flash_file_message_filter.cc +@@ -53,7 +53,7 @@ PepperFlashFileMessageFilter::PepperFlashFileMessageFilter( + // will construct a bad path and could provide access to the wrong files. + // In this case, |plugin_data_directory_| will remain unset and + // |ValidateAndConvertPepperFilePath| will fail. +- NOTREACHED(); ++ //NOTREACHED(); + } else { + plugin_data_directory_ = GetDataDirName(profile_data_directory).Append( + base::FilePath::FromUTF8Unsafe(plugin_name));