diff --git a/chrome/browser/pdf/BUILD.gn b/chrome/browser/pdf/BUILD.gn index 0b06828ca9292..a8827d8ae5726 100644 --- a/chrome/browser/pdf/BUILD.gn +++ b/chrome/browser/pdf/BUILD.gn @@ -31,6 +31,7 @@ source_set("pdf") { "//extensions/common:common_constants", "//extensions/common/api", "//pdf:buildflags", + "//pdf:features", "//printing/buildflags", "//ui/base", "//ui/gfx:color_utils", diff --git a/chrome/browser/pdf/chrome_pdf_stream_delegate.cc b/chrome/browser/pdf/chrome_pdf_stream_delegate.cc index 5e47daf17a6c4..31f6b512ebcfa 100644 --- a/chrome/browser/pdf/chrome_pdf_stream_delegate.cc +++ b/chrome/browser/pdf/chrome_pdf_stream_delegate.cc @@ -7,6 +7,7 @@ #include <string> #include <utility> +#include "base/feature_list.h" #include "base/memory/weak_ptr.h" #include "base/no_destructor.h" #include "base/numerics/safe_conversions.h" @@ -16,6 +17,7 @@ #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h" #include "extensions/common/api/mime_handler.mojom.h" #include "extensions/common/constants.h" +#include "pdf/pdf_features.h" #include "printing/buildflags/buildflags.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/base/resource/resource_bundle.h" @@ -85,6 +87,12 @@ absl::optional<GURL> ChromePdfStreamDelegate::MapToOriginalUrl( stream->pdf_plugin_attributes()->background_color); info.full_frame = !stream->embedded(); info.allow_javascript = stream->pdf_plugin_attributes()->allow_javascript; + + // TODO(crbug.com/1440430): Set `info.use_skia` based on both the feature + // flag and the enterprise policy once the policy is available for the Skia + // finch experiment. + info.use_skia = + base::FeatureList::IsEnabled(chrome_pdf::features::kPdfUseSkiaRenderer); #if BUILDFLAG(ENABLE_PRINT_PREVIEW) } else if (stream_url.GetWithEmptyPath() == chrome::kChromeUIUntrustedPrintURL) { @@ -94,6 +102,8 @@ absl::optional<GURL> ChromePdfStreamDelegate::MapToOriginalUrl( info.background_color = gfx::kGoogleGrey300; info.full_frame = false; info.allow_javascript = false; + info.use_skia = + base::FeatureList::IsEnabled(chrome_pdf::features::kPdfUseSkiaRenderer); #endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) } else { return absl::nullopt; diff --git a/components/pdf/browser/pdf_stream_delegate.h b/components/pdf/browser/pdf_stream_delegate.h index ebb1b57454ee3..a3f058cc031df 100644 --- a/components/pdf/browser/pdf_stream_delegate.h +++ b/components/pdf/browser/pdf_stream_delegate.h @@ -43,6 +43,7 @@ class PdfStreamDelegate { SkColor background_color = SK_ColorTRANSPARENT; bool full_frame = false; bool allow_javascript = false; + bool use_skia = false; }; PdfStreamDelegate(); diff --git a/components/pdf/browser/plugin_response_writer.cc b/components/pdf/browser/plugin_response_writer.cc index c6528bc52bbee..716e5c2f771c6 100644 --- a/components/pdf/browser/plugin_response_writer.cc +++ b/components/pdf/browser/plugin_response_writer.cc @@ -65,7 +65,7 @@ embed { </style> <div id="sizer"></div> <embed type="application/x-google-chrome-pdf" src="$1" original-url="$2" - background-color="$4" javascript="$5"$6> + background-color="$4" javascript="$5"$6$7> <script type="module"> $3 </script> @@ -82,7 +82,8 @@ $3 stream_info.injected_script ? *stream_info.injected_script : "", base::NumberToString(stream_info.background_color), stream_info.allow_javascript ? "allow" : "block", - stream_info.full_frame ? " full-frame" : ""}, + stream_info.full_frame ? " full-frame" : "", + stream_info.use_skia ? " use-skia" : ""}, /*offsets=*/nullptr); } diff --git a/extensions/browser/api/mime_handler_private/mime_handler_private_unittest.cc b/extensions/browser/api/mime_handler_private/mime_handler_private_unittest.cc index 545dbb6577d75..01f6245bb1f8d 100644 --- a/extensions/browser/api/mime_handler_private/mime_handler_private_unittest.cc +++ b/extensions/browser/api/mime_handler_private/mime_handler_private_unittest.cc @@ -51,32 +51,38 @@ TEST_F(MimeHandlerServiceImplTest, SetValidPdfPluginAttributes) { { const double kBackgroundColor = 4292533472.0f; service_->SetPdfPluginAttributes(mime_handler::PdfPluginAttributes::New( - /*background_color=*/kBackgroundColor, /*allow_javascript=*/true)); + /*background_color=*/kBackgroundColor, /*allow_javascript=*/true, + /*use_skia=*/true)); ASSERT_TRUE(stream_container_->pdf_plugin_attributes()); EXPECT_EQ(kBackgroundColor, stream_container_->pdf_plugin_attributes()->background_color); EXPECT_TRUE(stream_container_->pdf_plugin_attributes()->allow_javascript); + EXPECT_TRUE(stream_container_->pdf_plugin_attributes()->use_skia); } { service_->SetPdfPluginAttributes(mime_handler::PdfPluginAttributes::New( - /*background_color=*/0.0f, /*allow_javascript=*/true)); + /*background_color=*/0.0f, /*allow_javascript=*/true, + /*use_skia=*/false)); ASSERT_TRUE(stream_container_->pdf_plugin_attributes()); EXPECT_EQ(0.0f, stream_container_->pdf_plugin_attributes()->background_color); EXPECT_TRUE(stream_container_->pdf_plugin_attributes()->allow_javascript); + EXPECT_FALSE(stream_container_->pdf_plugin_attributes()->use_skia); } { service_->SetPdfPluginAttributes(mime_handler::PdfPluginAttributes::New( - /*background_color=*/UINT32_MAX, /*allow_javascript=*/false)); + /*background_color=*/UINT32_MAX, /*allow_javascript=*/false, + /*use_skia=*/true)); ASSERT_TRUE(stream_container_->pdf_plugin_attributes()); EXPECT_EQ(static_cast<double>(UINT32_MAX), stream_container_->pdf_plugin_attributes()->background_color); EXPECT_FALSE(stream_container_->pdf_plugin_attributes()->allow_javascript); + EXPECT_TRUE(stream_container_->pdf_plugin_attributes()->use_skia); } } @@ -85,7 +91,8 @@ TEST_F(MimeHandlerServiceImplTest, { // Background is not an integer. service_->SetPdfPluginAttributes(mime_handler::PdfPluginAttributes::New( - /*background_color=*/12.34, /*allow_javascript=*/true)); + /*background_color=*/12.34, /*allow_javascript=*/true, + /*use_skia=*/true)); EXPECT_FALSE(stream_container_->pdf_plugin_attributes()); } @@ -93,7 +100,8 @@ TEST_F(MimeHandlerServiceImplTest, // Background color is beyond the range of an uint32_t. uint64_t color_beyond_range = UINT32_MAX + static_cast<uint64_t>(1); service_->SetPdfPluginAttributes(mime_handler::PdfPluginAttributes::New( - static_cast<double>(color_beyond_range), /*allow_javascript=*/true)); + static_cast<double>(color_beyond_range), /*allow_javascript=*/true, + /*use_skia=*/true)); EXPECT_FALSE(stream_container_->pdf_plugin_attributes()); } } diff --git a/extensions/common/api/mime_handler.mojom b/extensions/common/api/mime_handler.mojom index 68fa2f147d91d..744381850bf2a 100644 --- a/extensions/common/api/mime_handler.mojom +++ b/extensions/common/api/mime_handler.mojom @@ -39,6 +39,9 @@ struct PdfPluginAttributes { // Indicates whether the plugin should allow running JavaScript. Loading XFA // for PDF forms will automatically be disabled if this flag is false. bool allow_javascript; + + // Indicates whether the PDF viewer should use Skia renderer. + bool use_skia; }; // Provides a mime handler guest methods to get and modify the stream associated diff --git a/pdf/parsed_params.cc b/pdf/parsed_params.cc index c10ccf09bf020..1e142613b731e 100644 --- a/pdf/parsed_params.cc +++ b/pdf/parsed_params.cc @@ -46,6 +46,8 @@ absl::optional<ParsedParams> ParseWebPluginParams( result.script_option = PDFiumFormFiller::ScriptOption::kNoJavaScript; } else if (params.attribute_names[i] == "has-edits") { result.has_edits = true; + } else if (params.attribute_names[i] == "use-skia") { + result.use_skia = true; } } diff --git a/pdf/parsed_params.h b/pdf/parsed_params.h index 8b2d713e90a2e..6ae4fddbdd3ae 100644 --- a/pdf/parsed_params.h +++ b/pdf/parsed_params.h @@ -46,6 +46,10 @@ struct ParsedParams { // Whether the PDF was edited previously in annotation mode. bool has_edits = false; + + // Whether the PDF viewer uses Skia renderer. When set to false, the PDF + // viewer uses AGG renderer. + bool use_skia = false; }; // Creates an `ParsedParams` by parsing a `blink::WebPluginParams`. If diff --git a/pdf/parsed_params_unittest.cc b/pdf/parsed_params_unittest.cc index ae870f36eab87..9d165c6c6d40a 100644 --- a/pdf/parsed_params_unittest.cc +++ b/pdf/parsed_params_unittest.cc @@ -46,6 +46,7 @@ TEST(ParsedParamsTest, ParseWebPluginParamsMinimal) { EXPECT_EQ(SK_ColorTRANSPARENT, result->background_color); EXPECT_EQ(PDFiumFormFiller::DefaultScriptOption(), result->script_option); EXPECT_FALSE(result->has_edits); + EXPECT_FALSE(result->use_skia); } TEST(ParsedParamsTest, ParseWebPluginParamsWithoutSourceUrl) { @@ -181,4 +182,26 @@ TEST(ParsedParamsTest, ParseWebPluginParamsWithHasEditsNonEmpty) { EXPECT_TRUE(result->has_edits); } +TEST(ParsedParamsTest, ParseWebPluginParamsWithHasUseSkia) { + blink::WebPluginParams params = CreateMinimalWebPluginParams(); + params.attribute_names.push_back(blink::WebString("use-skia")); + params.attribute_values.push_back(blink::WebString("")); + + absl::optional<ParsedParams> result = ParseWebPluginParams(params); + ASSERT_TRUE(result.has_value()); + + EXPECT_TRUE(result->use_skia); +} + +TEST(ParsedParamsTest, ParseWebPluginParamsWithHasUseSkiaNonEmpty) { + blink::WebPluginParams params = CreateMinimalWebPluginParams(); + params.attribute_names.push_back(blink::WebString("use-skia")); + params.attribute_values.push_back(blink::WebString("false")); + + absl::optional<ParsedParams> result = ParseWebPluginParams(params); + ASSERT_TRUE(result.has_value()); + + EXPECT_TRUE(result->use_skia); +} + } // namespace chrome_pdf diff --git a/pdf/pdf.cc b/pdf/pdf.cc index 9e59305fba984..c8aab79181005 100644 --- a/pdf/pdf.cc +++ b/pdf/pdf.cc @@ -24,6 +24,9 @@ class ScopedSdkInitializer { public: explicit ScopedSdkInitializer(bool enable_v8) { if (!IsSDKInitializedViaPlugin()) { + // TODO(crbug.com/1440430): Modify ScopedSdkInitializer() so that the + // option to use Skia can be based on enterprise policy if such policy is + // set. InitializeSDK(enable_v8, base::FeatureList::IsEnabled(features::kPdfUseSkiaRenderer), FontMappingMode::kNoMapping); diff --git a/pdf/pdf_view_web_plugin.cc b/pdf/pdf_view_web_plugin.cc index 4ea0420a308a3..ff6c55728c83c 100644 --- a/pdf/pdf_view_web_plugin.cc +++ b/pdf/pdf_view_web_plugin.cc @@ -179,7 +179,7 @@ class PerProcessInitializer final { return *instance; } - void Acquire() { + void Acquire(bool use_skia) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_GE(init_count_, 0); @@ -187,9 +187,7 @@ class PerProcessInitializer final { return; DCHECK(!IsSDKInitializedViaPlugin()); - InitializeSDK(/*enable_v8=*/true, - base::FeatureList::IsEnabled(features::kPdfUseSkiaRenderer), - FontMappingMode::kBlink); + InitializeSDK(/*enable_v8=*/true, use_skia, FontMappingMode::kBlink); SetIsSDKInitializedViaPlugin(true); } @@ -335,7 +333,7 @@ bool PdfViewWebPlugin::InitializeCommon() { base::debug::CrashKeySize::Size256); base::debug::SetCrashKeyString(subresource_url, params->original_url); - PerProcessInitializer::GetInstance().Acquire(); + PerProcessInitializer::GetInstance().Acquire(params->use_skia); initialized_ = true; // Check if the PDF is being loaded in the PDF chrome extension. We only allow