alloy: Add support for the new non-PPAPI PDF viewer (see issue #3047)

Enable by passing `--enable-features=PdfUnseasoned` on the command line.
This commit is contained in:
Marshall Greenblatt 2021-11-23 15:28:12 -05:00
parent d6d316e304
commit c75ebbccec
11 changed files with 244 additions and 173 deletions

View File

@ -524,8 +524,6 @@ static_library("libcef_static") {
"libcef/browser/extensions/extension_web_contents_observer.h",
"libcef/browser/extensions/mime_handler_view_guest_delegate.cc",
"libcef/browser/extensions/mime_handler_view_guest_delegate.h",
"libcef/browser/extensions/pdf_extension_util.cc",
"libcef/browser/extensions/pdf_extension_util.h",
"libcef/browser/extensions/pdf_web_contents_helper_client.cc",
"libcef/browser/extensions/pdf_web_contents_helper_client.h",
"libcef/browser/extensions/value_store/cef_value_store.cc",

View File

@ -780,11 +780,14 @@ bool AlloyBrowserHostImpl::MaybeAllowNavigation(
content::RenderFrameHost* opener,
bool is_guest_view,
const content::OpenURLParams& params) {
if (is_guest_view && !params.url.SchemeIs(extensions::kExtensionScheme) &&
if (is_guest_view && !params.is_pdf &&
!params.url.SchemeIs(extensions::kExtensionScheme) &&
!params.url.SchemeIs(content::kChromeUIScheme)) {
// The PDF viewer will load the PDF extension in the guest view, and print
// preview will load chrome://print in the guest view. All other navigations
// are passed to the owner browser.
// preview will load chrome://print in the guest view. The PDF renderer
// used with PdfUnseasoned will set |params.is_pdf| when loading the PDF
// stream (see PdfNavigationThrottle::WillStartRequest). All other
// navigations are passed to the owner browser.
CEF_POST_TASK(CEF_UIT,
base::BindOnce(
base::IgnoreResult(&AlloyBrowserHostImpl::OpenURLFromTab),

View File

@ -53,9 +53,12 @@
#include "cef/grit/cef_resources.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/cookie_settings_factory.h"
#include "chrome/browser/extensions/chrome_content_browser_client_extensions_part.h"
#include "chrome/browser/net/profile_network_context_service.h"
#include "chrome/browser/net/profile_network_context_service_factory.h"
#include "chrome/browser/net/system_network_context_manager.h"
#include "chrome/browser/pdf/chrome_pdf_stream_delegate.h"
#include "chrome/browser/plugins/pdf_iframe_navigation_throttle.h"
#include "chrome/browser/plugins/plugin_info_host_impl.h"
#include "chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.h"
#include "chrome/browser/plugins/plugin_utils.h"
@ -68,6 +71,7 @@
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/google_url_loader_throttle.h"
#include "chrome/common/pdf_util.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/webui_url_constants.h"
#include "chrome/grit/browser_resources.h"
@ -76,7 +80,10 @@
#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/embedder_support/switches.h"
#include "components/embedder_support/user_agent_utils.h"
#include "components/pdf/browser/pdf_navigation_throttle.h"
#include "components/pdf/browser/pdf_url_loader_request_interceptor.h"
#include "components/pdf/browser/pdf_web_contents_helper.h"
#include "components/pdf/common/internal_plugin_helpers.h"
#include "components/spellcheck/common/spellcheck.mojom.h"
#include "components/version_info/version_info.h"
#include "content/browser/plugin_service_impl.h"
@ -118,6 +125,7 @@
#include "net/base/auth.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "net/ssl/ssl_private_key.h"
#include "pdf/pdf_features.h"
#include "ppapi/host/ppapi_host.h"
#include "sandbox/policy/switches.h"
#include "services/network/public/cpp/network_switches.h"
@ -466,6 +474,19 @@ base::FilePath GetRootCachePath() {
CefString(&CefContext::Get()->settings().root_cache_path));
}
const extensions::Extension* GetEnabledExtensionFromSiteURL(
content::BrowserContext* context,
const GURL& site_url) {
if (!site_url.SchemeIs(extensions::kExtensionScheme))
return nullptr;
auto registry = extensions::ExtensionRegistry::Get(context);
if (!registry)
return nullptr;
return registry->enabled_extensions().GetByID(site_url.host());
}
} // namespace
AlloyContentBrowserClient::AlloyContentBrowserClient() = default;
@ -504,45 +525,79 @@ void AlloyContentBrowserClient::RenderProcessWillLaunch(
bool AlloyContentBrowserClient::ShouldUseProcessPerSite(
content::BrowserContext* browser_context,
const GURL& effective_url) {
if (!extensions::ExtensionsEnabled())
return false;
const GURL& site_url) {
if (extensions::ExtensionsEnabled()) {
if (auto profile = Profile::FromBrowserContext(browser_context)) {
return extensions::ChromeContentBrowserClientExtensionsPart::
ShouldUseProcessPerSite(profile, site_url);
}
}
if (!effective_url.SchemeIs(extensions::kExtensionScheme))
return false;
extensions::ExtensionRegistry* registry =
extensions::ExtensionRegistry::Get(browser_context);
if (!registry)
return false;
const extensions::Extension* extension =
registry->enabled_extensions().GetByID(effective_url.host());
if (!extension)
return false;
// TODO(extensions): Extra checks required if type is TYPE_HOSTED_APP.
// Hosted apps that have script access to their background page must use
// process per site, since all instances can make synchronous calls to the
// background window. Other extensions should use process per site as well.
return true;
return content::ContentBrowserClient::ShouldUseProcessPerSite(browser_context,
site_url);
}
bool AlloyContentBrowserClient::ShouldUseSpareRenderProcessHost(
content::BrowserContext* browser_context,
const GURL& site_url) {
if (extensions::ExtensionsEnabled()) {
if (auto profile = Profile::FromBrowserContext(browser_context)) {
return extensions::ChromeContentBrowserClientExtensionsPart::
ShouldUseSpareRenderProcessHost(profile, site_url);
}
}
return content::ContentBrowserClient::ShouldUseSpareRenderProcessHost(
browser_context, site_url);
}
// Based on
// ChromeContentBrowserClientExtensionsPart::DoesSiteRequireDedicatedProcess.
bool AlloyContentBrowserClient::DoesSiteRequireDedicatedProcess(
content::BrowserContext* browser_context,
const GURL& effective_site_url) {
if (!extensions::ExtensionsEnabled())
return false;
if (extensions::ExtensionsEnabled()) {
return extensions::ChromeContentBrowserClientExtensionsPart::
DoesSiteRequireDedicatedProcess(browser_context, effective_site_url);
}
const extensions::Extension* extension =
extensions::ExtensionRegistry::Get(browser_context)
->enabled_extensions()
.GetExtensionOrAppByURL(effective_site_url);
// Isolate all extensions.
return extension != nullptr;
return content::ContentBrowserClient::DoesSiteRequireDedicatedProcess(
browser_context, effective_site_url);
}
bool AlloyContentBrowserClient::ShouldLockProcessToSite(
content::BrowserContext* browser_context,
const GURL& effective_site_url) {
if (extensions::ExtensionsEnabled()) {
return extensions::ChromeContentBrowserClientExtensionsPart::
ShouldLockProcessToSite(browser_context, effective_site_url);
}
return content::ContentBrowserClient::ShouldLockProcessToSite(
browser_context, effective_site_url);
}
bool AlloyContentBrowserClient::ShouldTreatURLSchemeAsFirstPartyWhenTopLevel(
base::StringPiece scheme,
bool is_embedded_origin_secure) {
// This is needed to bypass the normal SameSite rules for any chrome:// page
// embedding a secure origin, regardless of the registrable domains of any
// intervening frames. For example, this is needed for browser UI to interact
// with SameSite cookies on accounts.google.com, which are used for logging
// into Cloud Print from chrome://print, for displaying a list of available
// accounts on the NTP (chrome://new-tab-page), etc.
if (is_embedded_origin_secure && scheme == content::kChromeUIScheme)
return true;
if (extensions::ExtensionsEnabled())
return scheme == extensions::kExtensionScheme;
return false;
}
bool AlloyContentBrowserClient::
ShouldIgnoreSameSiteCookieRestrictionsWhenTopLevel(
base::StringPiece scheme,
bool is_embedded_origin_secure) {
return is_embedded_origin_secure && scheme == content::kChromeUIScheme;
}
void AlloyContentBrowserClient::OverrideURLLoaderFactoryParams(
@ -600,17 +655,24 @@ void AlloyContentBrowserClient::SiteInstanceGotProcess(
if (!extensions::ExtensionsEnabled())
return;
// If this isn't an extension renderer there's nothing to do.
const extensions::Extension* extension = GetExtension(site_instance);
CHECK(site_instance->HasProcess());
auto context = site_instance->GetBrowserContext();
// Only add the process to the map if the SiteInstance's site URL is already
// a chrome-extension:// URL. This includes hosted apps, except in rare cases
// that a URL in the hosted app's extent is not treated as a hosted app (e.g.,
// for isolated origins or cross-site iframes). For that case, don't look up
// the hosted app's Extension from the site URL using GetExtensionOrAppByURL,
// since it isn't treated as a hosted app.
const auto extension =
GetEnabledExtensionFromSiteURL(context, site_instance->GetSiteURL());
if (!extension)
return;
auto browser_context =
static_cast<AlloyBrowserContext*>(site_instance->GetBrowserContext());
extensions::ProcessMap::Get(browser_context)
->Insert(extension->id(), site_instance->GetProcess()->GetID(),
site_instance->GetId());
extensions::ProcessMap::Get(context)->Insert(
extension->id(), site_instance->GetProcess()->GetID(),
site_instance->GetId());
}
void AlloyContentBrowserClient::SiteInstanceDeleting(
@ -618,25 +680,22 @@ void AlloyContentBrowserClient::SiteInstanceDeleting(
if (!extensions::ExtensionsEnabled())
return;
// May be NULL during shutdown.
if (!extensions::ExtensionsBrowserClient::Get())
return;
// May be NULL during shutdown.
if (!site_instance->HasProcess())
return;
// If this isn't an extension renderer there's nothing to do.
const extensions::Extension* extension = GetExtension(site_instance);
auto context = site_instance->GetBrowserContext();
auto registry = extensions::ExtensionRegistry::Get(context);
if (!registry)
return;
auto extension = registry->enabled_extensions().GetExtensionOrAppByURL(
site_instance->GetSiteURL());
if (!extension)
return;
auto browser_context =
static_cast<AlloyBrowserContext*>(site_instance->GetBrowserContext());
extensions::ProcessMap::Get(browser_context)
->Remove(extension->id(), site_instance->GetProcess()->GetID(),
site_instance->GetId());
extensions::ProcessMap::Get(context)->Remove(
extension->id(), site_instance->GetProcess()->GetID(),
site_instance->GetId());
}
void AlloyContentBrowserClient::BindHostReceiverForRenderer(
@ -1008,7 +1067,21 @@ std::vector<std::unique_ptr<content::NavigationThrottle>>
AlloyContentBrowserClient::CreateThrottlesForNavigation(
content::NavigationHandle* navigation_handle) {
throttle::NavigationThrottleList throttles;
if (extensions::ExtensionsEnabled()) {
auto pdf_iframe_throttle =
PDFIFrameNavigationThrottle::MaybeCreateThrottleFor(navigation_handle);
if (pdf_iframe_throttle)
throttles.push_back(std::move(pdf_iframe_throttle));
auto pdf_throttle = pdf::PdfNavigationThrottle::MaybeCreateThrottleFor(
navigation_handle, std::make_unique<ChromePdfStreamDelegate>());
if (pdf_throttle)
throttles.push_back(std::move(pdf_throttle));
}
throttle::CreateThrottlesForNavigation(navigation_handle, throttles);
return throttles;
}
@ -1037,6 +1110,26 @@ AlloyContentBrowserClient::CreateURLLoaderThrottles(
return result;
}
std::vector<std::unique_ptr<content::URLLoaderRequestInterceptor>>
AlloyContentBrowserClient::WillCreateURLLoaderRequestInterceptors(
content::NavigationUIData* navigation_ui_data,
int frame_tree_node_id,
const scoped_refptr<network::SharedURLLoaderFactory>&
network_loader_factory) {
std::vector<std::unique_ptr<content::URLLoaderRequestInterceptor>>
interceptors;
if (extensions::ExtensionsEnabled()) {
auto pdf_interceptor =
pdf::PdfURLLoaderRequestInterceptor::MaybeCreateInterceptor(
frame_tree_node_id, std::make_unique<ChromePdfStreamDelegate>());
if (pdf_interceptor)
interceptors.push_back(std::move(pdf_interceptor));
}
return interceptors;
}
#if defined(OS_LINUX)
void AlloyContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
const base::CommandLine& command_line,
@ -1383,6 +1476,8 @@ AlloyContentBrowserClient::GetPluginMimeTypesWithExternalHandlers(
auto map = PluginUtils::GetMimeTypeToExtensionIdMap(browser_context);
for (const auto& pair : map)
mime_types.insert(pair.first);
if (pdf::IsInternalPluginExternallyHandled())
mime_types.insert(pdf::kInternalPluginMimeType);
return mime_types;
}
@ -1401,27 +1496,20 @@ bool AlloyContentBrowserClient::ShouldAllowPluginCreation(
const url::Origin& embedder_origin,
const content::PepperPluginInfo& plugin_info) {
if (plugin_info.name == ChromeContentClient::kPDFInternalPluginName) {
// Allow embedding the internal PDF plugin in the built-in PDF extension.
if (embedder_origin.scheme() == extensions::kExtensionScheme &&
embedder_origin.host() == extension_misc::kPdfExtensionId) {
return true;
}
// Allow embedding the internal PDF plugin in chrome://print.
if (embedder_origin ==
url::Origin::Create(GURL(chrome::kChromeUIPrintURL))) {
return true;
}
// Only allow the PDF plugin in the known, trustworthy origins that are
// allowlisted above. See also https://crbug.com/520422 and
// https://crbug.com/1027173.
return false;
return IsPdfInternalPluginAllowedOrigin(embedder_origin);
}
return true;
}
bool AlloyContentBrowserClient::IsFindInPageDisabledForOrigin(
const url::Origin& origin) {
// For PDF viewing with the PPAPI-free PDF Viewer, find-in-page should only
// display results from the PDF content, and not from the UI.
return base::FeatureList::IsEnabled(chrome_pdf::features::kPdfUnseasoned) &&
IsPdfExtensionOrigin(origin);
}
CefRefPtr<CefRequestContextImpl> AlloyContentBrowserClient::request_context()
const {
return browser_main_parts_->request_context();

View File

@ -39,9 +39,19 @@ class AlloyContentBrowserClient : public content::ContentBrowserClient {
const content::MainFunctionParams& parameters) override;
void RenderProcessWillLaunch(content::RenderProcessHost* host) override;
bool ShouldUseProcessPerSite(content::BrowserContext* browser_context,
const GURL& effective_url) override;
const GURL& site_url) override;
bool ShouldUseSpareRenderProcessHost(content::BrowserContext* browser_context,
const GURL& site_url) override;
bool DoesSiteRequireDedicatedProcess(content::BrowserContext* browser_context,
const GURL& effective_site_url) override;
bool ShouldLockProcessToSite(content::BrowserContext* browser_context,
const GURL& effective_site_url) override;
bool ShouldTreatURLSchemeAsFirstPartyWhenTopLevel(
base::StringPiece scheme,
bool is_embedded_origin_secure) override;
bool ShouldIgnoreSameSiteCookieRestrictionsWhenTopLevel(
base::StringPiece scheme,
bool is_embedded_origin_secure) override;
void OverrideURLLoaderFactoryParams(
content::BrowserContext* browser_context,
const url::Origin& origin,
@ -124,6 +134,12 @@ class AlloyContentBrowserClient : public content::ContentBrowserClient {
const base::RepeatingCallback<content::WebContents*()>& wc_getter,
content::NavigationUIData* navigation_ui_data,
int frame_tree_node_id) override;
std::vector<std::unique_ptr<content::URLLoaderRequestInterceptor>>
WillCreateURLLoaderRequestInterceptors(
content::NavigationUIData* navigation_ui_data,
int frame_tree_node_id,
const scoped_refptr<network::SharedURLLoaderFactory>&
network_loader_factory) override;
#if defined(OS_LINUX)
void GetAdditionalMappedFilesForChildProcess(
@ -221,6 +237,7 @@ class AlloyContentBrowserClient : public content::ContentBrowserClient {
bool ShouldAllowPluginCreation(
const url::Origin& embedder_origin,
const content::PepperPluginInfo& plugin_info) override;
bool IsFindInPageDisabledForOrigin(const url::Origin& origin) override;
CefRefPtr<CefRequestContextImpl> request_context() const;
CefDevToolsDelegate* devtools_delegate() const;

View File

@ -8,7 +8,6 @@
#include <string>
#include "libcef/browser/extension_impl.h"
#include "libcef/browser/extensions/pdf_extension_util.h"
#include "libcef/browser/extensions/value_store/cef_value_store_factory.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/extensions/extensions_util.h"
@ -22,6 +21,7 @@
#include "base/strings/string_tokenizer.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "chrome/browser/pdf/pdf_extension_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_paths.h"
#include "components/crx_file/id_util.h"
@ -179,8 +179,8 @@ void CefExtensionSystem::Init() {
ready_.Signal();
// Add the internal PDF extension. PDF loading works as follows:
// 1. The PDF PPAPI plugin is registered in libcef/common/content_client.cc
// ComputeBuiltInPlugins to handle the kPDFPluginOutOfProcessMimeType.
// 1. The PDF plugin is registered in libcef/common/content_client.cc
// ComputeBuiltInPlugins to handle the pdf::kInternalPluginMimeType.
// 2. The PDF extension is registered by the below call to AddExtension and
// associated with the "application/pdf" mime type.
// 3. Web content running in the owner CefBrowser requests to load a PDF file
@ -230,24 +230,34 @@ void CefExtensionSystem::Init() {
// CefExtensionsBrowserClient::LoadResourceFromResourceBundle
// and CefComponentExtensionResourceManager. Access to chrome://resources
// is granted via CefExtensionWebContentsObserver::RenderViewCreated.
// 15.The PDF extension calls chrome.mimeHandlerPrivate.getStreamInfo
// (chrome/browser/resources/pdf/browser_api.js) to retrieve the PDF
// resource stream. This API is implemented using Mojo as described in
// libcef/common/extensions/api/README.txt.
// 16.The PDF extension requests the PDF PPAPI plugin to handle
// kPDFPluginOutOfProcessMimeType. Approval arrives in the guest renderer
// 15.The PDF extension requests the PDF plugin to handle
// pdf::kInternalPluginMimeType. Approval arrives in the guest renderer
// process via ExtensionFrameHelper::OnExtensionResponse which calls
// NativeExtensionBindingsSystem::HandleResponse. This triggers creation of
// an HTMLPlugInElement via native V8 bindings to host the PDF plugin.
// 16.- With the old PPAPI plugin:
// The PDF extension calls chrome.mimeHandlerPrivate.getStreamInfo
// (chrome/browser/resources/pdf/browser_api.js) to retrieve the PDF
// resource stream. This API is implemented using Mojo as described in
// libcef/common/extensions/api/README.txt.
// - With the new PdfUnseasoned plugin:
// The PDF resource navigation is redirected by PdfNavigationThrottle and
// the stream contents are replaced by PdfURLLoaderRequestInterceptor.
// 17.HTMLPlugInElement::RequestObject is called in the guest renderer process
// and determines that the PDF PPAPI plugin should be handled internally
// and determines that the PDF plugin should be handled internally
// (handled_externally=false). A PluginDocument is created and
// AlloyContentRendererClient::OverrideCreatePlugin is called to create a
// WebPlugin.
// 18.The PDF extension and PDF plugin are now loaded. Print commands, if
// 18.- With the old PPAPI plugin:
// The PDF plugin is loaded by ChromeContentRendererClient::CreatePlugin
// calling RenderFrameImpl::CreatePlugin.
// - With the new PdfUnseasoned plugin:
// The PDF plugin is loaded by ChromeContentRendererClient::CreatePlugin
// calling pdf::CreateInternalPlugin.
// 19.The PDF extension and PDF plugin are now loaded. Print commands, if
// any, are handled in the guest renderer process by ChromePDFPrintClient
// and CefPrintRenderFrameHelperDelegate.
// 19.When navigating away from the PDF file or closing the owner CefBrowser
// 20.When navigating away from the PDF file or closing the owner CefBrowser
// the guest WebContents will be destroyed. This triggers a call to
// CefMimeHandlerViewGuestDelegate::OnGuestDetached which removes the
// routing ID association with the owner CefBrowser.

View File

@ -1,46 +0,0 @@
// Copyright 2015 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/extensions/pdf_extension_util.h"
#include "base/strings/string_util.h"
#include "chrome/grit/browser_resources.h"
#include "ui/base/resource/resource_bundle.h"
namespace extensions {
namespace pdf_extension_util {
namespace {
// Tags in the manifest to be replaced.
const char kNameTag[] = "<NAME>";
} // namespace
// These should match the keys for the Chrome and Chromium PDF Viewer entries in
// chrome/browser/resources/plugin_metadata/plugins_*.json.
#if defined(GOOGLE_CHROME_BUILD)
const char kPdfResourceIdentifier[] = "google-chrome-pdf";
#else
const char kPdfResourceIdentifier[] = "chromium-pdf";
#endif
// Match the GOOGLE_CHROME_BUILD value from ChromeContentClient::kPDFPluginName
// to avoid breaking Websites that specifically look for this string in the
// plugin list.
const char kPdfPluginName[] = "Chrome PDF Viewer";
std::string GetManifest() {
std::string manifest_contents =
ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
IDR_PDF_MANIFEST);
DCHECK(manifest_contents.find(kNameTag) != std::string::npos);
base::ReplaceFirstSubstringAfterOffset(&manifest_contents, 0, kNameTag,
kPdfPluginName);
return manifest_contents;
}
} // namespace pdf_extension_util
} // namespace extensions

View File

@ -1,27 +0,0 @@
// Copyright 2015 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_EXTENSIONS_PDF_EXTENSION_UTIL_H_
#define CEF_LIBCEF_BROWSER_EXTENSIONS_PDF_EXTENSION_UTIL_H_
#include <string>
namespace extensions {
namespace pdf_extension_util {
// The ResourceIdentifier for the PDF Viewer plugin.
extern const char kPdfResourceIdentifier[];
// The name of the PDF Viewer plugin.
extern const char kPdfPluginName[];
// Return the extensions manifest for PDF. The manifest is loaded from
// browser_resources.grd and certain fields are replaced based on what chrome
// flags are enabled.
std::string GetManifest();
} // namespace pdf_extension_util
} // namespace extensions
#endif // CEF_LIBCEF_BROWSER_EXTENSIONS_PDF_EXTENSION_UTIL_H_

View File

@ -26,6 +26,7 @@ namespace {
// |is_main_frame| argument once this problem is fixed.
bool NavigationOnUIThread(
bool is_main_frame,
bool is_pdf,
const content::GlobalRenderFrameHostId& global_id,
const content::GlobalRenderFrameHostId& parent_global_id,
content::WebContents* source,
@ -37,6 +38,7 @@ bool NavigationOnUIThread(
params.transition_type(), params.is_renderer_initiated());
open_params.user_gesture = params.has_user_gesture();
open_params.initiator_origin = params.initiator_origin();
open_params.is_pdf = is_pdf;
CefRefPtr<CefBrowserHostBase> browser;
if (!CefBrowserInfoManager::GetInstance()->MaybeAllowNavigation(
@ -87,6 +89,7 @@ void CreateThrottlesForNavigation(content::NavigationHandle* navigation_handle,
CEF_REQUIRE_UIT();
const bool is_main_frame = navigation_handle->IsInMainFrame();
const bool is_pdf = navigation_handle->IsPdf();
const auto global_id = frame_util::GetGlobalId(navigation_handle);
// Identify the RenderFrameHost that originated the navigation.
@ -99,8 +102,8 @@ void CreateThrottlesForNavigation(content::NavigationHandle* navigation_handle,
std::unique_ptr<content::NavigationThrottle> throttle =
std::make_unique<navigation_interception::InterceptNavigationThrottle>(
navigation_handle,
base::BindRepeating(&NavigationOnUIThread, is_main_frame, global_id,
parent_global_id),
base::BindRepeating(&NavigationOnUIThread, is_main_frame, is_pdf,
global_id, parent_global_id),
navigation_interception::SynchronyMode::kSync);
throttles.push_back(std::move(throttle));
}

View File

@ -9,7 +9,6 @@
#include "include/cef_stream.h"
#include "include/cef_version.h"
#include "libcef/browser/extensions/pdf_extension_util.h"
#include "libcef/common/app_manager.h"
#include "libcef/common/cef_switches.h"
#include "libcef/common/extensions/extensions_util.h"
@ -25,9 +24,11 @@
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_content_client.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/media/cdm_registration.h"
#include "components/pdf/common/internal_plugin_helpers.h"
#include "content/public/common/cdm_info.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
@ -48,7 +49,6 @@ namespace {
const char kPDFPluginExtension[] = "pdf";
const char kPDFPluginDescription[] = "Portable Document Format";
const char kPDFPluginOutOfProcessMimeType[] = "application/x-google-chrome-pdf";
const uint32_t kPDFPluginPermissions =
ppapi::PERMISSION_PDF | ppapi::PERMISSION_DEV;
@ -66,11 +66,10 @@ void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
content::PepperPluginInfo pdf_info;
pdf_info.is_internal = true;
pdf_info.is_out_of_process = true;
pdf_info.name = extensions::pdf_extension_util::kPdfPluginName;
pdf_info.name = ChromeContentClient::kPDFInternalPluginName;
pdf_info.description = kPDFPluginDescription;
pdf_info.path =
base::FilePath::FromUTF8Unsafe(AlloyContentClient::kPDFPluginPath);
content::WebPluginMimeType pdf_mime_type(kPDFPluginOutOfProcessMimeType,
pdf_info.path = base::FilePath(ChromeContentClient::kPDFPluginPath);
content::WebPluginMimeType pdf_mime_type(pdf::kInternalPluginMimeType,
kPDFPluginExtension,
kPDFPluginDescription);
pdf_info.mime_types.push_back(pdf_mime_type);
@ -84,8 +83,6 @@ void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
} // namespace
const char AlloyContentClient::kPDFPluginPath[] = "internal-pdf-viewer";
AlloyContentClient::AlloyContentClient() = default;
AlloyContentClient::~AlloyContentClient() = default;

View File

@ -13,8 +13,6 @@
class AlloyContentClient : public content::ContentClient {
public:
static const char kPDFPluginPath[];
AlloyContentClient();
~AlloyContentClient() override;

View File

@ -48,6 +48,7 @@
#include "base/task/post_task.h"
#include "build/build_config.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pdf_util.h"
#include "chrome/common/url_constants.h"
#include "chrome/renderer/browser_exposed_renderer_interfaces.h"
#include "chrome/renderer/chrome_content_renderer_client.h"
@ -58,6 +59,9 @@
#include "chrome/renderer/plugins/chrome_plugin_placeholder.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/nacl/common/nacl_constants.h"
#include "components/pdf/common/internal_plugin_helpers.h"
#include "components/pdf/renderer/internal_plugin_renderer_helpers.h"
#include "components/pdf/renderer/pdf_find_in_page.h"
#include "components/printing/renderer/print_render_frame_helper.h"
#include "components/spellcheck/renderer/spellcheck.h"
#include "components/spellcheck/renderer/spellcheck_provider.h"
@ -80,6 +84,7 @@
#include "media/base/media.h"
#include "mojo/public/cpp/bindings/binder_map.h"
#include "mojo/public/cpp/bindings/generic_pending_receiver.h"
#include "pdf/pdf_features.h"
#include "printing/print_settings.h"
#include "services/network/public/cpp/is_potentially_trustworthy.h"
#include "services/service_manager/public/cpp/connector.h"
@ -195,11 +200,20 @@ void AlloyContentRendererClient::RenderThreadStarted() {
content::RenderThread* thread = content::RenderThread::Get();
const bool is_extension = IsStandaloneExtensionProcess();
thread->SetRendererProcessType(
IsStandaloneExtensionProcess()
is_extension
? blink::scheduler::WebRendererProcessType::kExtensionRenderer
: blink::scheduler::WebRendererProcessType::kRenderer);
if (is_extension) {
// The process name was set to "Renderer" in RendererMain(). Update it to
// "Extension Renderer" to highlight that it's hosting an extension.
base::trace_event::TraceLog::GetInstance()->set_process_name(
"Extension Renderer");
}
thread->AddObserver(observer_.get());
if (!command_line->HasSwitch(switches::kDisableSpellChecking)) {
@ -305,6 +319,12 @@ void AlloyContentRendererClient::RenderFrameCreated(
base::WrapUnique(
new extensions::CefPrintRenderFrameHelperDelegate(*is_windowless)));
}
if (base::FeatureList::IsEnabled(chrome_pdf::features::kPdfUnseasoned)) {
render_frame_observer->associated_interfaces()->AddInterface(
base::BindRepeating(&pdf::PdfFindInPageFactory::BindReceiver,
render_frame->GetRoutingID()));
}
}
void AlloyContentRendererClient::WebViewCreated(blink::WebView* web_view) {
@ -351,6 +371,16 @@ bool AlloyContentRendererClient::IsPluginHandledExternally(
plugin_element);
return false;
}
if (plugin_info->actual_mime_type == pdf::kInternalPluginMimeType &&
pdf::IsInternalPluginExternallyHandled()) {
// Only actually treat the internal PDF plugin as externally handled if
// used within an origin allowed to create the internal PDF plugin;
// otherwise, let Blink try to create the in-process PDF plugin.
if (IsPdfInternalPluginAllowedOrigin(
render_frame->GetWebFrame()->GetSecurityOrigin())) {
return true;
}
}
return ChromeExtensionsRendererClient::MaybeCreateMimeHandlerView(
plugin_element, original_url, plugin_info->actual_mime_type,
plugin_info->plugin);