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

@@ -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_