Skip to content

Commit

Permalink
refactor: move PDF viewer to OOPIF
Browse files Browse the repository at this point in the history
  • Loading branch information
codebytere committed Apr 4, 2024
1 parent 3eb94b7 commit 403c925
Show file tree
Hide file tree
Showing 6 changed files with 260 additions and 12 deletions.
Expand Up @@ -154,7 +154,7 @@ void ElectronManagementAPIDelegate::InstallOrLaunchReplacementWebApp(

void ElectronManagementAPIDelegate::EnableExtension(
content::BrowserContext* context,
const std::string& extension_id) const {
const extensions::ExtensionId& extension_id) const {
// const extensions::Extension* extension =
// extensions::ExtensionRegistry::Get(context)->GetExtensionById(
// extension_id, extensions::ExtensionRegistry::EVERYTHING);
Expand All @@ -171,7 +171,7 @@ void ElectronManagementAPIDelegate::EnableExtension(
void ElectronManagementAPIDelegate::DisableExtension(
content::BrowserContext* context,
const extensions::Extension* source_extension,
const std::string& extension_id,
const extensions::ExtensionId& extension_id,
extensions::disable_reason::DisableReason disable_reason) const {
// TODO(sentialx): we don't have ExtensionService
// extensions::ExtensionSystem::Get(context)
Expand All @@ -182,7 +182,7 @@ void ElectronManagementAPIDelegate::DisableExtension(

bool ElectronManagementAPIDelegate::UninstallExtension(
content::BrowserContext* context,
const std::string& transient_extension_id,
const extensions::ExtensionId& transient_extension_id,
extensions::UninstallReason reason,
std::u16string* error) const {
// TODO(sentialx): we don't have ExtensionService
Expand All @@ -194,7 +194,7 @@ bool ElectronManagementAPIDelegate::UninstallExtension(

void ElectronManagementAPIDelegate::SetLaunchType(
content::BrowserContext* context,
const std::string& extension_id,
const extensions::ExtensionId& extension_id,
extensions::LaunchType launch_type) const {
// TODO(sentialx)
// extensions::SetLaunchType(context, extension_id, launch_type);
Expand Down
Expand Up @@ -10,6 +10,7 @@

#include "base/task/cancelable_task_tracker.h"
#include "extensions/browser/api/management/management_api_delegate.h"
#include "extensions/common/extension_id.h"

class ElectronManagementAPIDelegate : public extensions::ManagementAPIDelegate {
public:
Expand Down Expand Up @@ -51,19 +52,20 @@ class ElectronManagementAPIDelegate : public extensions::ManagementAPIDelegate {
const GURL& web_app_url,
ManagementAPIDelegate::InstallOrLaunchWebAppCallback callback)
const override;
void EnableExtension(content::BrowserContext* context,
const std::string& extension_id) const override;
void EnableExtension(
content::BrowserContext* context,
const extensions::ExtensionId& extension_id) const override;
void DisableExtension(
content::BrowserContext* context,
const extensions::Extension* source_extension,
const std::string& extension_id,
const extensions::ExtensionId& extension_id,
extensions::disable_reason::DisableReason disable_reason) const override;
bool UninstallExtension(content::BrowserContext* context,
const std::string& transient_extension_id,
const extensions::ExtensionId& transient_extension_id,
extensions::UninstallReason reason,
std::u16string* error) const override;
void SetLaunchType(content::BrowserContext* context,
const std::string& extension_id,
const extensions::ExtensionId& extension_id,
extensions::LaunchType launch_type) const override;
GURL GetIconURL(const extensions::Extension* extension,
int icon_size,
Expand Down
Expand Up @@ -6,10 +6,16 @@

#include <string>

#include "base/memory/weak_ptr.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/pdf/pdf_viewer_stream_manager.h"
#include "chrome/common/extensions/api/pdf_viewer_private.h"
#include "chrome/common/pref_names.h"
#include "components/pdf/common/constants.h"
#include "components/prefs/pref_service.h"
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
#include "shell/browser/electron_browser_context.h"
#include "url/url_constants.h"

Expand All @@ -22,6 +28,11 @@ namespace IsAllowedLocalFileAccess =

namespace SetPdfOcrPref = api::pdf_viewer_private::SetPdfOcrPref;

namespace SetPdfPluginAttributes =
api::pdf_viewer_private::SetPdfPluginAttributes;

namespace SetPdfDocumentTitle = api::pdf_viewer_private::SetPdfDocumentTitle;

// Check if the current URL is allowed based on a list of allowlisted domains.
bool IsUrlAllowedToEmbedLocalFiles(
const GURL& current_url,
Expand All @@ -43,8 +54,46 @@ bool IsUrlAllowedToEmbedLocalFiles(
return false;
}

// Get the `StreamContainer` associated with the `extension_host`.
base::WeakPtr<StreamContainer> GetStreamContainer(
content::RenderFrameHost* extension_host) {
content::RenderFrameHost* embedder_host = extension_host->GetParent();
if (!embedder_host) {
return nullptr;
}

auto* pdf_viewer_stream_manager =
pdf::PdfViewerStreamManager::FromRenderFrameHost(embedder_host);
if (!pdf_viewer_stream_manager) {
return nullptr;
}

return pdf_viewer_stream_manager->GetStreamContainer(embedder_host);
}

} // namespace

PdfViewerPrivateGetStreamInfoFunction::PdfViewerPrivateGetStreamInfoFunction() =
default;

PdfViewerPrivateGetStreamInfoFunction::
~PdfViewerPrivateGetStreamInfoFunction() = default;

ExtensionFunction::ResponseAction PdfViewerPrivateGetStreamInfoFunction::Run() {
base::WeakPtr<StreamContainer> stream =
GetStreamContainer(render_frame_host());
if (!stream) {
return RespondNow(Error("Failed to get StreamContainer"));
}

api::pdf_viewer_private::StreamInfo stream_info;
stream_info.original_url = stream->original_url().spec();
stream_info.stream_url = stream->stream_url().spec();
stream_info.tab_id = stream->tab_id();
stream_info.embedded = stream->embedded();
return RespondNow(WithArguments(stream_info.ToValue()));
}

PdfViewerPrivateIsAllowedLocalFileAccessFunction::
PdfViewerPrivateIsAllowedLocalFileAccessFunction() = default;

Expand All @@ -61,6 +110,37 @@ PdfViewerPrivateIsAllowedLocalFileAccessFunction::Run() {
IsUrlAllowedToEmbedLocalFiles(GURL(params->url), base::Value::List())));
}

PdfViewerPrivateSetPdfDocumentTitleFunction::
PdfViewerPrivateSetPdfDocumentTitleFunction() = default;

PdfViewerPrivateSetPdfDocumentTitleFunction::
~PdfViewerPrivateSetPdfDocumentTitleFunction() = default;

// This function is only called for full-page PDFs.
ExtensionFunction::ResponseAction
PdfViewerPrivateSetPdfDocumentTitleFunction::Run() {
content::WebContents* web_contents = GetSenderWebContents();
if (!web_contents) {
return RespondNow(Error("Could not find a valid web contents."));
}

// Title should only be set for full-page PDFs.
// MIME type associated with sender `WebContents` must be `application/pdf`
// for a full-page PDF.
EXTENSION_FUNCTION_VALIDATE(web_contents->GetContentsMimeType() ==
pdf::kPDFMimeType);

std::optional<SetPdfDocumentTitle::Params> params =
SetPdfDocumentTitle::Params::Create(args());
EXTENSION_FUNCTION_VALIDATE(params);

web_contents->UpdateTitleForEntry(
web_contents->GetController().GetLastCommittedEntry(),
base::UTF8ToUTF16(params->title));

return RespondNow(NoArguments());
}

PdfViewerPrivateIsPdfOcrAlwaysActiveFunction::
PdfViewerPrivateIsPdfOcrAlwaysActiveFunction() = default;

Expand All @@ -87,4 +167,42 @@ ExtensionFunction::ResponseAction PdfViewerPrivateSetPdfOcrPrefFunction::Run() {
return RespondNow(WithArguments(false));
}

PdfViewerPrivateSetPdfPluginAttributesFunction::
PdfViewerPrivateSetPdfPluginAttributesFunction() = default;

PdfViewerPrivateSetPdfPluginAttributesFunction::
~PdfViewerPrivateSetPdfPluginAttributesFunction() = default;

ExtensionFunction::ResponseAction
PdfViewerPrivateSetPdfPluginAttributesFunction::Run() {
std::optional<SetPdfPluginAttributes::Params> params =
SetPdfPluginAttributes::Params::Create(args());
EXTENSION_FUNCTION_VALIDATE(params);

base::WeakPtr<StreamContainer> stream =
GetStreamContainer(render_frame_host());
if (!stream) {
return RespondNow(Error("Failed to get StreamContainer"));
}

const api::pdf_viewer_private::PdfPluginAttributes& attributes =
params->attributes;
// Check the `background_color` is an integer.
double whole = 0.0;
if (std::modf(attributes.background_color, &whole) != 0.0) {
return RespondNow(Error("Background color is not an integer"));
}

// Check the `background_color` is within the range of a uint32_t.
if (!base::IsValueInRangeForNumericType<uint32_t>(
attributes.background_color)) {
return RespondNow(Error("Background color out of bounds"));
}

stream->set_pdf_plugin_attributes(mime_handler::PdfPluginAttributes::New(
/*background_color=*/attributes.background_color,
/*allow_javascript=*/attributes.allow_javascript));
return RespondNow(NoArguments());
}

} // namespace extensions
Expand Up @@ -9,6 +9,24 @@

namespace extensions {

class PdfViewerPrivateGetStreamInfoFunction : public ExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("pdfViewerPrivate.getStreamInfo",
PDFVIEWERPRIVATE_GETSTREAMINFO)

PdfViewerPrivateGetStreamInfoFunction();
PdfViewerPrivateGetStreamInfoFunction(
const PdfViewerPrivateGetStreamInfoFunction&) = delete;
PdfViewerPrivateGetStreamInfoFunction& operator=(
const PdfViewerPrivateGetStreamInfoFunction&) = delete;

protected:
~PdfViewerPrivateGetStreamInfoFunction() override;

// Override from ExtensionFunction:
ResponseAction Run() override;
};

class PdfViewerPrivateIsAllowedLocalFileAccessFunction
: public ExtensionFunction {
public:
Expand All @@ -28,6 +46,24 @@ class PdfViewerPrivateIsAllowedLocalFileAccessFunction
ResponseAction Run() override;
};

class PdfViewerPrivateSetPdfDocumentTitleFunction : public ExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("pdfViewerPrivate.setPdfDocumentTitle",
PDFVIEWERPRIVATE_SETPDFDOCUMENTTITLE)

PdfViewerPrivateSetPdfDocumentTitleFunction();
PdfViewerPrivateSetPdfDocumentTitleFunction(
const PdfViewerPrivateSetPdfDocumentTitleFunction&) = delete;
PdfViewerPrivateSetPdfDocumentTitleFunction& operator=(
const PdfViewerPrivateSetPdfDocumentTitleFunction&) = delete;

protected:
~PdfViewerPrivateSetPdfDocumentTitleFunction() override;

// Override from ExtensionFunction:
ResponseAction Run() override;
};

class PdfViewerPrivateIsPdfOcrAlwaysActiveFunction : public ExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("pdfViewerPrivate.isPdfOcrAlwaysActive",
Expand Down Expand Up @@ -64,6 +100,25 @@ class PdfViewerPrivateSetPdfOcrPrefFunction : public ExtensionFunction {
ResponseAction Run() override;
};

class PdfViewerPrivateSetPdfPluginAttributesFunction
: public ExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("pdfViewerPrivate.setPdfPluginAttributes",
PDFVIEWERPRIVATE_SETPDFPLUGINATTRIBUTES)

PdfViewerPrivateSetPdfPluginAttributesFunction();
PdfViewerPrivateSetPdfPluginAttributesFunction(
const PdfViewerPrivateSetPdfPluginAttributesFunction&) = delete;
PdfViewerPrivateSetPdfPluginAttributesFunction& operator=(
const PdfViewerPrivateSetPdfPluginAttributesFunction&) = delete;

protected:
~PdfViewerPrivateSetPdfPluginAttributesFunction() override;

// Override from ExtensionFunction:
ResponseAction Run() override;
};

} // namespace extensions

#endif // ELECTRON_SHELL_BROWSER_EXTENSIONS_API_PDF_VIEWER_PRIVATE_PDF_VIEWER_PRIVATE_API_H_
Expand Up @@ -10,12 +10,20 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "electron/buildflags/buildflags.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_stream_manager.h"
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
#include "extensions/common/manifest_handlers/mime_types_handler.h"
#include "shell/browser/api/electron_api_web_contents.h"

#if BUILDFLAG(ENABLE_PDF_VIEWER)
#include "base/feature_list.h"
#include "chrome/browser/pdf/pdf_viewer_stream_manager.h"
#include "extensions/common/constants.h"
#include "pdf/pdf_features.h"
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)

namespace extensions {

void StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent(
Expand Down Expand Up @@ -51,13 +59,27 @@ void StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent(
GURL handler_url(
extensions::Extension::GetBaseURLFromExtensionId(extension_id).spec() +
handler->handler_url());

int tab_id = -1;
auto* api_contents = electron::api::WebContents::From(web_contents);
if (api_contents)
tab_id = api_contents->ID();

auto stream_container = std::make_unique<extensions::StreamContainer>(
tab_id, embedded, handler_url, extension_id,
std::move(transferrable_loader), original_url);

#if BUILDFLAG(ENABLE_PDF_VIEWER)
if (base::FeatureList::IsEnabled(chrome_pdf::features::kPdfOopif) &&
extension_id == extension_misc::kPdfExtensionId) {
pdf::PdfViewerStreamManager::Create(web_contents);
pdf::PdfViewerStreamManager::FromWebContents(web_contents)
->AddStreamContainer(frame_tree_node_id, internal_id,
std::move(stream_container));
return;
}
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)

extensions::MimeHandlerStreamManager::Get(browser_context)
->AddStream(stream_id, std::move(stream_container), frame_tree_node_id);
}
Expand Down

0 comments on commit 403c925

Please sign in to comment.